expo-iap 3.2.0 → 3.2.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.
Files changed (40) hide show
  1. package/CLAUDE.md +10 -4
  2. package/README.md +2 -23
  3. package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +141 -13
  4. package/build/index.d.ts.map +1 -1
  5. package/build/index.js +40 -12
  6. package/build/index.js.map +1 -1
  7. package/build/modules/android.d.ts +53 -1
  8. package/build/modules/android.d.ts.map +1 -1
  9. package/build/modules/android.js +61 -0
  10. package/build/modules/android.js.map +1 -1
  11. package/build/modules/ios.d.ts.map +1 -1
  12. package/build/modules/ios.js +4 -2
  13. package/build/modules/ios.js.map +1 -1
  14. package/build/types.d.ts +321 -24
  15. package/build/types.d.ts.map +1 -1
  16. package/build/types.js.map +1 -1
  17. package/coverage/clover.xml +115 -100
  18. package/coverage/coverage-final.json +3 -3
  19. package/coverage/lcov-report/index.html +26 -26
  20. package/coverage/lcov-report/src/index.html +19 -19
  21. package/coverage/lcov-report/src/index.ts.html +117 -24
  22. package/coverage/lcov-report/src/modules/android.ts.html +233 -8
  23. package/coverage/lcov-report/src/modules/index.html +15 -15
  24. package/coverage/lcov-report/src/modules/ios.ts.html +13 -7
  25. package/coverage/lcov-report/src/utils/debug.ts.html +1 -1
  26. package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
  27. package/coverage/lcov-report/src/utils/index.html +1 -1
  28. package/coverage/lcov.info +274 -244
  29. package/ios/ExpoIap.podspec +7 -5
  30. package/ios/ExpoIapHelper.swift +1 -1
  31. package/ios/ExpoIapModule.swift +1 -1
  32. package/openiap-versions.json +3 -3
  33. package/package.json +1 -1
  34. package/plugin/build/withIAP.d.ts +8 -5
  35. package/plugin/build/withIAP.js +12 -3
  36. package/plugin/src/withIAP.ts +18 -9
  37. package/src/index.ts +43 -12
  38. package/src/modules/android.ts +75 -0
  39. package/src/modules/ios.ts +4 -2
  40. package/src/types.ts +340 -24
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 */
@@ -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,13 +631,18 @@ 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);
460
- /**
461
- * @deprecated Use store instead
462
- * @deprecated Use store instead
463
- */
645
+ /** @deprecated Use store instead */
464
646
  platform: IapPlatform;
465
647
  productId: string;
466
648
  purchaseState: PurchaseState;
