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/build/types.d.ts CHANGED
@@ -56,12 +56,67 @@ export interface AppTransaction {
56
56
  preorderDate?: (number | null);
57
57
  signedDate: number;
58
58
  }
59
+ /**
60
+ * Billing program types for external content links and external offers (Android)
61
+ * Available in Google Play Billing Library 8.2.0+
62
+ */
63
+ export type BillingProgramAndroid = 'unspecified' | 'external-content-link' | 'external-offer';
64
+ /**
65
+ * Result of checking billing program availability (Android)
66
+ * Available in Google Play Billing Library 8.2.0+
67
+ */
68
+ export interface BillingProgramAvailabilityResultAndroid {
69
+ /** The billing program that was checked */
70
+ billingProgram: BillingProgramAndroid;
71
+ /** Whether the billing program is available for the user */
72
+ isAvailable: boolean;
73
+ }
74
+ /**
75
+ * Reporting details for transactions made outside of Google Play Billing (Android)
76
+ * Contains the external transaction token needed for reporting
77
+ * Available in Google Play Billing Library 8.2.0+
78
+ */
79
+ export interface BillingProgramReportingDetailsAndroid {
80
+ /** The billing program that the reporting details are associated with */
81
+ billingProgram: BillingProgramAndroid;
82
+ /**
83
+ * External transaction token used to report transactions made outside of Google Play Billing.
84
+ * This token must be used when reporting the external transaction to Google.
85
+ */
86
+ externalTransactionToken: string;
87
+ }
59
88
  export interface DeepLinkOptions {
60
89
  /** Android package name to target (required on Android) */
61
90
  packageNameAndroid?: (string | null);
62
91
  /** Android SKU to open (required on Android) */
63
92
  skuAndroid?: (string | null);
64
93
  }
