react-native-iap 14.5.0 → 14.5.1-rc.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 (66) hide show
  1. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +47 -7
  2. package/ios/reactnativeiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  3. package/ios/reactnativeiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  4. package/lib/module/types.js +35 -0
  5. package/lib/module/types.js.map +1 -1
  6. package/lib/module/utils/type-bridge.js +2 -1
  7. package/lib/module/utils/type-bridge.js.map +1 -1
  8. package/lib/typescript/src/specs/RnIap.nitro.d.ts +54 -1
  9. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  10. package/lib/typescript/src/types.d.ts +127 -14
  11. package/lib/typescript/src/types.d.ts.map +1 -1
  12. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
  13. package/nitrogen/generated/android/c++/JFunc_void_NitroProduct.hpp +13 -0
  14. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +24 -0
  15. package/nitrogen/generated/android/c++/JNitroDiscountAmountAndroid.hpp +61 -0
  16. package/nitrogen/generated/android/c++/JNitroDiscountDisplayInfoAndroid.hpp +64 -0
  17. package/nitrogen/generated/android/c++/JNitroLimitedQuantityInfoAndroid.hpp +61 -0
  18. package/nitrogen/generated/android/c++/JNitroOneTimePurchaseOfferDetail.hpp +70 -3
  19. package/nitrogen/generated/android/c++/JNitroPreorderDetailsAndroid.hpp +61 -0
  20. package/nitrogen/generated/android/c++/JNitroProduct.hpp +35 -5
  21. package/nitrogen/generated/android/c++/JNitroPurchase.hpp +7 -3
  22. package/nitrogen/generated/android/c++/JNitroRentalDetailsAndroid.hpp +62 -0
  23. package/nitrogen/generated/android/c++/JNitroValidTimeWindowAndroid.hpp +61 -0
  24. package/nitrogen/generated/android/c++/JPurchaseAndroid.hpp +5 -1
  25. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroDiscountAmountAndroid.kt +39 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroDiscountDisplayInfoAndroid.kt +39 -0
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroLimitedQuantityInfoAndroid.kt +39 -0
  28. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroOneTimePurchaseOfferDetail.kt +30 -3
  29. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPreorderDetailsAndroid.kt +39 -0
  30. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroProduct.kt +2 -2
  31. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchase.kt +6 -3
  32. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroRentalDetailsAndroid.kt +39 -0
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroValidTimeWindowAndroid.kt +39 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/PurchaseAndroid.kt +5 -2
  35. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +137 -18
  36. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +18 -0
  37. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +18 -0
  38. package/nitrogen/generated/ios/swift/NitroDiscountAmountAndroid.swift +46 -0
  39. package/nitrogen/generated/ios/swift/NitroDiscountDisplayInfoAndroid.swift +70 -0
  40. package/nitrogen/generated/ios/swift/NitroLimitedQuantityInfoAndroid.swift +46 -0
  41. package/nitrogen/generated/ios/swift/NitroOneTimePurchaseOfferDetail.swift +211 -2
  42. package/nitrogen/generated/ios/swift/NitroPreorderDetailsAndroid.swift +46 -0
  43. package/nitrogen/generated/ios/swift/NitroProduct.swift +26 -7
  44. package/nitrogen/generated/ios/swift/NitroPurchase.swift +31 -1
  45. package/nitrogen/generated/ios/swift/NitroRentalDetailsAndroid.swift +65 -0
  46. package/nitrogen/generated/ios/swift/NitroValidTimeWindowAndroid.swift +46 -0
  47. package/nitrogen/generated/ios/swift/PurchaseAndroid.swift +32 -2
  48. package/nitrogen/generated/shared/c++/NitroDiscountAmountAndroid.hpp +79 -0
  49. package/nitrogen/generated/shared/c++/NitroDiscountDisplayInfoAndroid.hpp +81 -0
  50. package/nitrogen/generated/shared/c++/NitroLimitedQuantityInfoAndroid.hpp +79 -0
  51. package/nitrogen/generated/shared/c++/NitroOneTimePurchaseOfferDetail.hpp +55 -3
  52. package/nitrogen/generated/shared/c++/NitroPreorderDetailsAndroid.hpp +79 -0
  53. package/nitrogen/generated/shared/c++/NitroProduct.hpp +6 -5
  54. package/nitrogen/generated/shared/c++/NitroPurchase.hpp +6 -2
  55. package/nitrogen/generated/shared/c++/NitroRentalDetailsAndroid.hpp +80 -0
  56. package/nitrogen/generated/shared/c++/NitroValidTimeWindowAndroid.hpp +79 -0
  57. package/nitrogen/generated/shared/c++/PurchaseAndroid.hpp +5 -1
  58. package/openiap-versions.json +2 -2
  59. package/package.json +1 -1
  60. package/plugin/build/src/withIAP.d.ts +3 -0
  61. package/plugin/build/src/withIAP.js +81 -0
  62. package/plugin/build/tsconfig.tsbuildinfo +1 -0
  63. package/plugin/tsconfig.tsbuildinfo +1 -1
  64. package/src/specs/RnIap.nitro.ts +60 -1
  65. package/src/types.ts +133 -14
  66. package/src/utils/type-bridge.ts +1 -0
