The cordova-plugin-purchase alternative many Capacitor teams adopt when they outgrow the CdvPurchase.store workflow is @capgo/native-purchases. It talks to StoreKit 2 on iOS and Google Play Billing 7 on Android through promise methods such as getProducts, purchaseProduct, and restorePurchases, with transactionUpdated listeners instead of store.when() chains. This guide explains when that trade-off makes sense, how to install the plugin, and how to map common cordova-plugin-purchase calls.
Why teams leave cordova-plugin-purchase in new Capacitor code
cordova-plugin-purchase is actively maintained. npm shows version 13.20.0 with a last modified date of 27 October 2026. The README states the plugin supports Capacitor through capacitor-plugin-cdv-purchase and the global CdvPurchase.store facade with product registration, store.initialize(), and store.when() approved handlers.
Reasons teams still pick @capgo/native-purchases on a Capacitor migration:
- Simpler API shape. Capgo exposes one method per store action (
purchaseProduct,getPurchases,acknowledgePurchase) instead of the FSM-stylestore.when().productUpdated().approved()pipeline. - Native billing stacks called out in the README. StoreKit 2 on iOS 15+ and Google Play Billing 7.x on Android, plus iOS subscription commitment helpers documented under
/docs/plugins/native-purchases/. - Capacitor-first packaging. Install with
npm install @capgo/native-purchasesandcap syncwithout carrying Cordova globals or the separatecapacitor-plugin-cdv-purchasebridge unless you still need Braintree payment requests from CdvPurchase. - Open source maintenance. Capgo fixes ship through the public repo where a human still reviews, tests and merges 50+ pull requests daily.
If you rely on CdvPurchase-only features such as Braintree payment requests or the Iaptic validator shortcut, stay on cordova-plugin-purchase or run both plugins temporarily while you port checkout flows.
Install
bun add @capgo/native-purchases
bunx cap sync
Android: add billing permission:
<uses-permission android:name="com.android.vending.BILLING" />
Configure products in App Store Connect and Google Play Console, then follow the platform testing guides linked from the plugin README (docs/iOS_TESTING_GUIDE.md and docs/ANDROID_TESTING_GUIDE.md).
Usage example
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
const productId = 'com.example.premium.monthly';
export async function buySubscription() {
const { isBillingSupported } = await NativePurchases.isBillingSupported();
if (!isBillingSupported) {
throw new Error('Billing unavailable');
}
await NativePurchases.addListener('transactionUpdated', (event) => {
console.log('Transaction', event.transaction?.transactionId);
});
const { products } = await NativePurchases.getProducts({
productIdentifiers: [productId],
productType: PURCHASE_TYPE.SUBS,
});
await NativePurchases.purchaseProduct({
productIdentifier: productId,
productType: PURCHASE_TYPE.SUBS,
planIdentifier: 'monthly-plan',
quantity: 1,
});
}
Call restorePurchases() from your settings screen and manageSubscriptions() when users need the store subscription UI.
Migrating from Cordova to Capacitor
Uninstall Cordova cordova-plugin-purchase or keep it only on screens you have not ported. Import NativePurchases and replace store orchestration with explicit async flows. Finish or acknowledge transactions per platform rules using finishTransaction() on iOS and acknowledgePurchase() or consumePurchase() on Android where the README requires it.
API mapping table
cordova-plugin-purchase (CdvPurchase.store) |
@capgo/native-purchases |
|---|---|
store.register([{ id, type }]) |
getProducts({ productIdentifiers, productType }) |
store.initialize([Platform.APPLE, Platform.GOOGLE]) |
isBillingSupported() then getProducts() |
store.ready() / store.update() |
await getProducts() after billing check |
store.get(productId) |
getProduct({ productIdentifier, productType }) |
store.order(offer) / product.getOffer().order() |
purchaseProduct({ productIdentifier, productType, planIdentifier, quantity }) |
store.requestPayment(...) (Braintree) |
Not in Capgo plugin, keep CdvPurchase or Stripe |
store.restore() |
restorePurchases() |
store.owned(productId) |
Inspect getPurchases() results or server entitlements |
store.when().approved(handler) |
addListener('transactionUpdated', ...) |
store.validator = url |
Validate receipt or purchase token on your server |
store.refresh() |
getProducts() or getPurchases() |
product.transaction.finish() |
finishTransaction({ transactionIdentifier }) |
| Consumable consume | consumePurchase({ purchaseToken }) (Android) |
PURCHASE_TYPE.INAPP maps to consumable and non-consumable products. PURCHASE_TYPE.SUBS maps to paid subscriptions. Android base plan ids from Play Console pass through planIdentifier on purchaseProduct(), as documented in the getting started guide.
Links and next steps
- Plugin docs: https://capgo.app/docs/plugins/native-purchases/
- Marketing page: /plugins/native-purchases/
- npm: https://www.npmjs.com/package/@capgo/native-purchases
- GitHub: https://github.com/Cap-go/capacitor-native-purchases/
- cordova-plugin-purchase: https://github.com/j3k0/cordova-plugin-purchase
Billing rule changes require a native rebuild. Use Capgo Build for signed artifacts. Paywall copy and pricing UI can ship faster with Capgo live updates once store binaries are current. See migrating Cordova to Capacitor for the wider migration checklist.