Capstart

Native Purchases

Add native in-app purchases and subscriptions to a Capacitor app.

@capgo/native-purchases adds native in-app purchases and subscriptions to Capacitor apps using StoreKit on iOS and Google Play Billing on Android.

The GitHub repository is named capacitor-native-purchases, but the package installed by the docs is @capgo/native-purchases.

Use it when your app needs one-time purchases, paid upgrades, subscriptions, restore purchases, subscription management, or native store purchase sheets without adding a paid purchase SDK.

What It Does

  • Loads product information from the App Store or Google Play.
  • Starts native purchase flows for one-time products.
  • Starts native subscription flows.
  • Restores purchases.
  • Opens native subscription management.
  • Supports StoreKit 2 on iOS and Google Play Billing on Android.
  • Exposes receipt, JWS, and purchase token data for backend validation.
  • Supports iOS monthly subscription commitment plans when StoreKit exposes them.

What It Does Not Replace

  • It does not create products in App Store Connect or Google Play Console.
  • It does not remove the need for purchase validation on your backend.
  • It does not let you hardcode prices safely. Store metadata should come from the plugin.
  • It does not replace App Store or Play Store compliance work.

Installation

npm install @capgo/native-purchases
npx cap sync

Android Setup

Add the Google Play Billing permission:

AndroidManifest.xml
<uses-permission android:name="com.android.vending.BILLING" />

For subscriptions on Android, the planIdentifier is important. It must match the Base Plan ID configured in Google Play Console.

iOS Setup

Add the In-App Purchase capability in Xcode:

  1. Open the iOS project in Xcode.
  2. Select the app target.
  3. Go to Signing & Capabilities.
  4. Add In-App Purchase.

App Store review expects product names and prices to be displayed from store data, such as product.title and product.priceString, not hardcoded copy.

Load Products

Always load product metadata before rendering your paywall:

purchases.ts
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';

const { isBillingSupported } = await NativePurchases.isBillingSupported();

if (!isBillingSupported) {
  throw new Error('Billing is not supported on this device.');
}

const { products } = await NativePurchases.getProducts({
  productIdentifiers: ['com.yourapp.premium.monthly', 'com.yourapp.premium.yearly'],
  productType: PURCHASE_TYPE.SUBS,
});

for (const product of products) {
  console.log(product.title, product.priceString);
}

Purchase A One-Time Product

One-time in-app products use PURCHASE_TYPE.INAPP and do not need a planIdentifier.

const transaction = await NativePurchases.purchaseProduct({
  productIdentifier: 'com.yourapp.premium_features',
  productType: PURCHASE_TYPE.INAPP,
  quantity: 1,
});

console.log('Purchase transaction', transaction.transactionId);

Purchase A Subscription

Subscriptions use PURCHASE_TYPE.SUBS. On Android, pass the Base Plan ID as planIdentifier.

const transaction = await NativePurchases.purchaseProduct({
  productIdentifier: 'com.yourapp.premium.monthly',
  planIdentifier: 'monthly-plan',
  productType: PURCHASE_TYPE.SUBS,
  quantity: 1,
});

console.log('Subscription transaction', transaction.transactionId);

Restore And Manage Purchases

await NativePurchases.restorePurchases();

const { purchases } = await NativePurchases.getPurchases({
  productType: PURCHASE_TYPE.SUBS,
});

await NativePurchases.manageSubscriptions();

Backend Validation

Use the transaction data to validate purchases on your server:

PlatformData to validate
iOSStoreKit receipt or JWS representation.
AndroidGoogle Play purchase token and product identifier.

Do not unlock long-lived subscriptions based only on client state. The client can update UI immediately after purchase, but the backend should verify and persist entitlement state.

Purchase Types

Purchase typeproductTypeNotes
One-time purchasePURCHASE_TYPE.INAPPPremium features, remove ads, content packs.
SubscriptionPURCHASE_TYPE.SUBSMonthly or yearly access. Android subscriptions require planIdentifier.

On this page

Need help with your app?

Our team can help you integrate Capstart.