@@ -52,6 +52,7 @@ namespace margelo::nitro::iap {
52
52
  std::optional<std::vector<std::string>> ids SWIFT_PRIVATE;
53
53
  std::optional<bool> isAcknowledgedAndroid SWIFT_PRIVATE;
54
54
  bool isAutoRenewing SWIFT_PRIVATE;
55
+ std::optional<bool> isSuspendedAndroid SWIFT_PRIVATE;
55
56
  std::optional<std::string> obfuscatedAccountIdAndroid SWIFT_PRIVATE;
56
57
  std::optional<std::string> obfuscatedProfileIdAndroid SWIFT_PRIVATE;
57
58
  std::optional<std::string> packageNameAndroid SWIFT_PRIVATE;
@@ -67,7 +68,7 @@ namespace margelo::nitro::iap {
67
68
 
68
69
  public:
69
70
  PurchaseAndroid() = default;
70
- explicit PurchaseAndroid(std::optional<bool> autoRenewingAndroid, std::optional<std::string> currentPlanId, std::optional<std::string> dataAndroid, std::optional<std::string> developerPayloadAndroid, std::string id, std::optional<std::vector<std::string>> ids, std::optional<bool> isAcknowledgedAndroid, bool isAutoRenewing, std::optional<std::string> obfuscatedAccountIdAndroid, std::optional<std::string> obfuscatedProfileIdAndroid, std::optional<std::string> packageNameAndroid, IapPlatform platform, std::string productId, PurchaseState purchaseState, std::optional<std::string> purchaseToken, double quantity, std::optional<std::string> signatureAndroid, IapStore store, double transactionDate, std::optional<std::string> transactionId): autoRenewingAndroid(autoRenewingAndroid), currentPlanId(currentPlanId), dataAndroid(dataAndroid), developerPayloadAndroid(developerPayloadAndroid), id(id), ids(ids), isAcknowledgedAndroid(isAcknowledgedAndroid), isAutoRenewing(isAutoRenewing), obfuscatedAccountIdAndroid(obfuscatedAccountIdAndroid), obfuscatedProfileIdAndroid(obfuscatedProfileIdAndroid), packageNameAndroid(packageNameAndroid), platform(platform), productId(productId), purchaseState(purchaseState), purchaseToken(purchaseToken), quantity(quantity), signatureAndroid(signatureAndroid), store(store), transactionDate(transactionDate), transactionId(transactionId) {}
71
+ explicit PurchaseAndroid(std::optional<bool> autoRenewingAndroid, std::optional<std::string> currentPlanId, std::optional<std::string> dataAndroid, std::optional<std::string> developerPayloadAndroid, std::string id, std::optional<std::vector<std::string>> ids, std::optional<bool> isAcknowledgedAndroid, bool isAutoRenewing, std::optional<bool> isSuspendedAndroid, std::optional<std::string> obfuscatedAccountIdAndroid, std::optional<std::string> obfuscatedProfileIdAndroid, std::optional<std::string> packageNameAndroid, IapPlatform platform, std::string productId, PurchaseState purchaseState, std::optional<std::string> purchaseToken, double quantity, std::optional<std::string> signatureAndroid, IapStore store, double transactionDate, std::optional<std::string> transactionId): autoRenewingAndroid(autoRenewingAndroid), currentPlanId(currentPlanId), dataAndroid(dataAndroid), developerPayloadAndroid(developerPayloadAndroid), id(id), ids(ids), isAcknowledgedAndroid(isAcknowledgedAndroid), isAutoRenewing(isAutoRenewing), isSuspendedAndroid(isSuspendedAndroid), obfuscatedAccountIdAndroid(obfuscatedAccountIdAndroid), obfuscatedProfileIdAndroid(obfuscatedProfileIdAndroid), packageNameAndroid(packageNameAndroid), platform(platform), productId(productId), purchaseState(purchaseState), purchaseToken(purchaseToken), quantity(quantity), signatureAndroid(signatureAndroid), store(store), transactionDate(transactionDate), transactionId(transactionId) {}
71
72
  };
72
73
 
73
74
  } // namespace margelo::nitro::iap
