Zum Inhalt springen

Einstieg

GitHub
  1. Das Paket installieren

    Terminal-Fenster
    bun add @capgo/native-purchases
  2. Synchronisieren Sie mit native Projekten

    Terminalfenster
    bunx cap sync
  3. Überprüfen Sie die Abrechnungsunterstützung

    import { NativePurchases } from '@capgo/native-purchases';
    const { isBillingSupported } = await NativePurchases.isBillingSupported();
    if (!isBillingSupported) {
    throw new Error('Billing is not available on this device');
    }
  4. Produkte direkt aus den Geschäften laden

    import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
    const { products } = await NativePurchases.getProducts({
    productIdentifiers: [
    'com.example.premium.monthly',
    'com.example.premium.yearly',
    'com.example.one_time_unlock'
    ],
    productType: PURCHASE_TYPE.SUBS, // Use PURCHASE_TYPE.INAPP for one‑time products
    });
    products.forEach((product) => {
    console.log(product.title, product.priceString);
    });
  5. Einführen Sie Kauf- und Wiederherstellungsflüsse

    import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
    const monthlyPlanId = 'monthly-plan'; // Base Plan ID from Google Play Console
    const transaction = await NativePurchases.purchaseProduct({
    productIdentifier: 'com.example.premium.monthly',
    planIdentifier: monthlyPlanId, // REQUIRED for Android subscriptions, ignored on iOS
    productType: PURCHASE_TYPE.SUBS,
    quantity: 1,
    });
    console.log('Transaction ID', transaction.transactionId);
    await NativePurchases.restorePurchases();
    • Erstellen Sie in-App-Produkte und -Abonnements in App Store Connect.
    • Verwenden Sie StoreKit Local Testing oder Sandbox-Tester für QA.
    • Keine Manifest-Änderungen erforderlich. Stellen Sie sicher, dass Ihre Produkte genehmigt sind.
import { NativePurchases, PURCHASE_TYPE, Transaction } from '@capgo/native-purchases';
import { Capacitor } from '@capacitor/core';
class PurchaseService {
private premiumProduct = 'com.example.premium.unlock';
private monthlySubId = 'com.example.premium.monthly';
private monthlyPlanId = 'monthly-plan'; // Base Plan ID (Android only)
async initialize() {
const { isBillingSupported } = await NativePurchases.isBillingSupported();
if (!isBillingSupported) throw new Error('Billing unavailable');
const { products } = await NativePurchases.getProducts({
productIdentifiers: [this.premiumProduct, this.monthlySubId],
productType: PURCHASE_TYPE.SUBS,
});
console.log('Loaded products', products);
if (Capacitor.getPlatform() === 'ios') {
NativePurchases.addListener('transactionUpdated', (transaction) => {
this.handleTransaction(transaction);
});
}
}
async buyPremium(appAccountToken?: string) {
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: this.premiumProduct,
productType: PURCHASE_TYPE.INAPP,
appAccountToken,
});
await this.processTransaction(transaction);
}
async buyMonthly(appAccountToken?: string) {
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: this.monthlySubId,
planIdentifier: this.monthlyPlanId, // REQUIRED for Android subscriptions
productType: PURCHASE_TYPE.SUBS,
appAccountToken,
});
await this.processTransaction(transaction);
}
async restore() {
await NativePurchases.restorePurchases();
await this.refreshEntitlements();
}
async openManageSubscriptions() {
await NativePurchases.manageSubscriptions();
}
private async processTransaction(transaction: Transaction) {
this.unlockContent(transaction.productIdentifier);
this.validateOnServer(transaction).catch(console.error);
}
private unlockContent(productIdentifier: string) {
// persist entitlement locally
console.log('Unlocked', productIdentifier);
}
private async refreshEntitlements() {
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
console.log('Current purchases', purchases);
}
private async handleTransaction(transaction: Transaction) {
console.log('StoreKit transaction update:', transaction);
await this.processTransaction(transaction);
}
private async validateOnServer(transaction: Transaction) {
await fetch('/api/validate-purchase', {
method: 'POST',
body: JSON.stringify({
transactionId: transaction.transactionId,
receipt: transaction.receipt,
purchaseToken: transaction.purchaseToken,
}),
});
}
}
OptionPlattformBeschreibung
productIdentifieriOS + AndroidArtikelnummer/Konfigurierte Produkt-ID in App Store Connect / Google Play Console.
productTypeNur für AndroidPURCHASE_TYPE.INAPP oder PURCHASE_TYPE.SUBS. Standardmäßig ist INAPP. Immer auf SUBS für Abonnements.
planIdentifierAbonnements für AndroidBasiskennung für Google Play Console. Erforderlich für Abonnements, wird bei iOS- und In-App-Käufen ignoriert.
billingPlanTypeAbonnements für iOSStoreKit-Billing-Plan zum Kauf. Verwenden 'monthly' für monatliche Abrechnung mit einem 12-monatigen Verpflichtungszeitraum, wenn product.pricingTerms dieses Option ausführt.
quantityiOSNur für In-App-Käufe, standardmäßig 1. Android kauft immer ein Produkt.
appAccountTokeniOS + AndroidEine UUID/Zeichenkette, die den Kauf mit Ihrem Benutzer verbindet. Erforderlich ist eine UUID auf iOS; Android akzeptiert jede verschlüsselte Zeichenkette bis zu 64 Zeichen.
isConsumableAndroidSetzen Sie auf true Zum automatischen Verbrauch von Token nach der Gewährung von Entgelt für Verbrauchsgüter. Standardmäßig false.