94
+ /**
95
+ * Discount amount details for one-time purchase offers (Android)
96
+ * Available in Google Play Billing Library 7.0+
97
+ */
98
+ export interface DiscountAmountAndroid {
99
+ /** Discount amount in micro-units (1,000,000 = 1 unit of currency) */
100
+ discountAmountMicros: string;
101
+ /** Formatted discount amount with currency sign (e.g., "$4.99") */
102
+ formattedDiscountAmount: string;
103
+ }
104
+ /**
105
+ * Discount display information for one-time purchase offers (Android)
106
+ * Available in Google Play Billing Library 7.0+
107
+ */
108
+ export interface DiscountDisplayInfoAndroid {
109
+ /**
110
+ * Absolute discount amount details
111
+ * Only returned for fixed amount discounts
112
+ */
113
+ discountAmount?: (DiscountAmountAndroid | null);
114
+ /**
115
+ * Percentage discount (e.g., 33 for 33% off)
116
+ * Only returned for percentage-based discounts
117
+ */
118
+ percentageDiscount?: (number | null);
119
+ }
65
120
  export interface DiscountIOS {
66
121
  identifier: string;
67
122
  localizedPrice?: (string | null);
@@ -140,6 +195,36 @@ export declare enum ErrorCode {
140
195
  UserCancelled = "user-cancelled",
141
196
  UserError = "user-error"
142
197
  }
198
+ /**
199
+ * Launch mode for external link flow (Android)
200
+ * Determines how the external URL is launched
201
+ * Available in Google Play Billing Library 8.2.0+
202
+ */
203
+ export type ExternalLinkLaunchModeAndroid = 'unspecified' | 'launch-in-external-browser-or-app' | 'caller-will-launch-link';
204
+ /**
205
+ * Link type for external link flow (Android)
206
+ * Specifies the type of external link destination
207
+ * Available in Google Play Billing Library 8.2.0+
208
+ */
209
+ export type ExternalLinkTypeAndroid = 'unspecified' | 'link-to-digital-content-offer' | 'link-to-app-download';
210
+ /**
211
+ * External offer availability result (Android)
212
+ * @deprecated Use BillingProgramAvailabilityResultAndroid with isBillingProgramAvailableAsync instead
213
+ * Available in Google Play Billing Library 6.2.0+, deprecated in 8.2.0
214
+ */
215
+ export interface ExternalOfferAvailabilityResultAndroid {
216
+ /** Whether external offers are available for the user */
217
+ isAvailable: boolean;
218
+ }
219
+ /**
220
+ * External offer reporting details (Android)
221
+ * @deprecated Use BillingProgramReportingDetailsAndroid with createBillingProgramReportingDetailsAsync instead
222
+ * Available in Google Play Billing Library 6.2.0+, deprecated in 8.2.0
223
+ */
224
+ export interface ExternalOfferReportingDetailsAndroid {
225
+ /** External transaction token for reporting external offer transactions */
226
+ externalTransactionToken: string;
227
+ }
143
228
  /** Result of presenting an external purchase link (iOS 18.2+) */
144
229
  export interface ExternalPurchaseLinkResultIOS {
145
230
  /** Optional error message if the presentation failed */
@@ -159,9 +244,9 @@ export interface ExternalPurchaseNoticeResultIOS {
159
244
  export type FetchProductsResult = ProductOrSubscription[] | Product[] | ProductSubscription[] | null;
160
245
  export type IapEvent = 'purchase-updated' | 'purchase-error' | 'promoted-product-ios' | 'user-choice-billing-android';
161
246
  export type IapPlatform = 'ios' | 'android';
247
+ export type IapStore = 'unknown' | 'apple' | 'google' | 'horizon';
162
248
  /** Unified purchase states from IAPKit verification response. */
163
249
  export type IapkitPurchaseState = 'entitled' | 'pending-acknowledgment' | 'pending' | 'canceled' | 'expired' | 'ready-to-consume' | 'consumed' | 'unknown' | 'inauthentic';
164
- export type IapkitStore = 'apple' | 'google';
165
250
  /** Connection initialization configuration */
166
251
  export interface InitConnectionConfig {
167
252
  /**
@@ -170,6 +255,31 @@ export interface InitConnectionConfig {
170
255
  */
171
256
  alternativeBillingModeAndroid?: (AlternativeBillingModeAndroid | null);
172
257
  }
258
+ /**
259
+ * Parameters for launching an external link (Android)
260
+ * Used with launchExternalLink to initiate external offer or app install flows
261
+ * Available in Google Play Billing Library 8.2.0+
262
+ */
263
+ export interface LaunchExternalLinkParamsAndroid {
264
+ /** The billing program (EXTERNAL_CONTENT_LINK or EXTERNAL_OFFER) */
265
+ billingProgram: BillingProgramAndroid;
266
+ /** The external link launch mode */
267
+ launchMode: ExternalLinkLaunchModeAndroid;
268
+ /** The type of the external link */
269
+ linkType: ExternalLinkTypeAndroid;
270
+ /** The URI where the content will be accessed from */
271
+ linkUri: string;
272
+ }
273
+ /**
274
+ * Limited quantity information for one-time purchase offers (Android)
275
+ * Available in Google Play Billing Library 7.0+
276
+ */
277
+ export interface LimitedQuantityInfoAndroid {
278
+ /** Maximum quantity a user can purchase */
279
+ maximumQuantity: number;
280
+ /** Remaining quantity the user can still purchase */
281
+ remainingQuantity: number;
282
+ }
173
283
  export interface Mutation {
174
284
  /** Acknowledge a non-consumable purchase or subscription */
175
285
  acknowledgePurchaseAndroid: Promise<boolean>;
@@ -267,6 +377,22 @@ export type MutationValidateReceiptArgs = VerifyPurchaseProps;
267
377
  export type MutationVerifyPurchaseArgs = VerifyPurchaseProps;
268
378
  export type MutationVerifyPurchaseWithProviderArgs = VerifyPurchaseWithProviderProps;
269
379
  export type PaymentModeIOS = 'empty' | 'free-trial' | 'pay-as-you-go' | 'pay-up-front';
380
+ /**
381
+ * Pre-order details for one-time purchase products (Android)
382
+ * Available in Google Play Billing Library 8.1.0+
383
+ */
384
+ export interface PreorderDetailsAndroid {
385
+ /**
386
+ * Pre-order presale end time in milliseconds since epoch.
387
+ * This is when the presale period ends and the product will be released.
388
+ */
389
+ preorderPresaleEndTimeMillis: string;
390
+ /**
391
+ * Pre-order release time in milliseconds since epoch.
392
+ * This is when the product will be available to users who pre-ordered.
393
+ */
394
+ preorderReleaseTimeMillis: string;
395
+ }
270
396
  export interface PricingPhaseAndroid {
271
397
  billingCycleCount: number;
272
398
  billingPeriod: string;
@@ -287,17 +413,52 @@ export interface ProductAndroid extends ProductCommon {
287
413
  displayPrice: string;
288
414
  id: string;
289
415
  nameAndroid: string;
290
- oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail | null);
416
+ /**
417
+ * One-time purchase offer details including discounts (Android)
418
+ * Returns all eligible offers. Available in Google Play Billing Library 7.0+
419
+ */
420
+ oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
291
421
  platform: 'android';
292
422
  price?: (number | null);
293
423
  subscriptionOfferDetailsAndroid?: (ProductSubscriptionAndroidOfferDetails[] | null);
294
424
  title: string;
295
425
  type: 'in-app';
296
426
  }
427
+ /**
428
+ * One-time purchase offer details (Android)
429
+ * Available in Google Play Billing Library 7.0+
430
+ */
297
431
  export interface ProductAndroidOneTimePurchaseOfferDetail {
432
+ /**
433
+ * Discount display information
434
+ * Only available for discounted offers
435
+ */
436
+ discountDisplayInfo?: (DiscountDisplayInfoAndroid | null);
298
437
  formattedPrice: string;
438
+ /**
439
+ * Full (non-discounted) price in micro-units
440
+ * Only available for discounted offers
441
+ */
442
+ fullPriceMicros?: (string | null);
443
+ /** Limited quantity information */
444
+ limitedQuantityInfo?: (LimitedQuantityInfoAndroid | null);
445
+ /** Offer ID */
446
+ offerId?: (string | null);
447
+ /** List of offer tags */
448
+ offerTags: string[];
449
+ /** Offer token for use in BillingFlowParams when purchasing */
450
+ offerToken: string;
451
+ /**
452
+ * Pre-order details for products available for pre-order
453
+ * Available in Google Play Billing Library 8.1.0+
454
+ */
455
+ preorderDetailsAndroid?: (PreorderDetailsAndroid | null);
299
456
  priceAmountMicros: string;
300
457
  priceCurrencyCode: string;
458
+ /** Rental details for rental offers */
459
+ rentalDetailsAndroid?: (RentalDetailsAndroid | null);
460
+ /** Valid time window for the offer */
461
+ validTimeWindow?: (ValidTimeWindowAndroid | null);
301
462
  }
302
463
  export interface ProductCommon {
303
464
  currency: string;
@@ -343,7 +504,11 @@ export interface ProductSubscriptionAndroid extends ProductCommon {
343
504
  displayPrice: string;
344
505
  id: string;
345
506
  nameAndroid: string;
346
- oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail | null);
507
+ /**
508
+ * One-time purchase offer details including discounts (Android)
509
+ * Returns all eligible offers. Available in Google Play Billing Library 7.0+
510
+ */
511
+ oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
347
512
  platform: 'android';
348
513
  price?: (number | null);
349
514
  subscriptionOfferDetailsAndroid: ProductSubscriptionAndroidOfferDetails[];
@@ -394,15 +559,26 @@ export interface PurchaseAndroid extends PurchaseCommon {
394
559
  ids?: (string[] | null);
395
560
  isAcknowledgedAndroid?: (boolean | null);
396
561
  isAutoRenewing: boolean;
562
+ /**
563
+ * Whether the subscription is suspended (Android)
564
+ * A suspended subscription means the user's payment method failed and they need to fix it.
565
+ * Users should be directed to the subscription center to resolve the issue.
566
+ * Do NOT grant entitlements for suspended subscriptions.
567
+ * Available in Google Play Billing Library 8.1.0+
568
+ */
569
+ isSuspendedAndroid?: (boolean | null);
397
570
  obfuscatedAccountIdAndroid?: (string | null);
398
571
  obfuscatedProfileIdAndroid?: (string | null);
399
572
  packageNameAndroid?: (string | null);
573
+ /** @deprecated Use store instead */
400
574
  platform: IapPlatform;
401
575
  productId: string;
402
576
  purchaseState: PurchaseState;
403
577
  purchaseToken?: (string | null);
404
578
  quantity: number;
405
579
  signatureAndroid?: (string | null);
580
+ /** Store where purchase was made */
581
+ store: IapStore;
406
582
  transactionDate: number;
407
583
  transactionId?: (string | null);
408
584
  }
@@ -417,12 +593,15 @@ export interface PurchaseCommon {
417
593
  id: string;
418
594
  ids?: (string[] | null);
419
595
  isAutoRenewing: boolean;
596
+ /** @deprecated Use store instead */
420
597
  platform: IapPlatform;
421
598
  productId: string;
422
599
  purchaseState: PurchaseState;
423
600
  /** Unified purchase token (iOS JWS, Android purchaseToken) */
424
601
  purchaseToken?: (string | null);
425
602
  quantity: number;
603
+ /** Store where purchase was made */
604
+ store: IapStore;
426
605
  transactionDate: number;
427
606
  }
428
607
  export interface PurchaseError {
@@ -447,6 +626,7 @@ export interface PurchaseIOS extends PurchaseCommon {
447
626
  originalTransactionDateIOS?: (number | null);
448
627
  originalTransactionIdentifierIOS?: (string | null);
449
628
  ownershipTypeIOS?: (string | null);
629
+ /** @deprecated Use store instead */
450
630
  platform: IapPlatform;
451
631
  productId: string;
452
632
  purchaseState: PurchaseState;
@@ -458,6 +638,8 @@ export interface PurchaseIOS extends PurchaseCommon {
458
638
  renewalInfoIOS?: (RenewalInfoIOS | null);
459
639
  revocationDateIOS?: (number | null);
460
640
  revocationReasonIOS?: (string | null);
641
+ /** Store where purchase was made */
642
+ store: IapStore;
461
643
  storefrontCountryCodeIOS?: (string | null);
462
644
  subscriptionGroupIdIOS?: (string | null);
463
645
  transactionDate: number;
@@ -584,6 +766,19 @@ export interface RenewalInfoIOS {
584
766
  renewalOfferType?: (string | null);
585
767
  willAutoRenew: boolean;
586
768
  }
769
+ /**
770
+ * Rental details for one-time purchase products that can be rented (Android)
771
+ * Available in Google Play Billing Library 7.0+
772
+ */
773
+ export interface RentalDetailsAndroid {
774
+ /**
775
+ * Rental expiration period in ISO 8601 format
776
+ * Time after rental period ends when user can still extend
777
+ */
778
+ rentalExpirationPeriod?: (string | null);
779
+ /** Rental period in ISO 8601 format (e.g., P7D for 7 days) */
780
+ rentalPeriod: string;
781
+ }
587
782
  export interface RequestPurchaseAndroidProps {
588
783
  /** Personalized offer flag */
589
784
  isOfferPersonalized?: (boolean | null);
@@ -619,10 +814,22 @@ export type RequestPurchaseProps = {
619
814
  /** Use alternative billing (Google Play alternative billing, Apple external purchase link) */
620
815
  useAlternativeBilling?: boolean | null;
621
816
  };
817
+ /**
818
+ * Platform-specific purchase request parameters.
819
+ *
820
+ * Note: "Platforms" refers to the SDK/OS level (apple, google), not the store.
821
+ * - apple: Always targets App Store
822
+ * - google: Targets Play Store by default, or Horizon when built with horizon flavor
823
+ * (determined at build time, not runtime)
824
+ */
622
825
  export interface RequestPurchasePropsByPlatforms {
623
- /** Android-specific purchase parameters */
826
+ /** @deprecated Use google instead */
624
827
  android?: (RequestPurchaseAndroidProps | null);
625
- /** iOS-specific purchase parameters */
828
+ /** Apple-specific purchase parameters */
829
+ apple?: (RequestPurchaseIosProps | null);
830
+ /** Google-specific purchase parameters */
831
+ google?: (RequestPurchaseAndroidProps | null);
832
+ /** @deprecated Use apple instead */
626
833
  ios?: (RequestPurchaseIosProps | null);
627
834
  }
628
835
  export type RequestPurchaseResult = Purchase | Purchase[] | null;
@@ -635,12 +842,20 @@ export interface RequestSubscriptionAndroidProps {
635
842
  obfuscatedProfileIdAndroid?: (string | null);
636
843
  /** Purchase token for upgrades/downgrades */
637
844
  purchaseTokenAndroid?: (string | null);
638
- /** Replacement mode for subscription changes */
845
+ /**
846
+ * Replacement mode for subscription changes
847
+ * @deprecated Use subscriptionProductReplacementParams instead for item-level replacement (8.1.0+)
848
+ */
639
849
  replacementModeAndroid?: (number | null);
640
850
  /** List of subscription SKUs */
641
851
  skus: string[];
642
852
  /** Subscription offers */
643
853
  subscriptionOffers?: (AndroidSubscriptionOfferInput[] | null);
854
+ /**
855
+ * Product-level replacement parameters (8.1.0+)
856
+ * Use this instead of replacementModeAndroid for item-level replacement
857
+ */
858
+ subscriptionProductReplacementParams?: (SubscriptionProductReplacementParamsAndroid | null);
644
859
  }
645
860
  export interface RequestSubscriptionIosProps {
646
861
  andDangerouslyFinishTransactionAutomatically?: (boolean | null);
@@ -649,10 +864,22 @@ export interface RequestSubscriptionIosProps {
649
864
  sku: string;
650
865
  withOffer?: (DiscountOfferInputIOS | null);
651
866
  }
867
+ /**
868
+ * Platform-specific subscription request parameters.
869
+ *
870
+ * Note: "Platforms" refers to the SDK/OS level (apple, google), not the store.
871
+ * - apple: Always targets App Store
872
+ * - google: Targets Play Store by default, or Horizon when built with horizon flavor
873
+ * (determined at build time, not runtime)
874
+ */
652
875
  export interface RequestSubscriptionPropsByPlatforms {
653
- /** Android-specific subscription parameters */
876
+ /** @deprecated Use google instead */
654
877
  android?: (RequestSubscriptionAndroidProps | null);
655
- /** iOS-specific subscription parameters */
878
+ /** Apple-specific subscription parameters */
879
+ apple?: (RequestSubscriptionIosProps | null);
880
+ /** Google-specific subscription parameters */
881
+ google?: (RequestSubscriptionAndroidProps | null);
882
+ /** @deprecated Use apple instead */
656
883
  ios?: (RequestSubscriptionIosProps | null);
657
884
  }
658
885
  export interface RequestVerifyPurchaseWithIapkitAppleProps {
@@ -663,12 +890,18 @@ export interface RequestVerifyPurchaseWithIapkitGoogleProps {
663
890
  /** The token provided to the user's device when the product or subscription was purchased. */
664
891
  purchaseToken: string;
665
892
  }
893
+ /**
894
+ * Platform-specific verification parameters for IAPKit.
895
+ *
896
+ * - apple: Verifies via App Store (JWS token)
897
+ * - google: Verifies via Play Store (purchase token)
898
+ */
666
899
  export interface RequestVerifyPurchaseWithIapkitProps {
667
900
  /** API key used for the Authorization header (Bearer {apiKey}). */
668
901
  apiKey?: (string | null);
669
- /** Apple verification parameters. */
902
+ /** Apple App Store verification parameters. */
670
903
  apple?: (RequestVerifyPurchaseWithIapkitAppleProps | null);
671
- /** Google verification parameters. */
904
+ /** Google Play Store verification parameters. */
672
905
  google?: (RequestVerifyPurchaseWithIapkitGoogleProps | null);
673
906
  }
674
907
  export interface RequestVerifyPurchaseWithIapkitResult {
@@ -676,7 +909,7 @@ export interface RequestVerifyPurchaseWithIapkitResult {
676
909
  isValid: boolean;
677
910
  /** The current state of the purchase. */
678
911
  state: IapkitPurchaseState;
679
- store: IapkitStore;
912
+ store: IapStore;
680
913
  }
681
914
  export interface Subscription {
682
915
  /** Fires when the App Store surfaces a promoted product (iOS only) */
@@ -712,6 +945,23 @@ export interface SubscriptionPeriodValueIOS {
712
945
  unit: SubscriptionPeriodIOS;
713
946
  value: number;
714
947
  }
948
+ /**
949
+ * Product-level subscription replacement parameters (Android)
950
+ * Used with setSubscriptionProductReplacementParams in BillingFlowParams.ProductDetailsParams
951
+ * Available in Google Play Billing Library 8.1.0+
952
+ */
953
+ export interface SubscriptionProductReplacementParamsAndroid {
954
+ /** The old product ID that needs to be replaced */
955
+ oldProductId: string;
956
+ /** The replacement mode for this product change */
957
+ replacementMode: SubscriptionReplacementModeAndroid;
958
+ }
959
+ /**
960
+ * Replacement mode for subscription changes (Android)
961
+ * These modes determine how the subscription replacement affects billing.
962
+ * Available in Google Play Billing Library 8.1.0+
963
+ */
964
+ export type SubscriptionReplacementModeAndroid = 'unknown-replacement-mode' | 'with-time-proration' | 'charge-prorated-price' | 'charge-full-price' | 'without-proration' | 'deferred' | 'keep-existing';
715
965
  export interface SubscriptionStatusIOS {
716
966
  renewalInfo?: (RenewalInfoIOS | null);
717
967
  state: string;
@@ -726,19 +976,82 @@ export interface UserChoiceBillingDetails {
726
976
  /** List of product IDs selected by the user */
727
977
  products: string[];
728
978
  }
729
- export interface VerifyPurchaseAndroidOptions {
979
+ /**
980
+ * Valid time window for when an offer is available (Android)
981
+ * Available in Google Play Billing Library 7.0+
982
+ */
983
+ export interface ValidTimeWindowAndroid {
984
+ /** End time in milliseconds since epoch */
985
+ endTimeMillis: string;
986
+ /** Start time in milliseconds since epoch */
987
+ startTimeMillis: string;
988
+ }
989
+ /**
990
+ * Apple App Store verification parameters.
991
+ * Used for server-side receipt validation via App Store Server API.
992
+ */
993
+ export interface VerifyPurchaseAppleOptions {
994
+ /** Product SKU to validate */
995
+ sku: string;
996
+ }
997
+ /**
998
+ * Google Play Store verification parameters.
999
+ * Used for server-side receipt validation via Google Play Developer API.
1000
+ *
1001
+ * ⚠️ SECURITY: Contains sensitive tokens (accessToken, purchaseToken). Do not log or persist this data.
1002
+ */
1003
+ export interface VerifyPurchaseGoogleOptions {
1004
+ /**
1005
+ * Google OAuth2 access token for API authentication.
1006
+ * ⚠️ Sensitive: Do not log this value.
1007
+ */
730
1008
  accessToken: string;
1009
+ /** Whether this is a subscription purchase (affects API endpoint used) */
731
1010
  isSub?: (boolean | null);
1011
+ /** Android package name (e.g., com.example.app) */
732
1012
  packageName: string;
733
- productToken: string;
734
- }
735
- export interface VerifyPurchaseProps {
736
- /** Android-specific validation options */
737
- androidOptions?: (VerifyPurchaseAndroidOptions | null);
1013
+ /**
1014
+ * Purchase token from the purchase response.
1015
+ * ⚠️ Sensitive: Do not log this value.
1016
+ */
1017
+ purchaseToken: string;
738
1018
  /** Product SKU to validate */
739
1019
  sku: string;
740
1020
  }
741
- export type VerifyPurchaseResult = VerifyPurchaseResultAndroid | VerifyPurchaseResultIOS;
1021
+ /**
1022
+ * Meta Horizon (Quest) verification parameters.
1023
+ * Used for server-side entitlement verification via Meta's S2S API.
1024
+ * POST https://graph.oculus.com/$APP_ID/verify_entitlement
1025
+ *
1026
+ * ⚠️ SECURITY: Contains sensitive token (accessToken). Do not log or persist this data.
1027
+ */
1028
+ export interface VerifyPurchaseHorizonOptions {
1029
+ /**
1030
+ * Access token for Meta API authentication (OC|$APP_ID|$APP_SECRET or User Access Token).
1031
+ * ⚠️ Sensitive: Do not log this value.
1032
+ */
1033
+ accessToken: string;
1034
+ /** The SKU for the add-on item, defined in Meta Developer Dashboard */
1035
+ sku: string;
1036
+ /** The user ID of the user whose purchase you want to verify */
1037
+ userId: string;
1038
+ }
1039
+ /**
1040
+ * Platform-specific purchase verification parameters.
1041
+ *
1042
+ * - apple: Verifies via App Store Server API
1043
+ * - google: Verifies via Google Play Developer API
1044
+ * - horizon: Verifies via Meta's S2S API (verify_entitlement endpoint)
1045
+ */
1046
+ export interface VerifyPurchaseProps {
1047
+ /** Apple App Store verification parameters. */
1048
+ apple?: (VerifyPurchaseAppleOptions | null);
1049
+ /** Google Play Store verification parameters. */
1050
+ google?: (VerifyPurchaseGoogleOptions | null);
1051
+ /** Meta Horizon (Quest) verification parameters. */
1052
+ horizon?: (VerifyPurchaseHorizonOptions | null);
1053
+ }
1054
+ export type VerifyPurchaseResult = VerifyPurchaseResultAndroid | VerifyPurchaseResultHorizon | VerifyPurchaseResultIOS;
742
1055
  export interface VerifyPurchaseResultAndroid {
743
1056
  autoRenewing: boolean;
744
1057
  betaProduct: boolean;
@@ -759,6 +1072,16 @@ export interface VerifyPurchaseResultAndroid {
759
1072
  termSku: string;
760
1073
  testTransaction: boolean;
761
1074
  }
1075
+ /**
1076
+ * Result from Meta Horizon verify_entitlement API.
1077
+ * Returns verification status and grant time for the entitlement.
1078
+ */
1079
+ export interface VerifyPurchaseResultHorizon {
1080
+ /** Unix timestamp (seconds) when the entitlement was granted. */
1081
+ grantTime?: (number | null);
1082
+ /** Whether the entitlement verification succeeded. */
1083
+ success: boolean;
1084
+ }
762
1085
  export interface VerifyPurchaseResultIOS {
763
1086
  /** Whether the receipt is valid */
764
1087
  isValid: boolean;
@@ -769,13 +1092,19 @@ export interface VerifyPurchaseResultIOS {
769
1092
  /** Receipt data string */
770
1093
  receiptData: string;
771
1094
  }
1095
+ export interface VerifyPurchaseWithProviderError {
1096
+ code?: (string | null);
1097
+ message: string;
1098
+ }
772
1099
  export interface VerifyPurchaseWithProviderProps {
773
1100
  iapkit?: (RequestVerifyPurchaseWithIapkitProps | null);
774
1101
  provider: PurchaseVerificationProvider;
775
1102
  }
776
1103
  export interface VerifyPurchaseWithProviderResult {
777
- /** IAPKit verification results (can include Apple and Google entries) */
778
- iapkit: RequestVerifyPurchaseWithIapkitResult[];
1104
+ /** Error details if verification failed */
1105
+ errors?: (VerifyPurchaseWithProviderError[] | null);
1106
+ /** IAPKit verification result */
1107
+ iapkit?: (RequestVerifyPurchaseWithIapkitResult | null);
779
1108
  provider: PurchaseVerificationProvider;
780
1109
  }
781
1110
  export type VoidResult = void;