react-native-iap 14.6.2 → 14.6.3-rc.2

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/src/index.ts CHANGED
@@ -1068,14 +1068,17 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
1068
1068
  }
1069
1069
 
1070
1070
  if (Platform.OS === 'ios') {
1071
- const iosRequest = perPlatformRequest.ios;
1071
+ // Support both 'apple' (recommended) and 'ios' (deprecated) fields
1072
+ const iosRequest = perPlatformRequest.apple ?? perPlatformRequest.ios;
1072
1073
  if (!iosRequest?.sku) {
1073
1074
  throw new Error(
1074
1075
  'Invalid request for iOS. The `sku` property is required.',
1075
1076
  );
1076
1077
  }
1077
1078
  } else if (Platform.OS === 'android') {
1078
- const androidRequest = perPlatformRequest.android;
1079
+ // Support both 'google' (recommended) and 'android' (deprecated) fields
1080
+ const androidRequest =
1081
+ perPlatformRequest.google ?? perPlatformRequest.android;
1079
1082
  if (!androidRequest?.skus?.length) {
1080
1083
  throw new Error(
1081
1084
  'Invalid request for Android. The `skus` property is required and must be a non-empty array.',
@@ -1087,10 +1090,12 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
1087
1090
 
1088
1091
  const unifiedRequest: NitroPurchaseRequest = {};
1089
1092
 
1090
- if (Platform.OS === 'ios' && perPlatformRequest.ios) {
1093
+ // Support both 'apple' (recommended) and 'ios' (deprecated) fields
1094
+ const iosRequestSource = perPlatformRequest.apple ?? perPlatformRequest.ios;
1095
+ if (Platform.OS === 'ios' && iosRequestSource) {
1091
1096
  const iosRequest = isSubs
1092
- ? (perPlatformRequest.ios as RequestSubscriptionIosProps)
1093
- : (perPlatformRequest.ios as RequestPurchaseIosProps);
1097
+ ? (iosRequestSource as RequestSubscriptionIosProps)
1098
+ : (iosRequestSource as RequestPurchaseIosProps);
1094
1099
 
1095
1100
  const iosPayload: NonNullable<NitroPurchaseRequest['ios']> = {
1096
1101
  sku: iosRequest.sku,
@@ -1117,14 +1122,20 @@ export const requestPurchase: MutationField<'requestPurchase'> = async (
1117
1122
  if (offerRecord) {
1118
1123
  iosPayload.withOffer = offerRecord;
1119
1124
  }
1125
+ if (iosRequest.advancedCommerceData) {
1126
+ iosPayload.advancedCommerceData = iosRequest.advancedCommerceData;
1127
+ }
1120
1128
 
1121
1129
  unifiedRequest.ios = iosPayload;
1122
1130
  }
1123
1131
 
1124
- if (Platform.OS === 'android' && perPlatformRequest.android) {
1132
+ // Support both 'google' (recommended) and 'android' (deprecated) fields
1133
+ const androidRequestSource =
1134
+ perPlatformRequest.google ?? perPlatformRequest.android;
1135
+ if (Platform.OS === 'android' && androidRequestSource) {
1125
1136
  const androidRequest = isSubs
1126
- ? (perPlatformRequest.android as RequestSubscriptionAndroidProps)
1127
- : (perPlatformRequest.android as RequestPurchaseAndroidProps);
1137
+ ? (androidRequestSource as RequestSubscriptionAndroidProps)
1138
+ : (androidRequestSource as RequestPurchaseAndroidProps);
1128
1139
 
1129
1140
  const androidPayload: NonNullable<NitroPurchaseRequest['android']> = {
1130
1141
  skus: androidRequest.skus,
@@ -1601,43 +1612,60 @@ export const presentCodeRedemptionSheetIOS: MutationField<
1601
1612
 
1602
1613
  /**
1603
1614
  * Buy promoted product on iOS
1615
+ * @deprecated In StoreKit 2, promoted products can be purchased directly via the standard `requestPurchase()` flow.
1616
+ * Use `promotedProductListenerIOS` to receive the product ID when a user taps a promoted product,
1617
+ * then call `requestPurchase()` with the received SKU directly.
1618
+ *
1619
+ * @example
1620
+ * ```typescript
1621
+ * // Recommended approach
1622
+ * promotedProductListenerIOS(async (product) => {
1623
+ * await requestPurchase({
1624
+ * request: { apple: { sku: product.id } },
1625
+ * type: 'in-app'
1626
+ * });
1627
+ * });
1628
+ * ```
1629
+ *
1604
1630
  * @returns Promise<boolean> - true when the request triggers successfully
1605
1631
  * @platform iOS
1606
1632
  */
1607
- export const requestPurchaseOnPromotedProductIOS: MutationField<
1608
- 'requestPurchaseOnPromotedProductIOS'
1609
- > = async () => {
1610
- if (Platform.OS !== 'ios') {
1611
- throw new Error(
1612
- 'requestPurchaseOnPromotedProductIOS is only available on iOS',
1613
- );
1614
- }
1615
-
1616
- try {
1617
- await IAP.instance.buyPromotedProductIOS();
1618
- const pending = await IAP.instance.getPendingTransactionsIOS();
1619
- const latest = pending.find((purchase) => purchase != null);
1620
- if (!latest) {
1621
- throw new Error('No promoted purchase available after request');
1633
+ export const requestPurchaseOnPromotedProductIOS =
1634
+ async (): Promise<boolean> => {
1635
+ if (Platform.OS !== 'ios') {
1636
+ throw new Error(
1637
+ 'requestPurchaseOnPromotedProductIOS is only available on iOS',
1638
+ );
1622
1639
  }
1623
1640
 
1624
- const converted = convertNitroPurchaseToPurchase(latest);
1625
- if (converted.platform !== 'ios') {
1626
- throw new Error('Promoted purchase result not available for iOS');
1627
- }
1641
+ try {
1642
+ await IAP.instance.buyPromotedProductIOS();
1643
+ const pending = await IAP.instance.getPendingTransactionsIOS();
1644
+ const latest = pending.find((purchase) => purchase != null);
1645
+ if (!latest) {
1646
+ throw new Error('No promoted purchase available after request');
1647
+ }
1628
1648
 
1629
- return true;
1630
- } catch (error) {
1631
- RnIapConsole.error('[requestPurchaseOnPromotedProductIOS] Failed:', error);
1632
- const parsedError = parseErrorStringToJsonObj(error);
1633
- throw createPurchaseError({
1634
- code: parsedError.code,
1635
- message: parsedError.message,
1636
- responseCode: parsedError.responseCode,
1637
- debugMessage: parsedError.debugMessage,
1638
- });
1639
- }
1640
- };
1649
+ const converted = convertNitroPurchaseToPurchase(latest);
1650
+ if (converted.platform !== 'ios') {
1651
+ throw new Error('Promoted purchase result not available for iOS');
1652
+ }
1653
+
1654
+ return true;
1655
+ } catch (error) {
1656
+ RnIapConsole.error(
1657
+ '[requestPurchaseOnPromotedProductIOS] Failed:',
1658
+ error,
1659
+ );
1660
+ const parsedError = parseErrorStringToJsonObj(error);
1661
+ throw createPurchaseError({
1662
+ code: parsedError.code,
1663
+ message: parsedError.message,
1664
+ responseCode: parsedError.responseCode,
1665
+ debugMessage: parsedError.debugMessage,
1666
+ });
1667
+ }
1668
+ };
1641
1669
 
1642
1670
  /**
1643
1671
  * Clear unfinished transactions on iOS
@@ -2333,9 +2361,9 @@ export const enableBillingProgramAndroid = (
2333
2361
  * }
2334
2362
  * ```
2335
2363
  */
2336
- export const isBillingProgramAvailableAndroid = async (
2337
- program: BillingProgramAndroid,
2338
- ): Promise<BillingProgramAvailabilityResultAndroid> => {
2364
+ export const isBillingProgramAvailableAndroid: MutationField<
2365
+ 'isBillingProgramAvailableAndroid'
2366
+ > = async (program) => {
2339
2367
  if (Platform.OS !== 'android') {
2340
2368
  throw new Error('Billing Programs API is only supported on Android');
2341
2369
  }
@@ -2372,9 +2400,9 @@ export const isBillingProgramAvailableAndroid = async (
2372
2400
  * });
2373
2401
  * ```
2374
2402
  */
2375
- export const createBillingProgramReportingDetailsAndroid = async (
2376
- program: BillingProgramAndroid,
2377
- ): Promise<BillingProgramReportingDetailsAndroid> => {
2403
+ export const createBillingProgramReportingDetailsAndroid: MutationField<
2404
+ 'createBillingProgramReportingDetailsAndroid'
2405
+ > = async (program) => {
2378
2406
  if (Platform.OS !== 'android') {
2379
2407
  throw new Error('Billing Programs API is only supported on Android');
2380
2408
  }
@@ -2417,9 +2445,9 @@ export const createBillingProgramReportingDetailsAndroid = async (
2417
2445
  * }
2418
2446
  * ```
2419
2447
  */
2420
- export const launchExternalLinkAndroid = async (
2421
- params: LaunchExternalLinkParamsAndroid,
2422
- ): Promise<boolean> => {
2448
+ export const launchExternalLinkAndroid: MutationField<
2449
+ 'launchExternalLinkAndroid'
2450
+ > = async (params) => {
2423
2451
  if (Platform.OS !== 'android') {
2424
2452
  throw new Error('Billing Programs API is only supported on Android');
2425
2453
  }
@@ -102,6 +102,13 @@ export interface NitroRequestPurchaseIos {
102
102
  appAccountToken?: RequestPurchaseIosProps['appAccountToken'];
103
103
  quantity?: RequestPurchaseIosProps['quantity'];
104
104
  withOffer?: Record<string, string> | null;
105
+ /**
106
+ * Advanced commerce data for StoreKit 2's Product.PurchaseOption.custom API.
107
+ * Used to pass attribution data (campaign tokens, affiliate IDs) during purchases.
108
+ * Data is formatted as JSON: {"signatureInfo": {"token": "<value>"}}
109
+ * @platform iOS
110
+ */
111
+ advancedCommerceData?: RequestPurchaseIosProps['advancedCommerceData'];
105
112
  }
106
113
 
107
114
  export interface NitroRequestPurchaseAndroid {
package/src/types.ts CHANGED
@@ -342,6 +342,15 @@ export interface Mutation {
342
342
  * Throws OpenIapError.NotPrepared if billing client not ready
343
343
  */
344
344
  createAlternativeBillingTokenAndroid?: Promise<(string | null)>;
345
+ /**
346
+ * Create reporting details for a billing program
347
+ * Replaces the deprecated createExternalOfferReportingDetailsAsync API
348
+ *
349
+ * Available in Google Play Billing Library 8.2.0+
350
+ * Returns external transaction token needed for reporting external transactions
351
+ * Throws OpenIapError.NotPrepared if billing client not ready
352
+ */
353
+ createBillingProgramReportingDetailsAndroid: Promise<BillingProgramReportingDetailsAndroid>;
345
354
  /** Open the native subscription management surface */
346
355
  deepLinkToSubscriptions: Promise<void>;
347
356
  /** Close the platform billing connection */
@@ -350,6 +359,24 @@ export interface Mutation {
350
359
  finishTransaction: Promise<void>;
351
360
  /** Establish the platform billing connection */
352
361
  initConnection: Promise<boolean>;
362
+ /**
363
+ * Check if a billing program is available for the current user
364
+ * Replaces the deprecated isExternalOfferAvailableAsync API
365
+ *
366
+ * Available in Google Play Billing Library 8.2.0+
367
+ * Returns availability result with isAvailable flag
368
+ * Throws OpenIapError.NotPrepared if billing client not ready
369
+ */
370
+ isBillingProgramAvailableAndroid: Promise<BillingProgramAvailabilityResultAndroid>;
371
+ /**
372
+ * Launch external link flow for external billing programs
373
+ * Replaces the deprecated showExternalOfferInformationDialog API
374
+ *
375
+ * Available in Google Play Billing Library 8.2.0+
376
+ * Shows Play Store dialog and optionally launches external URL
377
+ * Throws OpenIapError.NotPrepared if billing client not ready
378
+ */
379
+ launchExternalLinkAndroid: Promise<boolean>;
353
380
  /** Present the App Store code redemption sheet */
354
381
  presentCodeRedemptionSheetIOS: Promise<boolean>;
355
382
  /** Present external purchase custom link with StoreKit UI (iOS 18.2+) */
@@ -358,8 +385,15 @@ export interface Mutation {
358
385
  presentExternalPurchaseNoticeSheetIOS: Promise<ExternalPurchaseNoticeResultIOS>;
359
386
  /** Initiate a purchase flow; rely on events for final state */
360
387
  requestPurchase?: Promise<(Purchase | Purchase[] | null)>;
361
- /** Purchase the promoted product surfaced by the App Store */
362
- requestPurchaseOnPromotedProductIOS: Promise<boolean>;
388
+ /**
389
+ * Purchase the promoted product surfaced by the App Store.
390
+ *
391
+ * @deprecated Use promotedProductListenerIOS to receive the productId,
392
+ * then call requestPurchase with that SKU instead. In StoreKit 2,
393
+ * promoted products can be purchased directly via the standard purchase flow.
394
+ * @deprecated Use promotedProductListenerIOS + requestPurchase instead
395
+ */
396
+ requestPurchaseOnPromotedProductIOS: boolean;
363
397
  /** Restore completed purchases across platforms */
364
398
  restorePurchases: Promise<void>;
365
399
  /**
@@ -394,6 +428,8 @@ export type MutationBeginRefundRequestIosArgs = string;
394
428
 
395
429
  export type MutationConsumePurchaseAndroidArgs = string;
396
430
 
431
+ export type MutationCreateBillingProgramReportingDetailsAndroidArgs = BillingProgramAndroid;
432
+
397
433
  export type MutationDeepLinkToSubscriptionsArgs = (DeepLinkOptions | null) | undefined;
398
434
 
399
435
  export interface MutationFinishTransactionArgs {
@@ -404,6 +440,10 @@ export interface MutationFinishTransactionArgs {
404
440
 
405
441
  export type MutationInitConnectionArgs = (InitConnectionConfig | null) | undefined;
406
442
 
443
+ export type MutationIsBillingProgramAvailableAndroidArgs = BillingProgramAndroid;
444
+
445
+ export type MutationLaunchExternalLinkAndroidArgs = LaunchExternalLinkParamsAndroid;
446
+
407
447
  export type MutationPresentExternalPurchaseLinkIosArgs = string;
408
448
 
409
449
  export type MutationRequestPurchaseArgs =
@@ -889,6 +929,13 @@ export interface RequestPurchaseAndroidProps {
889
929
  }
890
930
 
891
931
  export interface RequestPurchaseIosProps {
932
+ /**
933
+ * Advanced commerce data token (iOS 15+).
934
+ * Used with StoreKit 2's Product.PurchaseOption.custom API for passing
935
+ * campaign tokens, affiliate IDs, or other attribution data.
936
+ * The data is formatted as JSON: {"signatureInfo": {"token": "<value>"}}
937
+ */
938
+ advancedCommerceData?: (string | null);
892
939
  /** Auto-finish transaction (dangerous) */
893
940
  andDangerouslyFinishTransactionAutomatically?: (boolean | null);
894
941
  /** App account token for user tracking */
@@ -964,6 +1011,13 @@ export interface RequestSubscriptionAndroidProps {
964
1011
  }
965
1012
 
966
1013
  export interface RequestSubscriptionIosProps {
1014
+ /**
1015
+ * Advanced commerce data token (iOS 15+).
1016
+ * Used with StoreKit 2's Product.PurchaseOption.custom API for passing
1017
+ * campaign tokens, affiliate IDs, or other attribution data.
1018
+ * The data is formatted as JSON: {"signatureInfo": {"token": "<value>"}}
1019
+ */
1020
+ advancedCommerceData?: (string | null);
967
1021
  andDangerouslyFinishTransactionAutomatically?: (boolean | null);
968
1022
  appAccountToken?: (string | null);
969
1023
  quantity?: (number | null);
@@ -1286,10 +1340,13 @@ export type MutationArgsMap = {
1286
1340
  clearTransactionIOS: never;
1287
1341
  consumePurchaseAndroid: MutationConsumePurchaseAndroidArgs;
1288
1342
  createAlternativeBillingTokenAndroid: never;
1343
+ createBillingProgramReportingDetailsAndroid: MutationCreateBillingProgramReportingDetailsAndroidArgs;
1289
1344
  deepLinkToSubscriptions: MutationDeepLinkToSubscriptionsArgs;
1290
1345
  endConnection: never;
1291
1346
  finishTransaction: MutationFinishTransactionArgs;
1292
1347
  initConnection: MutationInitConnectionArgs;
1348
+ isBillingProgramAvailableAndroid: MutationIsBillingProgramAvailableAndroidArgs;
1349
+ launchExternalLinkAndroid: MutationLaunchExternalLinkAndroidArgs;
1293
1350
  presentCodeRedemptionSheetIOS: never;
1294
1351
  presentExternalPurchaseLinkIOS: MutationPresentExternalPurchaseLinkIosArgs;
1295
1352
  presentExternalPurchaseNoticeSheetIOS: never;