@capgo/native-purchases 7.1.30 → 7.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -81,18 +81,40 @@ For testing in-app purchases on iOS:
81
81
  Import the plugin in your TypeScript file:
82
82
 
83
83
  ```typescript
84
- import { NativePurchases } from '@capgo/native-purchases';
84
+ import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
85
85
  ```
86
86
 
87
+ ### ⚠️ Important: In-App vs Subscription Purchases
88
+
89
+ There are two types of purchases with different requirements:
90
+
91
+ | Purchase Type | productType | planIdentifier | Use Case |
92
+ |---------------|-------------|----------------|----------|
93
+ | **In-App Purchase** | `PURCHASE_TYPE.INAPP` | ❌ Not needed | One-time purchases (premium features, remove ads, etc.) |
94
+ | **Subscription** | `PURCHASE_TYPE.SUBS` | ✅ **REQUIRED** | Recurring purchases (monthly/yearly subscriptions) |
95
+
96
+ **Key Rules:**
97
+ - ✅ **In-App Products**: Use `productType: PURCHASE_TYPE.INAPP`, no `planIdentifier` needed
98
+ - ✅ **Subscriptions**: Must use `productType: PURCHASE_TYPE.SUBS` AND `planIdentifier: "your-plan-id"`
99
+ - ❌ **Missing planIdentifier** for subscriptions will cause purchase failures
100
+
87
101
  ### Complete Example: Get Product Info and Purchase
88
102
 
89
- Here's a complete example showing how to get product information and make a purchase:
103
+ Here's a complete example showing how to get product information and make purchases for both in-app products and subscriptions:
90
104
 
91
105
  ```typescript
92
- import { NativePurchases } from '@capgo/native-purchases';
106
+ import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
93
107
 
94
108
  class PurchaseManager {
95
- private productId = 'com.yourapp.premium.monthly';
109
+ // In-app product (one-time purchase)
110
+ private premiumProductId = 'com.yourapp.premium_features';
111
+
112
+ // Subscription products (require planIdentifier)
113
+ private monthlySubId = 'com.yourapp.premium.monthly';
114
+ private monthlyPlanId = 'monthly-plan'; // Base plan ID from store
115
+
116
+ private yearlySubId = 'com.yourapp.premium.yearly';
117
+ private yearlyPlanId = 'yearly-plan'; // Base plan ID from store
96
118
 
97
119
  async initializeStore() {
98
120
  try {
@@ -103,72 +125,130 @@ class PurchaseManager {
103
125
  }
104
126
 
105
127
  // 2. Get product information (REQUIRED by Apple - no hardcoded prices!)
106
- const product = await this.getProductInfo();
107
-
108
- // 3. Display product with dynamic info from store
109
- this.displayProduct(product);
128
+ await this.loadProducts();
110
129
 
111
130
  } catch (error) {
112
131
  console.error('Store initialization failed:', error);
113
132
  }
114
133
  }
115
134
 
116
- async getProductInfo() {
135
+ async loadProducts() {
117
136
  try {
118
- const { product } = await NativePurchases.getProduct({
119
- productIdentifier: this.productId
137
+ // Load in-app products
138
+ const { product: premiumProduct } = await NativePurchases.getProduct({
139
+ productIdentifier: this.premiumProductId,
140
+ productType: PURCHASE_TYPE.INAPP
120
141
  });
121
142
 
122
- console.log('Product loaded:', {
123
- id: product.identifier,
124
- title: product.title, // Use this for display (required by Apple)
125
- price: product.priceString, // Use this for display (required by Apple)
126
- description: product.description
143
+ // Load subscription products
144
+ const { products: subscriptions } = await NativePurchases.getProducts({
145
+ productIdentifiers: [this.monthlySubId, this.yearlySubId],
146
+ productType: PURCHASE_TYPE.SUBS
127
147
  });
128
148
 
129
- return product;
149
+ console.log('Products loaded:', {
150
+ premium: premiumProduct,
151
+ subscriptions: subscriptions
152
+ });
153
+
154
+ // Display products with dynamic info from store
155
+ this.displayProducts(premiumProduct, subscriptions);
156
+
130
157
  } catch (error) {
131
- console.error('Failed to get product:', error);
158
+ console.error('Failed to load products:', error);
132
159
  throw error;
133
160
  }
134
161
  }
135
162
 
136
- displayProduct(product: any) {
163
+ displayProducts(premiumProduct: any, subscriptions: any[]) {
137
164
  // ✅ CORRECT: Use dynamic product info (required by Apple)
138
- document.getElementById('product-title')!.textContent = product.title;
139
- document.getElementById('product-price')!.textContent = product.priceString;
140
- document.getElementById('product-description')!.textContent = product.description;
165
+
166
+ // Display one-time purchase
167
+ document.getElementById('premium-title')!.textContent = premiumProduct.title;
168
+ document.getElementById('premium-price')!.textContent = premiumProduct.priceString;
169
+
170
+ // Display subscriptions
171
+ subscriptions.forEach(sub => {
172
+ const element = document.getElementById(`sub-${sub.identifier}`);
173
+ if (element) {
174
+ element.textContent = `${sub.title} - ${sub.priceString}`;
175
+ }
176
+ });
141
177
 
142
178
  // ❌ WRONG: Never hardcode prices - Apple will reject your app
143
- // document.getElementById('product-price')!.textContent = '$9.99/month';
179
+ // document.getElementById('premium-price')!.textContent = '$9.99';
180
+ }
181
+
182
+ // Purchase one-time product (no planIdentifier needed)
183
+ async purchaseInAppProduct() {
184
+ try {
185
+ console.log('Starting in-app purchase...');
186
+
187
+ const result = await NativePurchases.purchaseProduct({
188
+ productIdentifier: this.premiumProductId,
189
+ productType: PURCHASE_TYPE.INAPP,
190
+ quantity: 1
191
+ });
192
+
193
+ console.log('In-app purchase successful!', result.transactionId);
194
+ await this.handleSuccessfulPurchase(result.transactionId, 'premium');
195
+
196
+ } catch (error) {
197
+ console.error('In-app purchase failed:', error);
198
+ this.handlePurchaseError(error);
199
+ }
144
200
  }
145
201
 
146
- async purchaseProduct() {
202
+ // Purchase subscription (planIdentifier REQUIRED)
203
+ async purchaseMonthlySubscription() {
147
204
  try {
148
- console.log('Starting purchase...');
205
+ console.log('Starting subscription purchase...');
149
206
 
150
207
  const result = await NativePurchases.purchaseProduct({
151
- productIdentifier: this.productId,
208
+ productIdentifier: this.monthlySubId,
209
+ planIdentifier: this.monthlyPlanId, // REQUIRED for subscriptions
210
+ productType: PURCHASE_TYPE.SUBS, // REQUIRED for subscriptions
152
211
  quantity: 1
153
212
  });
154
213
 
155
- console.log('Purchase successful!', result.transactionId);
214
+ console.log('Subscription purchase successful!', result.transactionId);
215
+ await this.handleSuccessfulPurchase(result.transactionId, 'monthly');
156
216
 
157
- // Handle successful purchase
158
- await this.handleSuccessfulPurchase(result.transactionId);
217
+ } catch (error) {
218
+ console.error('Subscription purchase failed:', error);
219
+ this.handlePurchaseError(error);
220
+ }
221
+ }
222
+
223
+ // Purchase yearly subscription (planIdentifier REQUIRED)
224
+ async purchaseYearlySubscription() {
225
+ try {
226
+ console.log('Starting yearly subscription purchase...');
227
+
228
+ const result = await NativePurchases.purchaseProduct({
229
+ productIdentifier: this.yearlySubId,
230
+ planIdentifier: this.yearlyPlanId, // REQUIRED for subscriptions
231
+ productType: PURCHASE_TYPE.SUBS, // REQUIRED for subscriptions
232
+ quantity: 1
233
+ });
234
+
235
+ console.log('Yearly subscription successful!', result.transactionId);
236
+ await this.handleSuccessfulPurchase(result.transactionId, 'yearly');
159
237
 
160
238
  } catch (error) {
161
- console.error('Purchase failed:', error);
239
+ console.error('Yearly subscription failed:', error);
162
240
  this.handlePurchaseError(error);
163
241
  }
164
242
  }
165
243
 
166
- async handleSuccessfulPurchase(transactionId: string) {
244
+ async handleSuccessfulPurchase(transactionId: string, purchaseType: string) {
167
245
  // 1. Grant access to premium features
168
246
  localStorage.setItem('premium_active', 'true');
247
+ localStorage.setItem('purchase_type', purchaseType);
169
248
 
170
249
  // 2. Update UI
171
- document.getElementById('subscription-status')!.textContent = 'Premium Active';
250
+ const statusText = purchaseType === 'premium' ? 'Premium Unlocked' : `${purchaseType} Subscription Active`;
251
+ document.getElementById('subscription-status')!.textContent = statusText;
172
252
 
173
253
  // 3. Optional: Verify purchase on your server
174
254
  await this.verifyPurchaseOnServer(transactionId);
@@ -223,8 +303,16 @@ const purchaseManager = new PurchaseManager();
223
303
  purchaseManager.initializeStore();
224
304
 
225
305
  // Attach to UI buttons
226
- document.getElementById('buy-button')?.addEventListener('click', () => {
227
- purchaseManager.purchaseProduct();
306
+ document.getElementById('buy-premium-button')?.addEventListener('click', () => {
307
+ purchaseManager.purchaseInAppProduct();
308
+ });
309
+
310
+ document.getElementById('buy-monthly-button')?.addEventListener('click', () => {
311
+ purchaseManager.purchaseMonthlySubscription();
312
+ });
313
+
314
+ document.getElementById('buy-yearly-button')?.addEventListener('click', () => {
315
+ purchaseManager.purchaseYearlySubscription();
228
316
  });
229
317
 
230
318
  document.getElementById('restore-button')?.addEventListener('click', () => {
@@ -237,15 +325,39 @@ document.getElementById('restore-button')?.addEventListener('click', () => {
237
325
  #### Get Multiple Products
238
326
 
239
327
  ```typescript