@@ -88,6 +89,7 @@ namespace margelo::nitro {
88
89
  JSIConverter<std::optional<std::vector<std::string>>>::fromJSI(runtime, obj.getProperty(runtime, "ids")),
89
90
  JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, "isAcknowledgedAndroid")),
90
91
  JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, "isAutoRenewing")),
92
+ JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, "isSuspendedAndroid")),
91
93
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "obfuscatedAccountIdAndroid")),
92
94
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "obfuscatedProfileIdAndroid")),
93
95
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "packageNameAndroid")),
@@ -112,6 +114,7 @@ namespace margelo::nitro {
112
114
  obj.setProperty(runtime, "ids", JSIConverter<std::optional<std::vector<std::string>>>::toJSI(runtime, arg.ids));
113
115
  obj.setProperty(runtime, "isAcknowledgedAndroid", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isAcknowledgedAndroid));
114
116
  obj.setProperty(runtime, "isAutoRenewing", JSIConverter<bool>::toJSI(runtime, arg.isAutoRenewing));
117
+ obj.setProperty(runtime, "isSuspendedAndroid", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isSuspendedAndroid));
115
118
  obj.setProperty(runtime, "obfuscatedAccountIdAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.obfuscatedAccountIdAndroid));
116
119
  obj.setProperty(runtime, "obfuscatedProfileIdAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.obfuscatedProfileIdAndroid));
117
120
  obj.setProperty(runtime, "packageNameAndroid", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.packageNameAndroid));
@@ -142,6 +145,7 @@ namespace margelo::nitro {
142
145
  if (!JSIConverter<std::optional<std::vector<std::string>>>::canConvert(runtime, obj.getProperty(runtime, "ids"))) return false;
143
146
  if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, "isAcknowledgedAndroid"))) return false;
144
147
  if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, "isAutoRenewing"))) return false;
148
+ if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, "isSuspendedAndroid"))) return false;
145
149
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "obfuscatedAccountIdAndroid"))) return false;
146
150
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "obfuscatedProfileIdAndroid"))) return false;
147
151
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "packageNameAndroid"))) return false;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "apple": "1.3.0",
3
- "google": "1.3.10",
4
- "gql": "1.3.0"
3
+ "google": "1.3.11",
4
+ "gql": "1.3.1"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-iap",
3
- "version": "14.5.0",
3
+ "version": "14.5.1-rc.1",
4
4
  "description": "React Native In-App Purchases module for iOS and Android using Nitro",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -0,0 +1,3 @@
