expo-iap 3.1.38 → 3.2.1

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.
Files changed (43) hide show
  1. package/.prettierignore +1 -0
  2. package/README.md +1 -22
  3. package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +141 -13
  4. package/build/index.d.ts +15 -6
  5. package/build/index.d.ts.map +1 -1
  6. package/build/index.js +46 -29
  7. package/build/index.js.map +1 -1
  8. package/build/modules/android.d.ts +53 -1
  9. package/build/modules/android.d.ts.map +1 -1
  10. package/build/modules/android.js +61 -0
  11. package/build/modules/android.js.map +1 -1
  12. package/build/modules/ios.d.ts.map +1 -1
  13. package/build/modules/ios.js +4 -2
  14. package/build/modules/ios.js.map +1 -1
  15. package/build/types.d.ts +349 -20
  16. package/build/types.d.ts.map +1 -1
  17. package/build/types.js.map +1 -1
  18. package/build/useIAP.d.ts.map +1 -1
  19. package/build/useIAP.js +2 -0
  20. package/build/useIAP.js.map +1 -1
  21. package/coverage/clover.xml +176 -166
  22. package/coverage/coverage-final.json +3 -3
  23. package/coverage/lcov-report/index.html +23 -23
  24. package/coverage/lcov-report/src/index.html +14 -14
  25. package/coverage/lcov-report/src/index.ts.html +90 -39
  26. package/coverage/lcov-report/src/modules/android.ts.html +233 -8
  27. package/coverage/lcov-report/src/modules/index.html +15 -15
  28. package/coverage/lcov-report/src/modules/ios.ts.html +13 -7
  29. package/coverage/lcov-report/src/utils/debug.ts.html +1 -1
  30. package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
  31. package/coverage/lcov-report/src/utils/index.html +1 -1
  32. package/coverage/lcov.info +305 -284
  33. package/ios/ExpoIapModule.swift +1 -1
  34. package/openiap-versions.json +3 -3
  35. package/package.json +1 -1
  36. package/plugin/build/withIAP.d.ts +8 -5
  37. package/plugin/build/withIAP.js +12 -3
  38. package/plugin/src/withIAP.ts +18 -9
  39. package/src/index.ts +46 -29
  40. package/src/modules/android.ts +75 -0
  41. package/src/modules/ios.ts +4 -2
  42. package/src/types.ts +370 -21
  43. package/src/useIAP.ts +2 -0
package/src/types.ts CHANGED
@@ -65,6 +65,38 @@ export interface AppTransaction {
65
65
  signedDate: number;
66
66
  }
67
67
 