Verwenden Sie getPurchases() für eine plattformübergreifende Ansicht aller Transaktionen, die die Stores melden:

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
purchases.forEach((purchase) => {
if (purchase.isActive && purchase.expirationDate) {
console.log('iOS sub active until', purchase.expirationDate);
}
const isAndroidIapValid =
['PURCHASED', '1'].includes(purchase.purchaseState ?? '') && purchase.isAcknowledged;
if (isAndroidIapValid) {
console.log('Grant in-app entitlement for', purchase.productIdentifier);
}
});
  • iOS: Die Abonnements umfassen isActive, expirationDate, willCancelund StoreKit 2-Hinweisunterstützung. In-App-Käufe erfordern die Validierung des Server-Einkaufsbelegs.
  • Android: isActive/expirationDate werden nicht befüllt; rufen Sie den Google Play-Entwickler API mit dem purchaseToken für die autoritative Statusanzeige. purchaseState müssen PURCHASED und isAcknowledged müssen true.
  • isBillingSupported() – Überprüfen Sie die Verfügbarkeit von StoreKit / Google Play.
  • getProduct() / getProducts() – Abrufen Sie den Preis, den lokalisierten Titel, die Beschreibung, die Einführungsangebote und die unterstützten iOS-Preisbegriffe.
  • purchaseProduct() – Starten Sie den Kauffluss von StoreKit 2 oder Billing-Klient, einschließlich iOS-Monatsverpflichtungsabrechnungsplänen.
  • restorePurchases() – Wiedergeben Sie historische Kaufgeschäfte und synchronisieren Sie sie mit dem aktuellen Gerät.
  • getPurchases() – Listen Sie alle iOS-Transaktionen oder Play-Billing-Käufe auf.
  • manageSubscriptions() – Öffnen Sie die native Abonnementverwaltungsoberfläche.
  • addListener('transactionUpdated') – Behandeln Sie die bei App-Start wartenden StoreKit 2-Transaktionen (nur iOS).
  1. Zeigen Sie den Ladenpreis an – Apple erfordert die Anzeige von product.title und product.priceString; hardcode nie.
  2. Verwenden Sie appAccountToken – generieren Sie deterministisch eine UUID (v5) aus Ihrem Benutzer-ID, um Kaufleistungen mit Konten zu verbinden.
  3. Überprüfen Sie serverseitig – senden Sie receipt (iOS) / purchaseToken (Android) an Ihren Backend-Server zur Verifizierung.
  4. Behandeln Sie Fehler geschickt – überprüfen Sie Benutzerstornierungen, Netzwerkfehler und nicht unterstützte Bezahlumgebungen.
  5. Testen Sie gründlich – folge der iOS Sandbox-Leitfaden und Android Sandbox-Leitfaden.
  6. Wiederherstellung und -verwaltung anbieten – füge UI-Schaltflächen hinzu, die an restorePurchases() und manageSubscriptions().

Nachdem der Kauffluss funktioniert, verwende das Revenue Playbook um deinen ersten bezahlten Kanal zu planen: Produktumfang, ASO, Preis, Paywall-Platzierung, Analytics und Rückschläge bei der Abmeldung.

Produkte laden nicht

  • Stellen Sie sicher, dass die Bundle-ID / Anwendungs-ID der Lagerverwaltungskonfiguration entspricht.
  • Bestätigen Sie, dass die Produkt-IDs aktiv und genehmigt (App Store) oder aktiviert (Google Play) sind.
  • Warten Sie einige Stunden nach der Erstellung von Produkten; die Lagerverteilung ist nicht sofort.

Kauf abgebrochen oder hängen geblieben

  • Benutzer können mitten im Flow abbrechen; Wrap Aufrufe in try/catch und Oberflächenfreundliche Fehlermeldungen anbieten.
  • Für Android stellen Sie sicher, dass Testkonten die App vom Play Store (internes Track) installieren, damit die Abrechnung funktioniert.
  • Überprüfen Sie Logcat/Xcode für Abrechnungsfehler, wenn Sie auf einem Gerät laufen.

Ungültiger Zustand der Abonnement

  • Verwenden Sie getPurchases() um Daten des Stores mit Ihrem lokalen Cache für Berechtigungen zu vergleichen.
  • Bei Android- Geräten wird immer die Google Play Developer API abgefragt mit dem purchaseToken um Ablaufdaten oder einen Rückgabestatus zu erhalten.
  • Bei iOS-Geräten prüfen Sie isActive/expirationDate und überprüfen Sie die Rechnungen, um Rückzahlungen oder Widerrufe zu erkennen.

Wenn Sie Getting Started zur Planung der Genehmigung und Verteilung im Store verwenden, verbinden Sie es mit Verwenden Sie @capgo/native-purchases für die native Fähigkeit in @capgo/native-purchases, @capgo/capacitor-in-app-Bewertung für die Implementierungsdetails in @capgo/capacitor-in-app-Bewertung, Mit @capgo/capacitor-in-app-Bewertung für die native Fähigkeit in Mit @capgo/capacitor-in-app-Bewertung, @capgo/capacitor-native-Markt für die Implementierungsdetails in @capgo/capacitor-native-Markt, und Mit @capgo/capacitor-native-Markt für die native Fähigkeit in Mit @capgo/capacitor-native-Markt.