1
+ import type { ConfigPlugin } from 'expo/config-plugins';
2
+ declare const _default: ConfigPlugin<void>;
3
+ export default _default;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("expo/config-plugins");
4
+ const pkg = require('../../package.json');
5
+ // Global flag to prevent duplicate logs
6
+ let hasLoggedPluginExecution = false;
7
+ const addLineToGradle = (content, anchor, lineToAdd, offset = 1) => {
8
+ const lines = content.split('\n');
9
+ const index = lines.findIndex((line) => line.match(anchor));
10
+ if (index === -1) {
11
+ console.warn(`Anchor "${anchor}" not found in build.gradle. Appending to end.`);
12
+ lines.push(lineToAdd);
13
+ }
14
+ else {
15
+ lines.splice(index + offset, 0, lineToAdd);
16
+ }
17
+ return lines.join('\n');
18
+ };
19
+ const modifyAppBuildGradle = (gradle) => {
20
+ let modified = gradle;
21
+ // Add billing library dependencies to app-level build.gradle
22
+ const billingDep = ` implementation "com.android.billingclient:billing-ktx:8.0.0"`;
23
+ const gmsDep = ` implementation "com.google.android.gms:play-services-base:18.1.0"`;
24
+ let hasAddedDependency = false;
25
+ if (!modified.includes(billingDep)) {
26
+ modified = addLineToGradle(modified, /dependencies\s*{/, billingDep);
27
+ hasAddedDependency = true;
28
+ }
29
+ if (!modified.includes(gmsDep)) {
30
+ modified = addLineToGradle(modified, /dependencies\s*{/, gmsDep, 1);
31
+ hasAddedDependency = true;
32
+ }
33
+ // Log only once and only if we actually added dependencies
34
+ if (hasAddedDependency && !hasLoggedPluginExecution) {
35
+ console.log('🛠️ react-native-iap: Added billing dependencies to build.gradle');
36
+ }
37
+ return modified;
38
+ };
39
+ const withIapAndroid = (config) => {
40
+ // Add IAP dependencies to app build.gradle
41
+ config = (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
42
+ config.modResults.contents = modifyAppBuildGradle(config.modResults.contents);
43
+ return config;
44
+ });
45
+ config = (0, config_plugins_1.withAndroidManifest)(config, (config) => {
46
+ const manifest = config.modResults;
47
+ if (!manifest.manifest['uses-permission']) {
48
+ manifest.manifest['uses-permission'] = [];
49
+ }
50
+ const permissions = manifest.manifest['uses-permission'];
51
+ const billingPerm = { $: { 'android:name': 'com.android.vending.BILLING' } };
52
+ const alreadyExists = permissions.some((p) => p.$['android:name'] === 'com.android.vending.BILLING');
53
+ if (!alreadyExists) {
54
+ permissions.push(billingPerm);
55
+ if (!hasLoggedPluginExecution) {
56
+ console.log('✅ Added com.android.vending.BILLING to AndroidManifest.xml');
57
+ }
58
+ }
59
+ else {
60
+ if (!hasLoggedPluginExecution) {
61
+ console.log('ℹ️ com.android.vending.BILLING already exists in AndroidManifest.xml');
62
+ }
63
+ }
64
+ return config;
65
+ });
66
+ return config;
67
+ };
68
+ const withIAP = (config, _props) => {
69
+ try {
70
+ const result = withIapAndroid(config);
71
+ // Set flag after first execution to prevent duplicate logs
72
+ hasLoggedPluginExecution = true;
73
+ return result;
74
+ }
75
+ catch (error) {
76
+ config_plugins_1.WarningAggregator.addWarningAndroid('react-native-iap', `react-native-iap plugin encountered an error: ${error}`);
77
+ console.error('react-native-iap plugin error:', error);
78
+ return config;
79
+ }
80
+ };
81
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withIAP, pkg.name, pkg.version);
@@ -0,0 +1 @@
1
+ {"root":["../src/withiap.ts"],"version":"5.9.2"}
@@ -1 +1 @@
1
- {"root":["./src/withIAP.ts"],"version":"5.9.2"}
1
+ {"root":["./src/withiap.ts"],"version":"5.9.2"}
@@ -251,13 +251,71 @@ export interface NitroVerifyPurchaseWithProviderResult {
251
251
  provider: PurchaseVerificationProvider;
252
252
  }
253
253
 
254
+ /**
255
+ * Discount amount details for one-time purchase offers (Android)
256
+ */
257
+ export interface NitroDiscountAmountAndroid {
258
+ discountAmountMicros: string;
259
+ formattedDiscountAmount: string;
260
+ }
261
+
262
+ /**
263
+ * Discount display information for one-time purchase offers (Android)
264
+ */
265
+ export interface NitroDiscountDisplayInfoAndroid {
266
+ discountAmount?: NitroDiscountAmountAndroid | null;
267
+ percentageDiscount?: number | null;
268
+ }
269
+
270
+ /**
271
+ * Limited quantity information for one-time purchase offers (Android)
272
+ */
273
+ export interface NitroLimitedQuantityInfoAndroid {
274
+ maximumQuantity: number;
275
+ remainingQuantity: number;
276
+ }
277
+
278
+ /**
279
+ * Pre-order details for one-time purchase products (Android)
280
+ */
281
+ export interface NitroPreorderDetailsAndroid {
282
+ preorderPresaleEndTimeMillis: string;
283
+ preorderReleaseTimeMillis: string;
284
+ }
285
+
286
+ /**
287
+ * Rental details for one-time purchase products (Android)
288
+ */
289
+ export interface NitroRentalDetailsAndroid {
290
+ rentalExpirationPeriod?: string | null;
291
+ rentalPeriod: string;
292
+ }
293
+
294
+ /**
295
+ * Valid time window for when an offer is available (Android)
296
+ */
297
+ export interface NitroValidTimeWindowAndroid {
298
+ endTimeMillis: string;
299
+ startTimeMillis: string;
300
+ }
301
+
254
302
  /**
255
303
  * Android one-time purchase offer details
304
+ * Available in Google Play Billing Library 7.0+
256
305
  */