68
+ /**
69
+ * Billing program types for external content links and external offers (Android)
70
+ * Available in Google Play Billing Library 8.2.0+
71
+ */
72
+ export type BillingProgramAndroid = 'unspecified' | 'external-content-link' | 'external-offer';
73
+
74
+ /**
75
+ * Result of checking billing program availability (Android)
76
+ * Available in Google Play Billing Library 8.2.0+
77
+ */
78
+ export interface BillingProgramAvailabilityResultAndroid {
79
+ /** The billing program that was checked */
80
+ billingProgram: BillingProgramAndroid;
81
+ /** Whether the billing program is available for the user */
82
+ isAvailable: boolean;
83
+ }
84
+
85
+ /**
86
+ * Reporting details for transactions made outside of Google Play Billing (Android)
87
+ * Contains the external transaction token needed for reporting
88
+ * Available in Google Play Billing Library 8.2.0+
89
+ */
90
+ export interface BillingProgramReportingDetailsAndroid {
91
+ /** The billing program that the reporting details are associated with */
92
+ billingProgram: BillingProgramAndroid;
93
+ /**
94
+ * External transaction token used to report transactions made outside of Google Play Billing.
95
+ * This token must be used when reporting the external transaction to Google.
96
+ */
97
+ externalTransactionToken: string;
98
+ }
99
+
68
100
  export interface DeepLinkOptions {
69
101
  /** Android package name to target (required on Android) */
70
102
  packageNameAndroid?: (string | null);
@@ -72,6 +104,34 @@ export interface DeepLinkOptions {
72
104
  skuAndroid?: (string | null);
73
105
  }
74
106
 
107
+ /**
108
+ * Discount amount details for one-time purchase offers (Android)
109
+ * Available in Google Play Billing Library 7.0+
110
+ */
111
+ export interface DiscountAmountAndroid {
112
+ /** Discount amount in micro-units (1,000,000 = 1 unit of currency) */
113
+ discountAmountMicros: string;
114
+ /** Formatted discount amount with currency sign (e.g., "$4.99") */
115
+ formattedDiscountAmount: string;
116
+ }
117
+
118
+ /**
119
+ * Discount display information for one-time purchase offers (Android)
120
+ * Available in Google Play Billing Library 7.0+
121
+ */
122
+ export interface DiscountDisplayInfoAndroid {
123
+ /**
124
+ * Absolute discount amount details
125
+ * Only returned for fixed amount discounts
126
+ */
127
+ discountAmount?: (DiscountAmountAndroid | null);
128
+ /**
129
+ * Percentage discount (e.g., 33 for 33% off)
130
+ * Only returned for percentage-based discounts
131
+ */
132
+ percentageDiscount?: (number | null);
133
+ }
134
+
75
135
  export interface DiscountIOS {
76
136
  identifier: string;
77
137
  localizedPrice?: (string | null);
@@ -155,6 +215,40 @@ export enum ErrorCode {
155
215
  UserError = 'user-error'
156
216
  }
157
217
 
218
+ /**
219
+ * Launch mode for external link flow (Android)
220
+ * Determines how the external URL is launched
221
+ * Available in Google Play Billing Library 8.2.0+
222
+ */
223
+ export type ExternalLinkLaunchModeAndroid = 'unspecified' | 'launch-in-external-browser-or-app' | 'caller-will-launch-link';
224
+
225
+ /**
226
+ * Link type for external link flow (Android)
227
+ * Specifies the type of external link destination
228
+ * Available in Google Play Billing Library 8.2.0+
229
+ */
230
+ export type ExternalLinkTypeAndroid = 'unspecified' | 'link-to-digital-content-offer' | 'link-to-app-download';
231
+
232
+ /**
233
+ * External offer availability result (Android)
234
+ * @deprecated Use BillingProgramAvailabilityResultAndroid with isBillingProgramAvailableAsync instead
235
+ * Available in Google Play Billing Library 6.2.0+, deprecated in 8.2.0
236
+ */
237
+ export interface ExternalOfferAvailabilityResultAndroid {
238
+ /** Whether external offers are available for the user */
239
+ isAvailable: boolean;
240
+ }
241
+
242
+ /**
243
+ * External offer reporting details (Android)
244
+ * @deprecated Use BillingProgramReportingDetailsAndroid with createBillingProgramReportingDetailsAsync instead
245
+ * Available in Google Play Billing Library 6.2.0+, deprecated in 8.2.0
246
+ */
247
+ export interface ExternalOfferReportingDetailsAndroid {
248
+ /** External transaction token for reporting external offer transactions */
249
+ externalTransactionToken: string;
250
+ }
251
+
158
252
  /** Result of presenting an external purchase link (iOS 18.2+) */
159
253
  export interface ExternalPurchaseLinkResultIOS {
160
254
  /** Optional error message if the presentation failed */
@@ -180,11 +274,11 @@ export type IapEvent = 'purchase-updated' | 'purchase-error' | 'promoted-product
180
274
 
181
275
  export type IapPlatform = 'ios' | 'android';
182
276
 
277
+ export type IapStore = 'unknown' | 'apple' | 'google' | 'horizon';
278
+
183
279
  /** Unified purchase states from IAPKit verification response. */
184
280
  export type IapkitPurchaseState = 'entitled' | 'pending-acknowledgment' | 'pending' | 'canceled' | 'expired' | 'ready-to-consume' | 'consumed' | 'unknown' | 'inauthentic';
185
281
 
186
- export type IapkitStore = 'apple' | 'google';
187
-
188
282
  /** Connection initialization configuration */
189
283
  export interface InitConnectionConfig {
190
284
  /**
@@ -194,6 +288,33 @@ export interface InitConnectionConfig {
194
288
  alternativeBillingModeAndroid?: (AlternativeBillingModeAndroid | null);
195
289
  }
196
290
 
291
+ /**
292
+ * Parameters for launching an external link (Android)
293
+ * Used with launchExternalLink to initiate external offer or app install flows
294
+ * Available in Google Play Billing Library 8.2.0+
295
+ */
296
+ export interface LaunchExternalLinkParamsAndroid {
297
+ /** The billing program (EXTERNAL_CONTENT_LINK or EXTERNAL_OFFER) */
298
+ billingProgram: BillingProgramAndroid;
299
+ /** The external link launch mode */
300
+ launchMode: ExternalLinkLaunchModeAndroid;
301
+ /** The type of the external link */
302
+ linkType: ExternalLinkTypeAndroid;
303
+ /** The URI where the content will be accessed from */
304
+ linkUri: string;
305
+ }
306
+
307
+ /**
308
+ * Limited quantity information for one-time purchase offers (Android)
309
+ * Available in Google Play Billing Library 7.0+
310
+ */
311
+ export interface LimitedQuantityInfoAndroid {
312
+ /** Maximum quantity a user can purchase */
313
+ maximumQuantity: number;
314
+ /** Remaining quantity the user can still purchase */
315
+ remainingQuantity: number;
316
+ }
317
+
197
318
  export interface Mutation {
198
319
  /** Acknowledge a non-consumable purchase or subscription */
199
320
  acknowledgePurchaseAndroid: Promise<boolean>;
@@ -310,6 +431,23 @@ export type MutationVerifyPurchaseWithProviderArgs = VerifyPurchaseWithProviderP
310
431
 
311
432
  export type PaymentModeIOS = 'empty' | 'free-trial' | 'pay-as-you-go' | 'pay-up-front';
312
433
 
434
+ /**
435
+ * Pre-order details for one-time purchase products (Android)
436
+ * Available in Google Play Billing Library 8.1.0+
437
+ */
438
+ export interface PreorderDetailsAndroid {
439
+ /**
440
+ * Pre-order presale end time in milliseconds since epoch.
441
+ * This is when the presale period ends and the product will be released.
442
+ */
443
+ preorderPresaleEndTimeMillis: string;
444
+ /**
445
+ * Pre-order release time in milliseconds since epoch.
446
+ * This is when the product will be available to users who pre-ordered.
447
+ */
448
+ preorderReleaseTimeMillis: string;
449
+ }
450
+
313
451
  export interface PricingPhaseAndroid {
314
452
  billingCycleCount: number;
315
453
  billingPeriod: string;
@@ -333,7 +471,11 @@ export interface ProductAndroid extends ProductCommon {
333
471
  displayPrice: string;
334
472
  id: string;
335
473
  nameAndroid: string;
336
- oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail | null);
474
+ /**
475
+ * One-time purchase offer details including discounts (Android)
476
+ * Returns all eligible offers. Available in Google Play Billing Library 7.0+
477
+ */
478
+ oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
337
479
  platform: 'android';
338
480
  price?: (number | null);
339
481
  subscriptionOfferDetailsAndroid?: (ProductSubscriptionAndroidOfferDetails[] | null);
@@ -341,10 +483,41 @@ export interface ProductAndroid extends ProductCommon {
341
483
  type: 'in-app';
342
484
  }
343
485
 
486
+ /**
487
+ * One-time purchase offer details (Android)
488
+ * Available in Google Play Billing Library 7.0+
489
+ */
344
490
  export interface ProductAndroidOneTimePurchaseOfferDetail {
491
+ /**
492
+ * Discount display information
493
+ * Only available for discounted offers
494
+ */
495
+ discountDisplayInfo?: (DiscountDisplayInfoAndroid | null);
345
496
  formattedPrice: string;
497
+ /**
498
+ * Full (non-discounted) price in micro-units
499
+ * Only available for discounted offers
500
+ */
501
+ fullPriceMicros?: (string | null);
502
+ /** Limited quantity information */
503
+ limitedQuantityInfo?: (LimitedQuantityInfoAndroid | null);
504
+ /** Offer ID */
505
+ offerId?: (string | null);
506
+ /** List of offer tags */
507
+ offerTags: string[];
508
+ /** Offer token for use in BillingFlowParams when purchasing */
509
+ offerToken: string;
510
+ /**
511
+ * Pre-order details for products available for pre-order
512
+ * Available in Google Play Billing Library 8.1.0+
513
+ */
514
+ preorderDetailsAndroid?: (PreorderDetailsAndroid | null);
346
515
  priceAmountMicros: string;
347
516
  priceCurrencyCode: string;
517
+ /** Rental details for rental offers */
518
+ rentalDetailsAndroid?: (RentalDetailsAndroid | null);
519
+ /** Valid time window for the offer */
520
+ validTimeWindow?: (ValidTimeWindowAndroid | null);
348
521
  }
349
522
 
350
523
  export interface ProductCommon {
@@ -397,7 +570,11 @@ export interface ProductSubscriptionAndroid extends ProductCommon {
397
570
  displayPrice: string;
398
571
  id: string;
399
572
  nameAndroid: string;
400
- oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail | null);
573
+ /**
574
+ * One-time purchase offer details including discounts (Android)
575
+ * Returns all eligible offers. Available in Google Play Billing Library 7.0+
576
+ */
577
+ oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
401
578
  platform: 'android';
402
579
  price?: (number | null);
403
580
  subscriptionOfferDetailsAndroid: ProductSubscriptionAndroidOfferDetails[];
@@ -454,15 +631,26 @@ export interface PurchaseAndroid extends PurchaseCommon {
454
631
  ids?: (string[] | null);
455
632
  isAcknowledgedAndroid?: (boolean | null);
456
633
  isAutoRenewing: boolean;
634
+ /**
635
+ * Whether the subscription is suspended (Android)
636
+ * A suspended subscription means the user's payment method failed and they need to fix it.
637
+ * Users should be directed to the subscription center to resolve the issue.
638
+ * Do NOT grant entitlements for suspended subscriptions.
639
+ * Available in Google Play Billing Library 8.1.0+
640
+ */
641
+ isSuspendedAndroid?: (boolean | null);
457
642
  obfuscatedAccountIdAndroid?: (string | null);
458
643
  obfuscatedProfileIdAndroid?: (string | null);
459
644
  packageNameAndroid?: (string | null);
645
+ /** @deprecated Use store instead */
460
646
  platform: IapPlatform;
461
647
  productId: string;
462
648
  purchaseState: PurchaseState;
463
649
  purchaseToken?: (string | null);
464
650
  quantity: number;
465
651
  signatureAndroid?: (string | null);
652
+ /** Store where purchase was made */
653
+ store: IapStore;
466
654
  transactionDate: number;
467
655
  transactionId?: (string | null);
468
656
  }
@@ -478,12 +666,15 @@ export interface PurchaseCommon {
478
666
  id: string;
479
667
  ids?: (string[] | null);
480
668
  isAutoRenewing: boolean;
669
+ /** @deprecated Use store instead */
481
670
  platform: IapPlatform;
482
671
  productId: string;
483
672
  purchaseState: PurchaseState;
484
673
  /** Unified purchase token (iOS JWS, Android purchaseToken) */
485
674
  purchaseToken?: (string | null);
486
675
  quantity: number;
676
+ /** Store where purchase was made */
677
+ store: IapStore;
487
678
  transactionDate: number;
488
679
  }
489
680
 
@@ -510,6 +701,7 @@ export interface PurchaseIOS extends PurchaseCommon {
510
701
  originalTransactionDateIOS?: (number | null);
511
702
  originalTransactionIdentifierIOS?: (string | null);
512
703
  ownershipTypeIOS?: (string | null);
704
+ /** @deprecated Use store instead */
513
705
  platform: IapPlatform;
514
706
  productId: string;
515
707
  purchaseState: PurchaseState;
@@ -521,6 +713,8 @@ export interface PurchaseIOS extends PurchaseCommon {
521
713
  renewalInfoIOS?: (RenewalInfoIOS | null);
522
714
  revocationDateIOS?: (number | null);
523
715
  revocationReasonIOS?: (string | null);
716
+ /** Store where purchase was made */
717
+ store: IapStore;
524
718
  storefrontCountryCodeIOS?: (string | null);
525
719
  subscriptionGroupIdIOS?: (string | null);
526
720
  transactionDate: number;
@@ -669,6 +863,20 @@ export interface RenewalInfoIOS {
669
863
  willAutoRenew: boolean;
670
864
  }
671
865
 
866
+ /**
867
+ * Rental details for one-time purchase products that can be rented (Android)
868
+ * Available in Google Play Billing Library 7.0+
869
+ */
870
+ export interface RentalDetailsAndroid {
871
+ /**
872
+ * Rental expiration period in ISO 8601 format
873
+ * Time after rental period ends when user can still extend
874
+ */
875
+ rentalExpirationPeriod?: (string | null);
876
+ /** Rental period in ISO 8601 format (e.g., P7D for 7 days) */
877
+ rentalPeriod: string;
878
+ }
879
+
672
880
  export interface RequestPurchaseAndroidProps {
673
881
  /** Personalized offer flag */
674
882
  isOfferPersonalized?: (boolean | null);
@@ -709,10 +917,22 @@ export type RequestPurchaseProps =
709
917
  useAlternativeBilling?: boolean | null;
710
918
  };
711
919
 
920
+ /**
921
+ * Platform-specific purchase request parameters.
922
+ *
923
+ * Note: "Platforms" refers to the SDK/OS level (apple, google), not the store.
924
+ * - apple: Always targets App Store
925
+ * - google: Targets Play Store by default, or Horizon when built with horizon flavor
926
+ * (determined at build time, not runtime)
927
+ */
712
928
  export interface RequestPurchasePropsByPlatforms {
713
- /** Android-specific purchase parameters */
929
+ /** @deprecated Use google instead */
714
930
  android?: (RequestPurchaseAndroidProps | null);
715
- /** iOS-specific purchase parameters */
931
+ /** Apple-specific purchase parameters */
932
+ apple?: (RequestPurchaseIosProps | null);
933
+ /** Google-specific purchase parameters */
934
+ google?: (RequestPurchaseAndroidProps | null);
935
+ /** @deprecated Use apple instead */
716
936
  ios?: (RequestPurchaseIosProps | null);
717
937
  }
718
938
 
@@ -727,12 +947,20 @@ export interface RequestSubscriptionAndroidProps {
727
947
  obfuscatedProfileIdAndroid?: (string | null);
728
948
  /** Purchase token for upgrades/downgrades */
729
949
  purchaseTokenAndroid?: (string | null);
730
- /** Replacement mode for subscription changes */
950
+ /**
951
+ * Replacement mode for subscription changes
952
+ * @deprecated Use subscriptionProductReplacementParams instead for item-level replacement (8.1.0+)
953
+ */
731
954
  replacementModeAndroid?: (number | null);
732
955
  /** List of subscription SKUs */
733
956
  skus: string[];
734
957
  /** Subscription offers */
735
958
  subscriptionOffers?: (AndroidSubscriptionOfferInput[] | null);
959
+ /**
960
+ * Product-level replacement parameters (8.1.0+)
961
+ * Use this instead of replacementModeAndroid for item-level replacement
962
+ */
963
+ subscriptionProductReplacementParams?: (SubscriptionProductReplacementParamsAndroid | null);
736
964
  }
737
965
 
738
966
  export interface RequestSubscriptionIosProps {
@@ -743,10 +971,22 @@ export interface RequestSubscriptionIosProps {
743
971
  withOffer?: (DiscountOfferInputIOS | null);
744
972
  }
745
973
 
974
+ /**
975
+ * Platform-specific subscription request parameters.
976
+ *
977
+ * Note: "Platforms" refers to the SDK/OS level (apple, google), not the store.
978
+ * - apple: Always targets App Store
979
+ * - google: Targets Play Store by default, or Horizon when built with horizon flavor
980
+ * (determined at build time, not runtime)
981
+ */
746
982
  export interface RequestSubscriptionPropsByPlatforms {
747
- /** Android-specific subscription parameters */
983
+ /** @deprecated Use google instead */
748
984
  android?: (RequestSubscriptionAndroidProps | null);
749
- /** iOS-specific subscription parameters */
985
+ /** Apple-specific subscription parameters */
986
+ apple?: (RequestSubscriptionIosProps | null);
987
+ /** Google-specific subscription parameters */
988
+ google?: (RequestSubscriptionAndroidProps | null);
989
+ /** @deprecated Use apple instead */
750
990
  ios?: (RequestSubscriptionIosProps | null);
751
991
  }
752
992
 
@@ -760,12 +1000,18 @@ export interface RequestVerifyPurchaseWithIapkitGoogleProps {
760
1000
  purchaseToken: string;
761
1001
  }
762
1002
 
1003
+ /**
1004
+ * Platform-specific verification parameters for IAPKit.
1005
+ *
1006
+ * - apple: Verifies via App Store (JWS token)
1007
+ * - google: Verifies via Play Store (purchase token)
1008
+ */
763
1009
  export interface RequestVerifyPurchaseWithIapkitProps {
764
1010
  /** API key used for the Authorization header (Bearer {apiKey}). */
765
1011
  apiKey?: (string | null);
766
- /** Apple verification parameters. */
1012
+ /** Apple App Store verification parameters. */
767
1013
  apple?: (RequestVerifyPurchaseWithIapkitAppleProps | null);
768
- /** Google verification parameters. */
1014
+ /** Google Play Store verification parameters. */
769
1015
  google?: (RequestVerifyPurchaseWithIapkitGoogleProps | null);
770
1016
  }
771
1017
 
@@ -774,7 +1020,7 @@ export interface RequestVerifyPurchaseWithIapkitResult {
774
1020
  isValid: boolean;
775
1021
  /** The current state of the purchase. */
776
1022
  state: IapkitPurchaseState;
777
- store: IapkitStore;
1023
+ store: IapStore;
778
1024
  }
779
1025
 
780
1026
  export interface Subscription {
@@ -818,6 +1064,25 @@ export interface SubscriptionPeriodValueIOS {
818
1064
  value: number;
819
1065
  }
820
1066
 
1067
+ /**
1068
+ * Product-level subscription replacement parameters (Android)
1069
+ * Used with setSubscriptionProductReplacementParams in BillingFlowParams.ProductDetailsParams
1070
+ * Available in Google Play Billing Library 8.1.0+
1071
+ */
1072
+ export interface SubscriptionProductReplacementParamsAndroid {
1073
+ /** The old product ID that needs to be replaced */
1074
+ oldProductId: string;
1075
+ /** The replacement mode for this product change */
1076
+ replacementMode: SubscriptionReplacementModeAndroid;
1077
+ }
1078
+
1079
+ /**
1080
+ * Replacement mode for subscription changes (Android)
1081
+ * These modes determine how the subscription replacement affects billing.
1082
+ * Available in Google Play Billing Library 8.1.0+
1083
+ */
1084
+ export type SubscriptionReplacementModeAndroid = 'unknown-replacement-mode' | 'with-time-proration' | 'charge-prorated-price' | 'charge-full-price' | 'without-proration' | 'deferred' | 'keep-existing';
1085
+
821
1086
  export interface SubscriptionStatusIOS {
822
1087
  renewalInfo?: (RenewalInfoIOS | null);
823
1088
  state: string;
@@ -834,21 +1099,87 @@ export interface UserChoiceBillingDetails {
834
1099
  products: string[];
835
1100
  }
836
1101
 
837
- export interface VerifyPurchaseAndroidOptions {
1102
+ /**
1103
+ * Valid time window for when an offer is available (Android)
1104
+ * Available in Google Play Billing Library 7.0+
1105
+ */
1106
+ export interface ValidTimeWindowAndroid {
1107
+ /** End time in milliseconds since epoch */
1108
+ endTimeMillis: string;
1109
+ /** Start time in milliseconds since epoch */
1110
+ startTimeMillis: string;
1111
+ }
1112
+
1113
+ /**
1114
+ * Apple App Store verification parameters.
1115
+ * Used for server-side receipt validation via App Store Server API.
1116
+ */
1117
+ export interface VerifyPurchaseAppleOptions {
1118
+ /** Product SKU to validate */
1119
+ sku: string;
1120
+ }
1121
+
1122
+ /**
1123
+ * Google Play Store verification parameters.
1124
+ * Used for server-side receipt validation via Google Play Developer API.
1125
+ *
1126
+ * ⚠️ SECURITY: Contains sensitive tokens (accessToken, purchaseToken). Do not log or persist this data.
1127
+ */
1128
+ export interface VerifyPurchaseGoogleOptions {
1129
+ /**
1130
+ * Google OAuth2 access token for API authentication.
1131
+ * ⚠️ Sensitive: Do not log this value.
1132
+ */
838
1133
  accessToken: string;
1134
+ /** Whether this is a subscription purchase (affects API endpoint used) */
839
1135
  isSub?: (boolean | null);
1136
+ /** Android package name (e.g., com.example.app) */
840
1137
  packageName: string;
841
- productToken: string;
1138
+ /**
1139
+ * Purchase token from the purchase response.
1140
+ * ⚠️ Sensitive: Do not log this value.
1141
+ */
1142
+ purchaseToken: string;
1143
+ /** Product SKU to validate */
1144
+ sku: string;
842
1145
  }
843
1146
 
844
- export interface VerifyPurchaseProps {
845
- /** Android-specific validation options */
846
- androidOptions?: (VerifyPurchaseAndroidOptions | null);
847
- /** Product SKU to validate */
1147
+ /**
1148
+ * Meta Horizon (Quest) verification parameters.
1149
+ * Used for server-side entitlement verification via Meta's S2S API.
1150
+ * POST https://graph.oculus.com/$APP_ID/verify_entitlement
1151
+ *
1152
+ * ⚠️ SECURITY: Contains sensitive token (accessToken). Do not log or persist this data.
1153
+ */
1154
+ export interface VerifyPurchaseHorizonOptions {
1155
+ /**
1156
+ * Access token for Meta API authentication (OC|$APP_ID|$APP_SECRET or User Access Token).
1157
+ * ⚠️ Sensitive: Do not log this value.
1158
+ */
1159
+ accessToken: string;
1160
+ /** The SKU for the add-on item, defined in Meta Developer Dashboard */
848
1161
  sku: string;
1162
+ /** The user ID of the user whose purchase you want to verify */
1163
+ userId: string;
1164
+ }
1165
+
1166
+ /**
1167
+ * Platform-specific purchase verification parameters.
1168
+ *
1169
+ * - apple: Verifies via App Store Server API
1170
+ * - google: Verifies via Google Play Developer API
1171
+ * - horizon: Verifies via Meta's S2S API (verify_entitlement endpoint)
1172
+ */
1173
+ export interface VerifyPurchaseProps {
1174
+ /** Apple App Store verification parameters. */
1175
+ apple?: (VerifyPurchaseAppleOptions | null);
1176
+ /** Google Play Store verification parameters. */
1177
+ google?: (VerifyPurchaseGoogleOptions | null);
1178
+ /** Meta Horizon (Quest) verification parameters. */
1179
+ horizon?: (VerifyPurchaseHorizonOptions | null);
849
1180
  }
850
1181
 
851
- export type VerifyPurchaseResult = VerifyPurchaseResultAndroid | VerifyPurchaseResultIOS;
1182
+ export type VerifyPurchaseResult = VerifyPurchaseResultAndroid | VerifyPurchaseResultHorizon | VerifyPurchaseResultIOS;
852
1183
 
853
1184
  export interface VerifyPurchaseResultAndroid {
854
1185
  autoRenewing: boolean;
@@ -871,6 +1202,17 @@ export interface VerifyPurchaseResultAndroid {
871
1202
  testTransaction: boolean;
872
1203
  }
873
1204
 
1205
+ /**
1206
+ * Result from Meta Horizon verify_entitlement API.
1207
+ * Returns verification status and grant time for the entitlement.
1208
+ */
1209
+ export interface VerifyPurchaseResultHorizon {
1210
+ /** Unix timestamp (seconds) when the entitlement was granted. */
1211
+ grantTime?: (number | null);
1212
+ /** Whether the entitlement verification succeeded. */
1213
+ success: boolean;
1214
+ }
1215
+
874
1216
  export interface VerifyPurchaseResultIOS {
875
1217
  /** Whether the receipt is valid */
876
1218
  isValid: boolean;
@@ -882,14 +1224,21 @@ export interface VerifyPurchaseResultIOS {
882
1224
  receiptData: string;
883
1225
  }
884
1226
 
1227
+ export interface VerifyPurchaseWithProviderError {
1228
+ code?: (string | null);
1229
+ message: string;
1230
+ }
1231
+
885
1232
  export interface VerifyPurchaseWithProviderProps {
886
1233
  iapkit?: (RequestVerifyPurchaseWithIapkitProps | null);
887
1234
  provider: PurchaseVerificationProvider;
888
1235
  }
889
1236
 
890
1237
  export interface VerifyPurchaseWithProviderResult {
891
- /** IAPKit verification results (can include Apple and Google entries) */
892
- iapkit: RequestVerifyPurchaseWithIapkitResult[];
1238
+ /** Error details if verification failed */
1239
+ errors?: (VerifyPurchaseWithProviderError[] | null);
1240
+ /** IAPKit verification result */
1241
+ iapkit?: (RequestVerifyPurchaseWithIapkitResult | null);
893
1242
  provider: PurchaseVerificationProvider;
894
1243
  }
895
1244
 
package/src/useIAP.ts CHANGED
@@ -203,7 +203,9 @@ export function useIAP(options?: UseIAPOptions): UseIap {
203
203
  purchaseState: purchase.purchaseState,
204
204
  purchaseToken: purchase.purchaseToken ?? null,
205
205
  quantity: purchase.quantity,
206
+ store: purchase.store,
206
207
  transactionDate: purchase.transactionDate,
208
+ transactionId: purchase.transactionId,
207
209
  }),
208
210
  [],
209
211
  );