@@ -484,10 +666,7 @@ export interface PurchaseCommon {
484
666
  id: string;
485
667
  ids?: (string[] | null);
486
668
  isAutoRenewing: boolean;
487
- /**
488
- * @deprecated Use store instead
489
- * @deprecated Use store instead
490
- */
669
+ /** @deprecated Use store instead */
491
670
  platform: IapPlatform;
492
671
  productId: string;
493
672
  purchaseState: PurchaseState;
@@ -522,10 +701,7 @@ export interface PurchaseIOS extends PurchaseCommon {
522
701
  originalTransactionDateIOS?: (number | null);
523
702
  originalTransactionIdentifierIOS?: (string | null);
524
703
  ownershipTypeIOS?: (string | null);
525
- /**
526
- * @deprecated Use store instead
527
- * @deprecated Use store instead
528
- */
704
+ /** @deprecated Use store instead */
529
705
  platform: IapPlatform;
530
706
  productId: string;
531
707
  purchaseState: PurchaseState;
@@ -687,6 +863,20 @@ export interface RenewalInfoIOS {
687
863
  willAutoRenew: boolean;
688
864
  }
689
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
+
690
880
  export interface RequestPurchaseAndroidProps {
691
881
  /** Personalized offer flag */
692
882
  isOfferPersonalized?: (boolean | null);
@@ -727,6 +917,14 @@ export type RequestPurchaseProps =
727
917
  useAlternativeBilling?: boolean | null;
728
918
  };
729
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
+ */
730
928
  export interface RequestPurchasePropsByPlatforms {
731
929
  /** @deprecated Use google instead */
732
930
  android?: (RequestPurchaseAndroidProps | null);
@@ -749,12 +947,20 @@ export interface RequestSubscriptionAndroidProps {
749
947
  obfuscatedProfileIdAndroid?: (string | null);
750
948
  /** Purchase token for upgrades/downgrades */
751
949
  purchaseTokenAndroid?: (string | null);
752
- /** 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
+ */
753
954
  replacementModeAndroid?: (number | null);
754
955
  /** List of subscription SKUs */
755
956
  skus: string[];
756
957
  /** Subscription offers */
757
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);
758
964
  }
759
965
 
760
966
  export interface RequestSubscriptionIosProps {
@@ -765,6 +971,14 @@ export interface RequestSubscriptionIosProps {
765
971
  withOffer?: (DiscountOfferInputIOS | null);
766
972
  }
767
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
+ */
768
982
  export interface RequestSubscriptionPropsByPlatforms {
769
983
  /** @deprecated Use google instead */
770
984
  android?: (RequestSubscriptionAndroidProps | null);
@@ -786,12 +1000,18 @@ export interface RequestVerifyPurchaseWithIapkitGoogleProps {
786
1000
  purchaseToken: string;
787
1001
  }
788
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
+ */
789
1009
  export interface RequestVerifyPurchaseWithIapkitProps {
790
1010
  /** API key used for the Authorization header (Bearer {apiKey}). */
791
1011
  apiKey?: (string | null);
792
- /** Apple verification parameters. */
1012
+ /** Apple App Store verification parameters. */
793
1013
  apple?: (RequestVerifyPurchaseWithIapkitAppleProps | null);
794
- /** Google verification parameters. */
1014
+ /** Google Play Store verification parameters. */
795
1015
  google?: (RequestVerifyPurchaseWithIapkitGoogleProps | null);
796
1016
  }
797
1017
 
@@ -844,6 +1064,25 @@ export interface SubscriptionPeriodValueIOS {
844
1064
  value: number;
845
1065
  }
846
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
+
847
1086
  export interface SubscriptionStatusIOS {
848
1087
  renewalInfo?: (RenewalInfoIOS | null);
849
1088
  state: string;
@@ -860,21 +1099,87 @@ export interface UserChoiceBillingDetails {
860
1099
  products: string[];
861
1100
  }
862
1101
 
863
- 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
+ */
864
1133
  accessToken: string;
1134
+ /** Whether this is a subscription purchase (affects API endpoint used) */
865
1135
  isSub?: (boolean | null);
1136
+ /** Android package name (e.g., com.example.app) */
866
1137
  packageName: string;
867
- 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;
868
1145
  }
869
1146
 
870
- export interface VerifyPurchaseProps {
871
- /** Android-specific validation options */
872
- androidOptions?: (VerifyPurchaseAndroidOptions | null);
873
- /** 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 */
874
1161
  sku: string;
1162
+ /** The user ID of the user whose purchase you want to verify */
1163
+ userId: string;
875
1164
  }
876
1165
 
877
- export type VerifyPurchaseResult = VerifyPurchaseResultAndroid | VerifyPurchaseResultIOS;
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);
1180
+ }
1181
+
1182
+ export type VerifyPurchaseResult = VerifyPurchaseResultAndroid | VerifyPurchaseResultHorizon | VerifyPurchaseResultIOS;
878
1183
 
879
1184
  export interface VerifyPurchaseResultAndroid {
880
1185
  autoRenewing: boolean;
@@ -897,6 +1202,17 @@ export interface VerifyPurchaseResultAndroid {
897
1202
  testTransaction: boolean;
898
1203
  }
899
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
+
900
1216
  export interface VerifyPurchaseResultIOS {
901
1217
  /** Whether the receipt is valid */
902
1218
  isValid: boolean;