Mulai
Salin prompt pengaturan dengan langkah-langkah instalasi dan panduan markdown lengkap untuk plugin ini.
Set up this Capacitor plugin in the project.
Use the package manager already used by the project.
Install these package(s): `@capgo/native-purchases`
Run the required Capacitor sync/update step after installation.
Read this markdown guide for the full setup steps: https://raw.githubusercontent.com/Cap-go/website/refs/heads/main/apps/docs/src/content/docs/docs/plugins/native-purchases/getting-started.mdx
Use that guide for platform-specific steps, native file edits, permissions, config changes, imports, and usage setup.
If that guide references other docs pages, read them too.
-
Instal paket
Jendela terminal bun add @capgo/native-purchases -
Sinkron dengan proyek native
Jendela terminal bunx cap sync -
Periksa dukungan billing
import { NativePurchases } from '@capgo/native-purchases';const { isBillingSupported } = await NativePurchases.isBillingSupported();if (!isBillingSupported) {throw new Error('Billing is not available on this device');} -
Muat produk secara langsung dari toko
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);}); -
Implementasikan alur pembelian & pengembalian
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';const monthlyPlanId = 'monthly-plan'; // Base Plan ID from Google Play Consoleconst transaction = await NativePurchases.purchaseProduct({productIdentifier: 'com.example.premium.monthly',planIdentifier: monthlyPlanId, // REQUIRED for Android subscriptions, ignored on iOSproductType: PURCHASE_TYPE.SUBS,quantity: 1,});console.log('Transaction ID', transaction.transactionId);await NativePurchases.restorePurchases();- Buat produk dalam aplikasi dan langganan di App Store Connect.
- Gunakan StoreKit Local Testing atau Sandbox tester untuk QA.
- Tidak perlu edit manifest. Pastikan produk Anda disetujui.
- Buat produk dalam aplikasi dan langganan di Google Play Console.
- Unggah setidaknya sebuah versi uji internal dan tambahkan tester lisensi.
- Tambahkan izin pembayaran ke
AndroidManifest.xml:
<uses-permission android:name="com.android.vending.BILLING" /> - Buat produk dalam aplikasi dan langganan di App Store Connect.
Contoh pembelian layanan
Judul bagian “Contoh pembelian layanan”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, }), }); }}Pilihan pembelian yang diperlukan
Judul bagian “Pilihan pembelian yang diperlukan”| Pilihan | Platform | Deskripsi |
|---|---|---|
productIdentifier | iOS + Android | SKU/Kode Produk yang telah dikonfigurasi di App Store Connect / Google Play Console. |
productType | Hanya Android | PURCHASE_TYPE.INAPP atau PURCHASE_TYPE.SUBS. Default ke INAPP. Selalu ditetapkan ke SUBS untuk langganan. |
planIdentifier | ID Rencana Dasar dari Google Play Console. Diperlukan untuk langganan, diabaikan pada iOS dan pembelian dalam aplikasi. | Langganan iOS |
billingPlanType | Rencana pembayaran StoreKit untuk membeli. Gunakan | untuk pembayaran bulanan dengan komitmen 12 bulan ketika 'monthly' mengungkapkan opsi tersebut. product.pricingTerms iOS |
quantity | Hanya untuk pembelian dalam aplikasi, default ke | . Android selalu membeli satu item. 1__CAPGO_KEEP_0__ |
appAccountToken | iOS + Android | UUID/string yang terkait pembelian dengan pengguna Anda. Diperlukan UUID pada iOS; Android menerima string yang diobfuskan hingga 64 karakter. |
isConsumable | Android | Dipilih true untuk mengonsumsi token secara otomatis setelah memberikan hak untuk konsumables. Default adalah false. |
Mengecek status hak
Judul bagian “Mengecek status hak”Gunakan getPurchases() untuk tampilan lintas platform dari setiap transaksi yang dilaporkan oleh toko:
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); }});Tingkah laku platform
Judul bagian “Tingkah laku platform”- iOS: Langganan mencakup
isActive,expirationDate,willCancel, dan dukungan pendengar StoreKit 2. - Pembelian dalam aplikasi memerlukan validasi bukti penerimaan server.:
isActive/expirationDateare not populated; call the Google Play Developer API with thepurchaseTokentidak diisi; hubungi pengembang Google Play dengan __CAPGO_KEEP_0__ untuk status otoritatif.purchaseStateharus diisiPURCHASEDdanisAcknowledgedharus diisitrue.
API referensi cepat
Judul bagian “API referensi cepat”isBillingSupported()– periksa ketersediaan StoreKit / Google Play.getProduct()/getProducts()– mengambil harga, judul yang disesuaikan, deskripsi, penawaran intro, dan istilah harga iOS yang didukung.purchaseProduct()– memulai alur pembelian StoreKit 2 atau Billing klien, termasuk rencana pembayaran bulanan iOS.restorePurchases()– merekam pembelian sejarah dan sinkron ke perangkat saat ini.getPurchases()– menampilkan semua transaksi iOS atau pembelian Play Billing.manageSubscriptions()– membuka antarmuka pengelolaan langganan native.addListener('transactionUpdated')– mengatasi transaksi StoreKit 2 yang menunggu ketika aplikasi Anda dimulai (hanya iOS).
Praktik Terbaik
Bagian berjudul “Praktik Terbaik”- Tampilkan harga toko – Apple memerlukan menampilkan
product.titledanproduct.priceString; tidak pernah mengkodekan secara keras. - Menggunakan – menghasilkan UUID (v5) secara deterministik dari ID pengguna untuk menghubungkan pembelian ke akun.
appAccountTokenMengvalidasi di server – kirim - (iOS) / (Android) ke backend Anda untuk verifikasi.
receiptMenghadapi kesalahan dengan sopan – periksa pembatalan pengguna, kegagalan jaringan, dan lingkungan pembayaran yang tidak didukung.purchaseTokenMenguji secara menyeluruh – ikuti panduan - iOS sandbox dan
- __CAPGO_KEEP_0__ __CAPGO_KEEP_1__ __CAPGO_KEEP_2__ __CAPGO_KEEP_3__ Petunjuk Panduan Sandbox Android.
- Pulihkan dan Kelola Penawaran – tambahkan tombol UI yang terhubung ke
restorePurchases()danmanageSubscriptions().
Langkah-Langkah Selanjutnya untuk Pendapatan
Judul Bagian “Langkah-Langkah Selanjutnya untuk Pendapatan”Setelah alur pembelian berfungsi, gunakan Revenue Playbook untuk merencanakan funnel pembayaran pertama: ruang lingkup produk, ASO, harga, penempatan paywall, analisis, dan umpan balik pengurangan.
Pengaturan
Judul Bagian “Pengaturan”Produk Tidak Terisi
- Pastikan ID bundle / ID aplikasi sesuai dengan konfigurasi toko.
- Konfirmasi bahwa ID produk aktif dan disetujui (App Store) atau diaktifkan (Google Play).
- Tunggu beberapa jam setelah membuat produk; penyebaran toko tidak instan.
Pembelian dibatalkan atau terjebak
- Pengguna dapat membatalkan di tengah alur; tutup panggilan dengan
try/catchdan permukaan pesan kesalahan yang ramah. - Untuk Android, pastikan akun uji instal aplikasi dari Play Store (track internal) agar Billing berfungsi.
- Cek logcat/Xcode untuk kesalahan billing saat menjalankan pada perangkat.
Keadaan langganan salah
- Gunakan
getPurchases()untuk membandingkan data toko dengan cache hak milik lokal Anda. - Pada Android, selalu tanyakan ke Google Play Developer API dengan
purchaseToken__CAPGO_KEEP_0__ untuk mendapatkan tanggal kedaluwarsa atau status pengembalian. - Pada iOS, cek
isActive/expirationDatedan validasi struk pembayaran untuk mendeteksi pengembalian atau pembatalan.