257
306
  export interface NitroOneTimePurchaseOfferDetail {
307
+ discountDisplayInfo?: NitroDiscountDisplayInfoAndroid | null;
258
308
  formattedPrice: string;
309
+ fullPriceMicros?: string | null;
310
+ limitedQuantityInfo?: NitroLimitedQuantityInfoAndroid | null;
311
+ offerId?: string | null;
312
+ offerTags: string[];
313
+ offerToken: string;
314
+ preorderDetailsAndroid?: NitroPreorderDetailsAndroid | null;
259
315
  priceAmountMicros: string;
260
316
  priceCurrencyCode: string;
317
+ rentalDetailsAndroid?: NitroRentalDetailsAndroid | null;
318
+ validTimeWindow?: NitroValidTimeWindowAndroid | null;
261
319
  }
262
320
 
263
321
  export interface NitroPurchase {
@@ -306,6 +364,7 @@ export interface NitroPurchase {
306
364
  obfuscatedAccountIdAndroid?: string | null;
307
365
  obfuscatedProfileIdAndroid?: string | null;
308
366
  developerPayloadAndroid?: string | null;
367
+ isSuspendedAndroid?: boolean | null;
309
368
  }
310
369
 
311
370
  /**
@@ -380,7 +439,7 @@ export interface NitroProduct {
380
439
  subscriptionPeriodAndroid?: string | null;
381
440
  freeTrialPeriodAndroid?: string | null;
382
441
  subscriptionOfferDetailsAndroid?: string | null;
383
- oneTimePurchaseOfferDetailsAndroid?: NitroOneTimePurchaseOfferDetail | null;
442
+ oneTimePurchaseOfferDetailsAndroid?: NitroOneTimePurchaseOfferDetail[] | null;
384
443
  }
385
444
 
386
445
  // ╔══════════════════════════════════════════════════════════════════════════╗
package/src/types.ts CHANGED
@@ -72,6 +72,34 @@ export interface DeepLinkOptions {
72
72
  skuAndroid?: (string | null);
73
73
  }
74
74
 
75
+ /**
76
+ * Discount amount details for one-time purchase offers (Android)
77
+ * Available in Google Play Billing Library 7.0+
78
+ */
79
+ export interface DiscountAmountAndroid {
80
+ /** Discount amount in micro-units (1,000,000 = 1 unit of currency) */
81
+ discountAmountMicros: string;
82
+ /** Formatted discount amount with currency sign (e.g., "$4.99") */
83
+ formattedDiscountAmount: string;
84
+ }
85
+
86
+ /**
87
+ * Discount display information for one-time purchase offers (Android)
88
+ * Available in Google Play Billing Library 7.0+
89
+ */
90
+ export interface DiscountDisplayInfoAndroid {
91
+ /**
92
+ * Absolute discount amount details
93
+ * Only returned for fixed amount discounts
94
+ */
95
+ discountAmount?: (DiscountAmountAndroid | null);
96
+ /**
97
+ * Percentage discount (e.g., 33 for 33% off)
98
+ * Only returned for percentage-based discounts
99
+ */
100
+ percentageDiscount?: (number | null);
101
+ }
102
+
75
103
  export interface DiscountIOS {
76
104
  identifier: string;
77
105
  localizedPrice?: (string | null);
@@ -194,6 +222,17 @@ export interface InitConnectionConfig {
194
222
  alternativeBillingModeAndroid?: (AlternativeBillingModeAndroid | null);
195
223
  }
196
224
 
225
+ /**
226
+ * Limited quantity information for one-time purchase offers (Android)
227
+ * Available in Google Play Billing Library 7.0+
228
+ */
229
+ export interface LimitedQuantityInfoAndroid {
230
+ /** Maximum quantity a user can purchase */
231
+ maximumQuantity: number;
232
+ /** Remaining quantity the user can still purchase */
233
+ remainingQuantity: number;
234
+ }
235
+
197
236
  export interface Mutation {
198
237
  /** Acknowledge a non-consumable purchase or subscription */
199
238
  acknowledgePurchaseAndroid: Promise<boolean>;
@@ -310,6 +349,23 @@ export type MutationVerifyPurchaseWithProviderArgs = VerifyPurchaseWithProviderP
310
349
 
311
350
  export type PaymentModeIOS = 'empty' | 'free-trial' | 'pay-as-you-go' | 'pay-up-front';
312
351
 
352
+ /**
353
+ * Pre-order details for one-time purchase products (Android)
354
+ * Available in Google Play Billing Library 8.1.0+
355
+ */
356
+ export interface PreorderDetailsAndroid {
357
+ /**
358
+ * Pre-order presale end time in milliseconds since epoch.
359
+ * This is when the presale period ends and the product will be released.
360
+ */
361
+ preorderPresaleEndTimeMillis: string;
362
+ /**
363
+ * Pre-order release time in milliseconds since epoch.
364
+ * This is when the product will be available to users who pre-ordered.
365
+ */
366
+ preorderReleaseTimeMillis: string;
367
+ }
368
+
313
369
  export interface PricingPhaseAndroid {
314
370
  billingCycleCount: number;
315
371
  billingPeriod: string;
@@ -333,7 +389,11 @@ export interface ProductAndroid extends ProductCommon {
333
389
  displayPrice: string;
334
390
  id: string;
335
391
  nameAndroid: string;
336
- oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail | null);
392
+ /**
393
+ * One-time purchase offer details including discounts (Android)
394
+ * Returns all eligible offers. Available in Google Play Billing Library 7.0+
395
+ */
396
+ oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
337
397
  platform: 'android';
338
398
  price?: (number | null);
339
399
  subscriptionOfferDetailsAndroid?: (ProductSubscriptionAndroidOfferDetails[] | null);
@@ -341,10 +401,41 @@ export interface ProductAndroid extends ProductCommon {
341
401
  type: 'in-app';
342
402
  }
343
403
 
404
+ /**
405
+ * One-time purchase offer details (Android)
406
+ * Available in Google Play Billing Library 7.0+
407
+ */
344
408
  export interface ProductAndroidOneTimePurchaseOfferDetail {
409
+ /**
410
+ * Discount display information
411
+ * Only available for discounted offers
412
+ */
413
+ discountDisplayInfo?: (DiscountDisplayInfoAndroid | null);
345
414
  formattedPrice: string;
415
+ /**
416
+ * Full (non-discounted) price in micro-units
417
+ * Only available for discounted offers
418
+ */
419
+ fullPriceMicros?: (string | null);
420
+ /** Limited quantity information */
421
+ limitedQuantityInfo?: (LimitedQuantityInfoAndroid | null);
422
+ /** Offer ID */
423
+ offerId?: (string | null);
424
+ /** List of offer tags */
425
+ offerTags: string[];
426
+ /** Offer token for use in BillingFlowParams when purchasing */
427
+ offerToken: string;
428
+ /**
429
+ * Pre-order details for products available for pre-order
430
+ * Available in Google Play Billing Library 8.1.0+
431
+ */
432
+ preorderDetailsAndroid?: (PreorderDetailsAndroid | null);
346
433
  priceAmountMicros: string;
347
434
  priceCurrencyCode: string;
435
+ /** Rental details for rental offers */
436
+ rentalDetailsAndroid?: (RentalDetailsAndroid | null);
437
+ /** Valid time window for the offer */
438
+ validTimeWindow?: (ValidTimeWindowAndroid | null);
348
439
  }
349
440
 
350
441
  export interface ProductCommon {
@@ -397,7 +488,11 @@ export interface ProductSubscriptionAndroid extends ProductCommon {
397
488
  displayPrice: string;
398
489
  id: string;
399
490
  nameAndroid: string;
400
- oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail | null);
491
+ /**
492
+ * One-time purchase offer details including discounts (Android)
493
+ * Returns all eligible offers. Available in Google Play Billing Library 7.0+
494
+ */
495
+ oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
401
496
  platform: 'android';
402
497
  price?: (number | null);
403
498
  subscriptionOfferDetailsAndroid: ProductSubscriptionAndroidOfferDetails[];
@@ -454,13 +549,18 @@ export interface PurchaseAndroid extends PurchaseCommon {
454
549
  ids?: (string[] | null);
455
550
  isAcknowledgedAndroid?: (boolean | null);
456
551
  isAutoRenewing: boolean;
552
+ /**
553
+ * Whether the subscription is suspended (Android)
554
+ * A suspended subscription means the user's payment method failed and they need to fix it.
555
+ * Users should be directed to the subscription center to resolve the issue.
556
+ * Do NOT grant entitlements for suspended subscriptions.
557
+ * Available in Google Play Billing Library 8.1.0+
558
+ */
559
+ isSuspendedAndroid?: (boolean | null);
457
560
  obfuscatedAccountIdAndroid?: (string | null);
458
561
  obfuscatedProfileIdAndroid?: (string | null);
459
562
  packageNameAndroid?: (string | null);
460
- /**
461
- * @deprecated Use store instead
462
- * @deprecated Use store instead
463
- */
563
+ /** @deprecated Use store instead */
464
564
  platform: IapPlatform;
465
565
  productId: string;
466
566
  purchaseState: PurchaseState;
@@ -484,10 +584,7 @@ export interface PurchaseCommon {
484
584
  id: string;
485
585
  ids?: (string[] | null);
486
586
  isAutoRenewing: boolean;
487
- /**
488
- * @deprecated Use store instead
489
- * @deprecated Use store instead
490
- */
587
+ /** @deprecated Use store instead */
491
588
  platform: IapPlatform;
492
589
  productId: string;
493
590
  purchaseState: PurchaseState;
@@ -522,10 +619,7 @@ export interface PurchaseIOS extends PurchaseCommon {
522
619
  originalTransactionDateIOS?: (number | null);
523
620
  originalTransactionIdentifierIOS?: (string | null);
524
621
  ownershipTypeIOS?: (string | null);
525
- /**
526
- * @deprecated Use store instead
527
- * @deprecated Use store instead
528
- */
622
+ /** @deprecated Use store instead */
529
623
  platform: IapPlatform;
530
624
  productId: string;
531
625
  purchaseState: PurchaseState;
@@ -687,6 +781,20 @@ export interface RenewalInfoIOS {
687
781
  willAutoRenew: boolean;
688
782
  }
689
783
 
784
+ /**
785
+ * Rental details for one-time purchase products that can be rented (Android)
786
+ * Available in Google Play Billing Library 7.0+
787
+ */
788
+ export interface RentalDetailsAndroid {
789
+ /**
790
+ * Rental expiration period in ISO 8601 format
791
+ * Time after rental period ends when user can still extend
792
+ */
793
+ rentalExpirationPeriod?: (string | null);
794
+ /** Rental period in ISO 8601 format (e.g., P7D for 7 days) */
795
+ rentalPeriod: string;
796
+ }
797
+
690
798
  export interface RequestPurchaseAndroidProps {
691
799
  /** Personalized offer flag */
692
800
  isOfferPersonalized?: (boolean | null);
@@ -860,6 +968,17 @@ export interface UserChoiceBillingDetails {
860
968
  products: string[];
861
969
  }
862
970
 
971
+ /**
972
+ * Valid time window for when an offer is available (Android)
973
+ * Available in Google Play Billing Library 7.0+
974
+ */
975
+ export interface ValidTimeWindowAndroid {
976
+ /** End time in milliseconds since epoch */
977
+ endTimeMillis: string;
978
+ /** Start time in milliseconds since epoch */
979
+ startTimeMillis: string;
980
+ }
981
+
863
982
  export interface VerifyPurchaseAndroidOptions {
864
983
  accessToken: string;
865
984
  isSub?: (boolean | null);
@@ -478,6 +478,7 @@ export function convertNitroPurchaseToPurchase(
478
478
  developerPayloadAndroid: toNullableString(
479
479
  nitroPurchase.developerPayloadAndroid,
480
480
  ),
481
+ isSuspendedAndroid: toNullableBoolean(nitroPurchase.isSuspendedAndroid),
481
482
  };
482
483
 
483
484
  return androidPurchase;