Skip to main content

Multi-Quantity Consumable Purchases

Starting with v13.15.0, the plugin supports ordering multiple units of a consumable product in a single transaction on both iOS and Android. Previously this was Android-only.

Ordering with Quantity

Pass a quantity value in the additional data when calling store.order():

const product = store.get('my_consumable');
const offer = product && product.getOffer();

if (offer) {
const error = await store.order(offer, { quantity: 3 });
if (error) {
console.log('Order failed: ' + error.message);
}
}

iOS limit: Apple restricts quantity to 1-10 per transaction.

Android: Google Play has supported multi-quantity consumables since the plugin first introduced it. No specific upper limit is enforced by the plugin, but Google Play may apply its own limits.

Checking Platform Support

Not all platforms support multi-quantity orders. Use checkSupport to decide whether to show a quantity picker in your UI:

const { store, Platform } = CdvPurchase;

if (store.checkSupport(Platform.APPLE_APPSTORE, 'orderQuantity')) {
// Show quantity picker for iOS
showQuantityPicker();
} else if (store.checkSupport(Platform.GOOGLE_PLAY, 'orderQuantity')) {
// Show quantity picker for Android
showQuantityPicker();
} else {
// Platform does not support multi-quantity; order one at a time
}

The 'orderQuantity' capability is advertised by the Apple AppStore adapter. The Google Play adapter supports it through the standard order flow.

Reading Quantity from Verified Purchases

After receipt validation, the server-side response includes the quantity in the VerifiedPurchase object:

store.when().verified(receipt => {
receipt.collection.forEach(purchase => {
if (purchase.id === 'my_consumable' && purchase.quantity) {
grantCoins(purchase.quantity * COINS_PER_UNIT);
}
});
receipt.finish();
});

The VerifiedPurchase.quantity field:

interface VerifiedPurchase {
id: string;
// ... other fields ...
/**
* Quantity of items purchased in a single transaction.
* For consumable products, represents the number of items purchased.
* For non-consumable products and subscriptions, always 1.
*/
quantity?: number;
}

Complete Example

const { store, ProductType, Platform } = CdvPurchase;

// Register a consumable product
store.register([{
id: 'coins_pack',
type: ProductType.CONSUMABLE,
platform: Platform.APPLE_APPSTORE
}]);

// Handle verified purchases
store.when().verified(receipt => {
receipt.collection.forEach(purchase => {
if (purchase.id === 'coins_pack') {
const qty = purchase.quantity || 1;
addCoins(qty * 100); // 100 coins per unit
}
});
receipt.finish();
});

// Order with quantity (after user selects amount)
async function buyCoins(quantity) {
const product = store.get('coins_pack');
const offer = product && product.getOffer();
if (!offer) return;

const error = await store.order(offer, { quantity: quantity });
if (error) {
showError('Purchase failed: ' + error.message);
}
}

Notes

  • If quantity is not specified, it defaults to 1.
  • The quantity is part of AdditionalData, not tied to a specific platform's additional data object — it works cross-platform.
  • Always validate the actual quantity received from the server (via VerifiedPurchase.quantity) rather than trusting the client-side value.