240
- // Get multiple products at once
241
- const getProducts = async () => {
328
+ import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
329
+
330
+ // Get in-app products (one-time purchases)
331
+ const getInAppProducts = async () => {
332
+ try {
333
+ const { products } = await NativePurchases.getProducts({
334
+ productIdentifiers: [
335
+ 'com.yourapp.premium_features',
336
+ 'com.yourapp.remove_ads',
337
+ 'com.yourapp.extra_content'
338
+ ],
339
+ productType: PURCHASE_TYPE.INAPP
340
+ });
341
+
342
+ products.forEach(product => {
343
+ console.log(`${product.title}: ${product.priceString}`);
344
+ });
345
+
346
+ return products;
347
+ } catch (error) {
348
+ console.error('Error getting in-app products:', error);
349
+ }
350
+ };
351
+
352
+ // Get subscription products
353
+ const getSubscriptions = async () => {
242
354
  try {
243
355
  const { products } = await NativePurchases.getProducts({
244
356
  productIdentifiers: [
245
357
  'com.yourapp.premium.monthly',
246
- 'com.yourapp.premium.yearly',
247
- 'com.yourapp.remove_ads'
248
- ]
358
+ 'com.yourapp.premium.yearly'
359
+ ],
360
+ productType: PURCHASE_TYPE.SUBS
249
361
  });
250
362
 
251
363
  products.forEach(product => {
@@ -254,7 +366,7 @@ const getProducts = async () => {
254
366
 
255
367
  return products;
256
368
  } catch (error) {
257
- console.error('Error getting products:', error);
369
+ console.error('Error getting subscriptions:', error);
258
370
  }
259
371
  };
260
372
  ```
@@ -262,8 +374,10 @@ const getProducts = async () => {
262
374
  #### Simple Purchase Flow
263
375
 
264
376
  ```typescript
265
- // Simple one-function purchase
266
- const buyPremium = async () => {
377
+ import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
378
+
379
+ // Simple one-time purchase (in-app product)
380
+ const buyInAppProduct = async () => {
267
381
  try {
268
382
  // Check billing support
269
383
  const { isBillingSupported } = await NativePurchases.isBillingSupported();
@@ -274,25 +388,76 @@ const buyPremium = async () => {
274
388
 
275
389
  // Get product (for price display)
276
390
  const { product } = await NativePurchases.getProduct({
277
- productIdentifier: 'com.yourapp.premium'
391
+ productIdentifier: 'com.yourapp.premium_features',
392
+ productType: PURCHASE_TYPE.INAPP
278
393
  });
279
394
 
280
395
  // Confirm with user (showing real price from store)
281
396
  const confirmed = confirm(`Purchase ${product.title} for ${product.priceString}?`);
282
397
  if (!confirmed) return;
283
398
 
284
- // Make purchase
399
+ // Make purchase (no planIdentifier needed for in-app)
285
400
  const result = await NativePurchases.purchaseProduct({
286
- productIdentifier: 'com.yourapp.premium',
287
- quantity: 1
401
+ productIdentifier: 'com.yourapp.premium_features',
402
+ productType: PURCHASE_TYPE.INAPP,
403
+ quantity: 1,
404
+ appAccountToken: userUUID // Optional: iOS only - for linking purchases to user accounts
288
405
  });
289
406
 
290
407
  alert('Purchase successful! Transaction ID: ' + result.transactionId);
291
408
 
409
+ // iOS will also return receipt data for validation
410
+ if (result.receipt) {
411
+ // Send to your backend for validation
412
+ await validateReceipt(result.receipt);
413
+ }
414
+
292
415
  } catch (error) {
293
416
  alert('Purchase failed: ' + error.message);
294
417
  }
295
418
  };
419
+
420
+ // Simple subscription purchase (requires planIdentifier)
421
+ const buySubscription = async () => {
422
+ try {
423
+ // Check billing support
424
+ const { isBillingSupported } = await NativePurchases.isBillingSupported();
425
+ if (!isBillingSupported) {
426
+ alert('Purchases not supported on this device');
427
+ return;
428
+ }
429
+
430
+ // Get subscription product (for price display)
431
+ const { product } = await NativePurchases.getProduct({
432
+ productIdentifier: 'com.yourapp.premium.monthly',
433
+ productType: PURCHASE_TYPE.SUBS
434
+ });
435
+
436
+ // Confirm with user (showing real price from store)
437
+ const confirmed = confirm(`Subscribe to ${product.title} for ${product.priceString}?`);
438
+ if (!confirmed) return;
439
+
440
+ // Make subscription purchase (planIdentifier REQUIRED for Android)
441
+ const result = await NativePurchases.purchaseProduct({
442
+ productIdentifier: 'com.yourapp.premium.monthly',
443
+ planIdentifier: 'monthly-plan', // REQUIRED for Android subscriptions
444
+ productType: PURCHASE_TYPE.SUBS, // REQUIRED for subscriptions
445
+ quantity: 1,
446
+ appAccountToken: userUUID // Optional: iOS only - for linking purchases to user accounts
447
+ });
448
+
449
+ alert('Subscription successful! Transaction ID: ' + result.transactionId);
450
+
451
+ // iOS will also return receipt data for validation
452
+ if (result.receipt) {
453
+ // Send to your backend for validation
454
+ await validateReceipt(result.receipt);
455
+ }
456
+
457
+ } catch (error) {
458
+ alert('Subscription failed: ' + error.message);
459
+ }
460
+ };
296
461
  ```
297
462
 
298
463
  ### Check if billing is supported
@@ -366,13 +531,14 @@ import axios from 'axios'; // Make sure to install axios: npm install axios
366
531
  class Store {
367
532
  // ... (previous code remains the same)
368
533
 
534
+ // Purchase in-app product
369
535
  async purchaseProduct(productId: string) {
370
536
  try {
371
537
  const transaction = await NativePurchases.purchaseProduct({
372
538
  productIdentifier: productId,
373
539
  productType: PURCHASE_TYPE.INAPP
374
540
  });
375
- console.log('Purchase successful:', transaction);
541
+ console.log('In-app purchase successful:', transaction);
376
542
 
377
543
  // Immediately grant access to the purchased content
378
544
  await this.grantAccess(productId);
@@ -387,6 +553,29 @@ class Store {
387
553
  }
388
554
  }
389
555
 
556
+ // Purchase subscription (requires planIdentifier)
557
+ async purchaseSubscription(productId: string, planId: string) {
558
+ try {
559
+ const transaction = await NativePurchases.purchaseProduct({
560
+ productIdentifier: productId,
561
+ planIdentifier: planId, // REQUIRED for subscriptions
562
+ productType: PURCHASE_TYPE.SUBS // REQUIRED for subscriptions
563
+ });
564
+ console.log('Subscription purchase successful:', transaction);
565
+
566
+ // Immediately grant access to the subscription content
567
+ await this.grantAccess(productId);
568
+
569
+ // Initiate server-side validation asynchronously
570
+ this.validatePurchaseOnServer(transaction).catch(console.error);
571
+
572
+ return transaction;
573
+ } catch (error) {
574
+ console.error('Subscription purchase failed:', error);
575
+ throw error;
576
+ }
577
+ }
578
+
390
579
  private async grantAccess(productId: string) {
391
580
  // Implement logic to grant immediate access to the purchased content
392
581
  console.log(`Granting access to ${productId}`);
@@ -411,13 +600,18 @@ class Store {
411
600
  }
412
601
  }
413
602
 
414
- // Usage remains the same
603
+ // Usage examples
415
604
  const store = new Store();
416
605
  await store.initialize();
417
606
 
418
607
  try {
419
- await store.purchaseProduct('premium_subscription');
420
- console.log('Purchase completed successfully');
608
+ // Purchase in-app product (one-time purchase)
609
+ await store.purchaseProduct('premium_features');
610
+ console.log('In-app purchase completed successfully');
611
+
612
+ // Purchase subscription (requires planIdentifier)
613
+ await store.purchaseSubscription('premium_monthly', 'monthly-plan');
614
+ console.log('Subscription completed successfully');
421
615
  } catch (error) {
422
616
  console.error('Purchase failed:', error);
423
617
  }
@@ -554,14 +748,14 @@ Restores a user's previous and links their appUserIDs to any user's also using
554
748
  ### purchaseProduct(...)
555
749
 
556
750
  ```typescript
557
- purchaseProduct(options: { productIdentifier: string; planIdentifier?: string; productType?: PURCHASE_TYPE; quantity?: number; }) => Promise<Transaction>
751
+ purchaseProduct(options: { productIdentifier: string; planIdentifier?: string; productType?: PURCHASE_TYPE; quantity?: number; appAccountToken?: string; }) => Promise<Transaction>
558
752
  ```
559
753
 
560
754
  Started purchase process for the given product.
561
755
 
562
- | Param | Type | Description |
563
- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
564
- | **`options`** | <code>{ productIdentifier: string; planIdentifier?: string; productType?: <a href="#purchase_type">PURCHASE_TYPE</a>; quantity?: number; }</code> | - The product to purchase |
756
+ | Param | Type | Description |
757
+ | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
758
+ | **`options`** | <code>{ productIdentifier: string; planIdentifier?: string; productType?: <a href="#purchase_type">PURCHASE_TYPE</a>; quantity?: number; appAccountToken?: string; }</code> | - The product to purchase |
565
759
 
566
760
  **Returns:** <code>Promise&lt;<a href="#transaction">Transaction</a>&gt;</code>
567
761
 
@@ -633,9 +827,10 @@ Get the native Capacitor plugin version
633
827
 
634
828
  #### Transaction
635
829
 
636
- | Prop | Type | Description |
637
- | ------------------- | ------------------- | -------------------------------------------- |
638
- | **`transactionId`** | <code>string</code> | RevenueCat Id associated to the transaction. |
830
+ | Prop | Type | Description |
831
+ | ------------------- | ------------------- | --------------------------------------------------------------- |
832
+ | **`transactionId`** | <code>string</code> | RevenueCat Id associated to the transaction. |
833
+ | **`receipt`** | <code>string</code> | Receipt data for validation (iOS only - base64 encoded receipt) |
639
834
 
640
835
 
641
836
  #### Product
@@ -375,15 +375,14 @@ public class NativePurchasesPlugin extends Plugin {
375
375
  return;
376
376
  }
377
377
 
378
- String productId = productType.equals("inapp")
379
- ? productIdentifier
380
- : planIdentifier;
381
- Log.d(TAG, "Using product ID for query: " + productId);
378
+ // For subscriptions, always use the productIdentifier (subscription ID) to query
379
+ // The planIdentifier is used later when setting the offer token
380
+ Log.d(TAG, "Using product ID for query: " + productIdentifier);
382
381
 
383
382
  ImmutableList<QueryProductDetailsParams.Product> productList =
384
383
  ImmutableList.of(
385
384
  QueryProductDetailsParams.Product.newBuilder()
386
- .setProductId(productId)
385
+ .setProductId(productIdentifier)
387
386
  .setProductType(
388
387
  productType.equals("inapp")
389
388
  ? BillingClient.ProductType.INAPP
package/dist/docs.json CHANGED
@@ -17,12 +17,12 @@
17
17
  },
18
18
  {
19
19
  "name": "purchaseProduct",
20
- "signature": "(options: { productIdentifier: string; planIdentifier?: string; productType?: PURCHASE_TYPE; quantity?: number; }) => Promise<Transaction>",
20
+ "signature": "(options: { productIdentifier: string; planIdentifier?: string; productType?: PURCHASE_TYPE; quantity?: number; appAccountToken?: string; }) => Promise<Transaction>",
21
21
  "parameters": [
22
22
  {
23
23
  "name": "options",
24
24
  "docs": "- The product to purchase",
25
- "type": "{ productIdentifier: string; planIdentifier?: string | undefined; productType?: PURCHASE_TYPE | undefined; quantity?: number | undefined; }"
25
+ "type": "{ productIdentifier: string; planIdentifier?: string | undefined; productType?: PURCHASE_TYPE | undefined; quantity?: number | undefined; appAccountToken?: string | undefined; }"
26
26
  }
27
27
  ],
28
28
  "returns": "Promise<Transaction>",
@@ -46,6 +46,10 @@
46
46
  {
47
47
  "name": "param",
48
48
  "text": "options.quantity - Only iOS, the number of items you wish to purchase. Will use 1 by default."
49
+ },
50
+ {
51
+ "name": "param",
52
+ "text": "options.appAccountToken - Only iOS, UUID for the user's account. Used to link purchases to the user account for App Store Server Notifications."
49
53
  }
50
54
  ],
51
55
  "docs": "Started purchase process for the given product.",
@@ -173,6 +177,13 @@
173
177
  "docs": "RevenueCat Id associated to the transaction.",
174
178
  "complexTypes": [],
175
179
  "type": "string"
180
+ },
181
+ {
182
+ "name": "receipt",
183
+ "tags": [],
184
+ "docs": "Receipt data for validation (iOS only - base64 encoded receipt)",
185
+ "complexTypes": [],
186
+ "type": "string | undefined"
176
187
  }
177
188
  ]
178
189
  },
@@ -124,6 +124,10 @@ export interface Transaction {
124
124
  * RevenueCat Id associated to the transaction.
125
125
  */
126
126
  readonly transactionId: string;
127
+ /**
128
+ * Receipt data for validation (iOS only - base64 encoded receipt)
129
+ */
130
+ readonly receipt?: string;
127
131
  }
128
132
  export interface SubscriptionPeriod {
129
133
  /**
@@ -236,12 +240,14 @@ export interface NativePurchasesPlugin {
236
240
  * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.
237
241
  * @param options.planIdentifier - Only Android, the identifier of the plan you want to purchase, require for for subs.
238
242
  * @param options.quantity - Only iOS, the number of items you wish to purchase. Will use 1 by default.
243
+ * @param options.appAccountToken - Only iOS, UUID for the user's account. Used to link purchases to the user account for App Store Server Notifications.
239
244
  */
240
245
  purchaseProduct(options: {
241
246
  productIdentifier: string;
242
247
  planIdentifier?: string;
243
248
  productType?: PURCHASE_TYPE;
244
249
  quantity?: number;
250
+ appAccountToken?: string;
245
251
  }): Promise<Transaction>;
246
252
  /**
247
253
  * Gets the product info associated with a list of product identifiers.
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,mBAOX;AAPD,WAAY,mBAAmB;IAC7B,qFAAoB,CAAA;IACpB,iEAAU,CAAA;IACV,uEAAa,CAAA;IACb,iEAAU,CAAA;IACV,iEAAU,CAAA;IACV,qEAAY,CAAA;AACd,CAAC,EAPW,mBAAmB,KAAnB,mBAAmB,QAO9B;AAED,MAAM,CAAN,IAAY,aAUX;AAVD,WAAY,aAAa;IACvB;;OAEG;IACH,gCAAe,CAAA;IAEf;;OAEG;IACH,8BAAa,CAAA;AACf,CAAC,EAVW,aAAa,KAAb,aAAa,QAUxB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAyBX;AAzBD,WAAY,eAAe;IACzB;;OAEG;IACH,uEAAa,CAAA;IAEb;;OAEG;IACH,qFAAoB,CAAA;IAEpB;;OAEG;IACH,iFAAkB,CAAA;IAElB;;OAEG;IACH,mFAAmB,CAAA;IAEnB;;OAEG;IACH,+FAAyB,CAAA;AAC3B,CAAC,EAzBW,eAAe,KAAf,eAAe,QAyB1B;AACD,MAAM,CAAN,IAAY,cA2BX;AA3BD,WAAY,cAAc;IACxB,qIAAiD,CAAA;IAEjD;;;OAGG;IACH,qGAAiC,CAAA;IAEjC;;;;OAIG;IACH,iHAAuC,CAAA;IAEvC;;;OAGG;IACH,iGAA+B,CAAA;IAE/B;;;OAGG;IACH,2DAAY,CAAA;AACd,CAAC,EA3BW,cAAc,KAAd,cAAc,QA2BzB;AAED,MAAM,CAAN,IAAY,YA6CX;AA7CD,WAAY,YAAY;IACtB;;OAEG;IACH,mCAAmB,CAAA;IAEnB;;OAEG;IACH,iCAAiB,CAAA;IAEjB;;OAEG;IACH,qCAAqB,CAAA;IAErB;;OAEG;IACH,iCAAiB,CAAA;IAEjB;;OAEG;IACH,uCAAuB,CAAA;IAEvB;;OAEG;IACH,2CAA2B,CAAA;IAE3B;;OAEG;IACH,uCAAuB,CAAA;IAEvB;;OAEG;IACH,mCAAmB,CAAA;IAEnB;;OAEG;IACH,iCAAiB,CAAA;AACnB,CAAC,EA7CW,YAAY,KAAZ,YAAY,QA6CvB;AAED,MAAM,CAAN,IAAY,wBAaX;AAbD,WAAY,wBAAwB;IAClC;;OAEG;IACH,+HAAoC,CAAA;IACpC;;OAEG;IACH,qIAAmC,CAAA;IACnC;;OAEG;IACH,iIAAiC,CAAA;AACnC,CAAC,EAbW,wBAAwB,KAAxB,wBAAwB,QAanC","sourcesContent":["export enum ATTRIBUTION_NETWORK {\n APPLE_SEARCH_ADS = 0,\n ADJUST = 1,\n APPSFLYER = 2,\n BRANCH = 3,\n TENJIN = 4,\n FACEBOOK = 5,\n}\n\nexport enum PURCHASE_TYPE {\n /**\n * A type of SKU for in-app products.\n */\n INAPP = \"inapp\",\n\n /**\n * A type of SKU for subscriptions.\n */\n SUBS = \"subs\",\n}\n\n/**\n * Enum for billing features.\n * Currently, these are only relevant for Google Play Android users:\n * https://developer.android.com/reference/com/android/billingclient/api/BillingClient.FeatureType\n */\nexport enum BILLING_FEATURE {\n /**\n * Purchase/query for subscriptions.\n */\n SUBSCRIPTIONS,\n\n /**\n * Subscriptions update/replace.\n */\n SUBSCRIPTIONS_UPDATE,\n\n /**\n * Purchase/query for in-app items on VR.\n */\n IN_APP_ITEMS_ON_VR,\n\n /**\n * Purchase/query for subscriptions on VR.\n */\n SUBSCRIPTIONS_ON_VR,\n\n /**\n * Launch a price change confirmation flow.\n */\n PRICE_CHANGE_CONFIRMATION,\n}\nexport enum PRORATION_MODE {\n UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY = 0,\n\n /**\n * Replacement takes effect immediately, and the remaining time will be\n * prorated and credited to the user. This is the current default behavior.\n */\n IMMEDIATE_WITH_TIME_PRORATION = 1,\n\n /**\n * Replacement takes effect immediately, and the billing cycle remains the\n * same. The price for the remaining period will be charged. This option is\n * only available for subscription upgrade.\n */\n IMMEDIATE_AND_CHARGE_PRORATED_PRICE = 2,\n\n /**\n * Replacement takes effect immediately, and the new price will be charged on\n * next recurrence time. The billing cycle stays the same.\n */\n IMMEDIATE_WITHOUT_PRORATION = 3,\n\n /**\n * Replacement takes effect when the old plan expires, and the new price will\n * be charged at the same time.\n */\n DEFERRED = 4,\n}\n\nexport enum PACKAGE_TYPE {\n /**\n * A package that was defined with a custom identifier.\n */\n UNKNOWN = \"UNKNOWN\",\n\n /**\n * A package that was defined with a custom identifier.\n */\n CUSTOM = \"CUSTOM\",\n\n /**\n * A package configured with the predefined lifetime identifier.\n */\n LIFETIME = \"LIFETIME\",\n\n /**\n * A package configured with the predefined annual identifier.\n */\n ANNUAL = \"ANNUAL\",\n\n /**\n * A package configured with the predefined six month identifier.\n */\n SIX_MONTH = \"SIX_MONTH\",\n\n /**\n * A package configured with the predefined three month identifier.\n */\n THREE_MONTH = \"THREE_MONTH\",\n\n /**\n * A package configured with the predefined two month identifier.\n */\n TWO_MONTH = \"TWO_MONTH\",\n\n /**\n * A package configured with the predefined monthly identifier.\n */\n MONTHLY = \"MONTHLY\",\n\n /**\n * A package configured with the predefined weekly identifier.\n */\n WEEKLY = \"WEEKLY\",\n}\n\nexport enum INTRO_ELIGIBILITY_STATUS {\n /**\n * RevenueCat doesn't have enough information to determine eligibility.\n */\n INTRO_ELIGIBILITY_STATUS_UNKNOWN = 0,\n /**\n * The user is not eligible for a free trial or intro pricing for this product.\n */\n INTRO_ELIGIBILITY_STATUS_INELIGIBLE,\n /**\n * The user is eligible for a free trial or intro pricing for this product.\n */\n INTRO_ELIGIBILITY_STATUS_ELIGIBLE,\n}\n\nexport interface Transaction {\n /**\n * RevenueCat Id associated to the transaction.\n */\n readonly transactionId: string;\n /**\n * Product Id associated with the transaction.\n */\n // readonly productIdentifier: string;\n /**\n * Purchase date of the transaction in ISO 8601 format.\n */\n // readonly purchaseDate: string;\n}\n\nexport interface SubscriptionPeriod {\n /**\n * The Subscription Period number of unit.\n */\n readonly numberOfUnits: number;\n /**\n * The Subscription Period unit.\n */\n readonly unit: number;\n}\nexport interface SKProductDiscount {\n /**\n * The Product discount identifier.\n */\n readonly identifier: string;\n /**\n * The Product discount type.\n */\n readonly type: number;\n /**\n * The Product discount price.\n */\n readonly price: number;\n /**\n * Formatted price of the item, including its currency sign, such as €3.99.\n */\n readonly priceString: string;\n /**\n * The Product discount currency symbol.\n */\n readonly currencySymbol: string;\n /**\n * The Product discount currency code.\n */\n readonly currencyCode: string;\n /**\n * The Product discount paymentMode.\n */\n readonly paymentMode: number;\n /**\n * The Product discount number Of Periods.\n */\n readonly numberOfPeriods: number;\n /**\n * The Product discount subscription period.\n */\n readonly subscriptionPeriod: SubscriptionPeriod;\n}\nexport interface Product {\n /**\n * Product Id.\n */\n readonly identifier: string;\n /**\n * Description of the product.\n */\n readonly description: string;\n /**\n * Title of the product.\n */\n readonly title: string;\n /**\n * Price of the product in the local currency.\n */\n readonly price: number;\n /**\n * Formatted price of the item, including its currency sign, such as €3.99.\n */\n readonly priceString: string;\n /**\n * Currency code for price and original price.\n */\n readonly currencyCode: string;\n /**\n * Currency symbol for price and original price.\n */\n readonly currencySymbol: string;\n /**\n * Boolean indicating if the product is sharable with family\n */\n readonly isFamilyShareable: boolean;\n /**\n * Group identifier for the product.\n */\n readonly subscriptionGroupIdentifier: string;\n /**\n * The Product subcription group identifier.\n */\n readonly subscriptionPeriod: SubscriptionPeriod;\n /**\n * The Product introductory Price.\n */\n readonly introductoryPrice: SKProductDiscount | null;\n /**\n * The Product discounts list.\n */\n readonly discounts: SKProductDiscount[];\n}\n\nexport interface NativePurchasesPlugin {\n /**\n * Restores a user's previous and links their appUserIDs to any user's also using those .\n */\n restorePurchases(): Promise<void>;\n\n /**\n * Started purchase process for the given product.\n *\n * @param options - The product to purchase\n * @param options.productIdentifier - The product identifier of the product you want to purchase.\n * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.\n * @param options.planIdentifier - Only Android, the identifier of the plan you want to purchase, require for for subs.\n * @param options.quantity - Only iOS, the number of items you wish to purchase. Will use 1 by default.\n */\n purchaseProduct(options: {\n productIdentifier: string;\n planIdentifier?: string;\n productType?: PURCHASE_TYPE;\n quantity?: number;\n }): Promise<Transaction>;\n\n /**\n * Gets the product info associated with a list of product identifiers.\n *\n * @param options - The product identifiers you wish to retrieve information for\n * @param options.productIdentifiers - Array of product identifiers\n * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.\n * @returns - The requested product info\n */\n getProducts(options: {\n productIdentifiers: string[];\n productType?: PURCHASE_TYPE;\n }): Promise<{ products: Product[] }>;\n\n /**\n * Gets the product info for a single product identifier.\n *\n * @param options - The product identifier you wish to retrieve information for\n * @param options.productIdentifier - The product identifier\n * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.\n * @returns - The requested product info\n */\n getProduct(options: {\n productIdentifier: string;\n productType?: PURCHASE_TYPE;\n }): Promise<{ product: Product }>;\n\n /**\n * Check if billing is supported for the current device.\n *\n *\n */\n isBillingSupported(): Promise<{ isBillingSupported: boolean }>;\n /**\n * Get the native Capacitor plugin version\n *\n * @returns {Promise<{ id: string }>} an Promise with version for this device\n * @throws An error if the something went wrong\n */\n getPluginVersion(): Promise<{ version: string }>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,mBAOX;AAPD,WAAY,mBAAmB;IAC7B,qFAAoB,CAAA;IACpB,iEAAU,CAAA;IACV,uEAAa,CAAA;IACb,iEAAU,CAAA;IACV,iEAAU,CAAA;IACV,qEAAY,CAAA;AACd,CAAC,EAPW,mBAAmB,KAAnB,mBAAmB,QAO9B;AAED,MAAM,CAAN,IAAY,aAUX;AAVD,WAAY,aAAa;IACvB;;OAEG;IACH,gCAAe,CAAA;IAEf;;OAEG;IACH,8BAAa,CAAA;AACf,CAAC,EAVW,aAAa,KAAb,aAAa,QAUxB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAyBX;AAzBD,WAAY,eAAe;IACzB;;OAEG;IACH,uEAAa,CAAA;IAEb;;OAEG;IACH,qFAAoB,CAAA;IAEpB;;OAEG;IACH,iFAAkB,CAAA;IAElB;;OAEG;IACH,mFAAmB,CAAA;IAEnB;;OAEG;IACH,+FAAyB,CAAA;AAC3B,CAAC,EAzBW,eAAe,KAAf,eAAe,QAyB1B;AACD,MAAM,CAAN,IAAY,cA2BX;AA3BD,WAAY,cAAc;IACxB,qIAAiD,CAAA;IAEjD;;;OAGG;IACH,qGAAiC,CAAA;IAEjC;;;;OAIG;IACH,iHAAuC,CAAA;IAEvC;;;OAGG;IACH,iGAA+B,CAAA;IAE/B;;;OAGG;IACH,2DAAY,CAAA;AACd,CAAC,EA3BW,cAAc,KAAd,cAAc,QA2BzB;AAED,MAAM,CAAN,IAAY,YA6CX;AA7CD,WAAY,YAAY;IACtB;;OAEG;IACH,mCAAmB,CAAA;IAEnB;;OAEG;IACH,iCAAiB,CAAA;IAEjB;;OAEG;IACH,qCAAqB,CAAA;IAErB;;OAEG;IACH,iCAAiB,CAAA;IAEjB;;OAEG;IACH,uCAAuB,CAAA;IAEvB;;OAEG;IACH,2CAA2B,CAAA;IAE3B;;OAEG;IACH,uCAAuB,CAAA;IAEvB;;OAEG;IACH,mCAAmB,CAAA;IAEnB;;OAEG;IACH,iCAAiB,CAAA;AACnB,CAAC,EA7CW,YAAY,KAAZ,YAAY,QA6CvB;AAED,MAAM,CAAN,IAAY,wBAaX;AAbD,WAAY,wBAAwB;IAClC;;OAEG;IACH,+HAAoC,CAAA;IACpC;;OAEG;IACH,qIAAmC,CAAA;IACnC;;OAEG;IACH,iIAAiC,CAAA;AACnC,CAAC,EAbW,wBAAwB,KAAxB,wBAAwB,QAanC","sourcesContent":["export enum ATTRIBUTION_NETWORK {\n APPLE_SEARCH_ADS = 0,\n ADJUST = 1,\n APPSFLYER = 2,\n BRANCH = 3,\n TENJIN = 4,\n FACEBOOK = 5,\n}\n\nexport enum PURCHASE_TYPE {\n /**\n * A type of SKU for in-app products.\n */\n INAPP = \"inapp\",\n\n /**\n * A type of SKU for subscriptions.\n */\n SUBS = \"subs\",\n}\n\n/**\n * Enum for billing features.\n * Currently, these are only relevant for Google Play Android users:\n * https://developer.android.com/reference/com/android/billingclient/api/BillingClient.FeatureType\n */\nexport enum BILLING_FEATURE {\n /**\n * Purchase/query for subscriptions.\n */\n SUBSCRIPTIONS,\n\n /**\n * Subscriptions update/replace.\n */\n SUBSCRIPTIONS_UPDATE,\n\n /**\n * Purchase/query for in-app items on VR.\n */\n IN_APP_ITEMS_ON_VR,\n\n /**\n * Purchase/query for subscriptions on VR.\n */\n SUBSCRIPTIONS_ON_VR,\n\n /**\n * Launch a price change confirmation flow.\n */\n PRICE_CHANGE_CONFIRMATION,\n}\nexport enum PRORATION_MODE {\n UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY = 0,\n\n /**\n * Replacement takes effect immediately, and the remaining time will be\n * prorated and credited to the user. This is the current default behavior.\n */\n IMMEDIATE_WITH_TIME_PRORATION = 1,\n\n /**\n * Replacement takes effect immediately, and the billing cycle remains the\n * same. The price for the remaining period will be charged. This option is\n * only available for subscription upgrade.\n */\n IMMEDIATE_AND_CHARGE_PRORATED_PRICE = 2,\n\n /**\n * Replacement takes effect immediately, and the new price will be charged on\n * next recurrence time. The billing cycle stays the same.\n */\n IMMEDIATE_WITHOUT_PRORATION = 3,\n\n /**\n * Replacement takes effect when the old plan expires, and the new price will\n * be charged at the same time.\n */\n DEFERRED = 4,\n}\n\nexport enum PACKAGE_TYPE {\n /**\n * A package that was defined with a custom identifier.\n */\n UNKNOWN = \"UNKNOWN\",\n\n /**\n * A package that was defined with a custom identifier.\n */\n CUSTOM = \"CUSTOM\",\n\n /**\n * A package configured with the predefined lifetime identifier.\n */\n LIFETIME = \"LIFETIME\",\n\n /**\n * A package configured with the predefined annual identifier.\n */\n ANNUAL = \"ANNUAL\",\n\n /**\n * A package configured with the predefined six month identifier.\n */\n SIX_MONTH = \"SIX_MONTH\",\n\n /**\n * A package configured with the predefined three month identifier.\n */\n THREE_MONTH = \"THREE_MONTH\",\n\n /**\n * A package configured with the predefined two month identifier.\n */\n TWO_MONTH = \"TWO_MONTH\",\n\n /**\n * A package configured with the predefined monthly identifier.\n */\n MONTHLY = \"MONTHLY\",\n\n /**\n * A package configured with the predefined weekly identifier.\n */\n WEEKLY = \"WEEKLY\",\n}\n\nexport enum INTRO_ELIGIBILITY_STATUS {\n /**\n * RevenueCat doesn't have enough information to determine eligibility.\n */\n INTRO_ELIGIBILITY_STATUS_UNKNOWN = 0,\n /**\n * The user is not eligible for a free trial or intro pricing for this product.\n */\n INTRO_ELIGIBILITY_STATUS_INELIGIBLE,\n /**\n * The user is eligible for a free trial or intro pricing for this product.\n */\n INTRO_ELIGIBILITY_STATUS_ELIGIBLE,\n}\n\nexport interface Transaction {\n /**\n * RevenueCat Id associated to the transaction.\n */\n readonly transactionId: string;\n /**\n * Receipt data for validation (iOS only - base64 encoded receipt)\n */\n readonly receipt?: string;\n /**\n * Product Id associated with the transaction.\n */\n // readonly productIdentifier: string;\n /**\n * Purchase date of the transaction in ISO 8601 format.\n */\n // readonly purchaseDate: string;\n}\n\nexport interface SubscriptionPeriod {\n /**\n * The Subscription Period number of unit.\n */\n readonly numberOfUnits: number;\n /**\n * The Subscription Period unit.\n */\n readonly unit: number;\n}\nexport interface SKProductDiscount {\n /**\n * The Product discount identifier.\n */\n readonly identifier: string;\n /**\n * The Product discount type.\n */\n readonly type: number;\n /**\n * The Product discount price.\n */\n readonly price: number;\n /**\n * Formatted price of the item, including its currency sign, such as €3.99.\n */\n readonly priceString: string;\n /**\n * The Product discount currency symbol.\n */\n readonly currencySymbol: string;\n /**\n * The Product discount currency code.\n */\n readonly currencyCode: string;\n /**\n * The Product discount paymentMode.\n */\n readonly paymentMode: number;\n /**\n * The Product discount number Of Periods.\n */\n readonly numberOfPeriods: number;\n /**\n * The Product discount subscription period.\n */\n readonly subscriptionPeriod: SubscriptionPeriod;\n}\nexport interface Product {\n /**\n * Product Id.\n */\n readonly identifier: string;\n /**\n * Description of the product.\n */\n readonly description: string;\n /**\n * Title of the product.\n */\n readonly title: string;\n /**\n * Price of the product in the local currency.\n */\n readonly price: number;\n /**\n * Formatted price of the item, including its currency sign, such as €3.99.\n */\n readonly priceString: string;\n /**\n * Currency code for price and original price.\n */\n readonly currencyCode: string;\n /**\n * Currency symbol for price and original price.\n */\n readonly currencySymbol: string;\n /**\n * Boolean indicating if the product is sharable with family\n */\n readonly isFamilyShareable: boolean;\n /**\n * Group identifier for the product.\n */\n readonly subscriptionGroupIdentifier: string;\n /**\n * The Product subcription group identifier.\n */\n readonly subscriptionPeriod: SubscriptionPeriod;\n /**\n * The Product introductory Price.\n */\n readonly introductoryPrice: SKProductDiscount | null;\n /**\n * The Product discounts list.\n */\n readonly discounts: SKProductDiscount[];\n}\n\nexport interface NativePurchasesPlugin {\n /**\n * Restores a user's previous and links their appUserIDs to any user's also using those .\n */\n restorePurchases(): Promise<void>;\n\n /**\n * Started purchase process for the given product.\n *\n * @param options - The product to purchase\n * @param options.productIdentifier - The product identifier of the product you want to purchase.\n * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.\n * @param options.planIdentifier - Only Android, the identifier of the plan you want to purchase, require for for subs.\n * @param options.quantity - Only iOS, the number of items you wish to purchase. Will use 1 by default.\n * @param options.appAccountToken - Only iOS, UUID for the user's account. Used to link purchases to the user account for App Store Server Notifications.\n */\n purchaseProduct(options: {\n productIdentifier: string;\n planIdentifier?: string;\n productType?: PURCHASE_TYPE;\n quantity?: number;\n appAccountToken?: string;\n }): Promise<Transaction>;\n\n /**\n * Gets the product info associated with a list of product identifiers.\n *\n * @param options - The product identifiers you wish to retrieve information for\n * @param options.productIdentifiers - Array of product identifiers\n * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.\n * @returns - The requested product info\n */\n getProducts(options: {\n productIdentifiers: string[];\n productType?: PURCHASE_TYPE;\n }): Promise<{ products: Product[] }>;\n\n /**\n * Gets the product info for a single product identifier.\n *\n * @param options - The product identifier you wish to retrieve information for\n * @param options.productIdentifier - The product identifier\n * @param options.productType - Only Android, the type of product, can be inapp or subs. Will use inapp by default.\n * @returns - The requested product info\n */\n getProduct(options: {\n productIdentifier: string;\n productType?: PURCHASE_TYPE;\n }): Promise<{ product: Product }>;\n\n /**\n * Check if billing is supported for the current device.\n *\n *\n */\n isBillingSupported(): Promise<{ isBillingSupported: boolean }>;\n /**\n * Get the native Capacitor plugin version\n *\n * @returns {Promise<{ id: string }>} an Promise with version for this device\n * @throws An error if the something went wrong\n */\n getPluginVersion(): Promise<{ version: string }>;\n}\n"]}
@@ -42,6 +42,8 @@ public class NativePurchasesPlugin: CAPPlugin, CAPBridgedPlugin {
42
42
  print("purchaseProduct")
43
43
  let productIdentifier = call.getString("productIdentifier", "")
44
44
  let quantity = call.getInt("quantity", 1)
45
+ let appAccountToken = call.getString("appAccountToken")
46
+
45
47
  if productIdentifier.isEmpty {
46
48
  call.reject("productIdentifier is Empty, give an id")
47
49
  return
@@ -56,13 +58,31 @@ public class NativePurchasesPlugin: CAPPlugin, CAPBridgedPlugin {
56
58
  }
57
59
  var purchaseOptions = Set<Product.PurchaseOption>()
58
60
  purchaseOptions.insert(Product.PurchaseOption.quantity(quantity))
61
+
62
+ // Add appAccountToken if provided
63
+ if let accountToken = appAccountToken, !accountToken.isEmpty {
64
+ if let tokenData = UUID(uuidString: accountToken) {
65
+ purchaseOptions.insert(Product.PurchaseOption.appAccountToken(tokenData))
66
+ }
67
+ }
68
+
59
69
  let result = try await product.purchase(options: purchaseOptions)
60
70
  print("purchaseProduct result \(result)")
61
71
  switch result {
62
72
  case let .success(.verified(transaction)):
63
- // Successful purhcase
73
+ // Successful purchase
74
+ var response: [String: Any] = ["transactionId": transaction.id]
75
+
76
+ // Get receipt data
77
+ if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
78
+ FileManager.default.fileExists(atPath: appStoreReceiptURL.path),
79
+ let receiptData = try? Data(contentsOf: appStoreReceiptURL) {
80
+ let receiptBase64 = receiptData.base64EncodedString()
81
+ response["receipt"] = receiptBase64
82
+ }
83
+
64
84
  await transaction.finish()
65
- call.resolve(["transactionId": transaction.id])
85
+ call.resolve(response)
66
86
  case let .success(.unverified(_, error)):
67
87
  // Successful purchase but transaction/receipt can't be verified
68
88
  // Could be a jailbroken phone
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/native-purchases",
3
- "version": "7.1.30",
3
+ "version": "7.1.32",
4
4
  "description": "In-app Subscriptions Made Easy",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",