expo-iap 3.0.5 → 3.0.7-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 (46) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/CLAUDE.md +8 -0
  3. package/android/build.gradle +1 -1
  4. package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +35 -0
  5. package/build/index.d.ts +10 -3
  6. package/build/index.d.ts.map +1 -1
  7. package/build/index.js +23 -14
  8. package/build/index.js.map +1 -1
  9. package/build/useIAP.d.ts +0 -4
  10. package/build/useIAP.d.ts.map +1 -1
  11. package/build/useIAP.js +10 -75
  12. package/build/useIAP.js.map +1 -1
  13. package/coverage/clover.xml +440 -0
  14. package/coverage/coverage-final.json +7 -0
  15. package/coverage/lcov-report/base.css +224 -0
  16. package/coverage/lcov-report/block-navigation.js +87 -0
  17. package/coverage/lcov-report/favicon.png +0 -0
  18. package/coverage/lcov-report/index.html +161 -0
  19. package/coverage/lcov-report/prettify.css +1 -0
  20. package/coverage/lcov-report/prettify.js +2 -0
  21. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  22. package/coverage/lcov-report/sorter.js +196 -0
  23. package/coverage/lcov-report/src/ExpoIap.types.ts.html +1243 -0
  24. package/coverage/lcov-report/src/PurchaseError.ts.html +787 -0
  25. package/coverage/lcov-report/src/helpers/index.html +116 -0
  26. package/coverage/lcov-report/src/helpers/subscription.ts.html +496 -0
  27. package/coverage/lcov-report/src/index.html +131 -0
  28. package/coverage/lcov-report/src/index.ts.html +2236 -0
  29. package/coverage/lcov-report/src/modules/android.ts.html +544 -0
  30. package/coverage/lcov-report/src/modules/index.html +131 -0
  31. package/coverage/lcov-report/src/modules/ios.ts.html +952 -0
  32. package/coverage/lcov-report/src/purchase-error.ts.html +880 -0
  33. package/coverage/lcov-report/src/types/ExpoIapAndroid.types.ts.html +493 -0
  34. package/coverage/lcov-report/src/types/index.html +116 -0
  35. package/coverage/lcov-report/src/useIap.ts.html +1483 -0
  36. package/coverage/lcov-report/src/utils/errorMapping.ts.html +529 -0
  37. package/coverage/lcov-report/src/utils/index.html +116 -0
  38. package/coverage/lcov.info +852 -0
  39. package/ios/expoiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  40. package/ios/expoiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  41. package/package.json +1 -1
  42. package/plugin/build/withIAP.js +3 -3
  43. package/plugin/src/withIAP.ts +3 -3
  44. package/plugin/tsconfig.tsbuildinfo +1 -1
  45. package/src/index.ts +93 -29
  46. package/src/useIAP.ts +10 -85
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 3.0.6 (Breaking: useIAP) - 2025-09-18
4
+
5
+ - Hook: Remove the transient `currentPurchase` / `currentPurchaseError` state from `useIAP` so consumers rely exclusively on the `onPurchaseSuccess` and `onPurchaseError` callbacks for post-purchase handling. This is a light breaking tweak for hook callers, but keeps the root API untouched.
6
+
3
7
  ## 3.0.5 - 2025-09-17
4
8
 
5
9
  - Types: Normalize OpenIAP literal unions to `'in-app'`, `'ios'`, and `'android'`, update `useIAP` helpers to the new `PurchaseRequestInput`, and refresh docs/examples/tests to the lowercase schema tokens.
package/CLAUDE.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Implementation Guidelines
2
2
 
3
+ ## Commit Message Convention
4
+
5
+ - Follow the Angular Conventional Commits format: `<type>(<scope>): <subject>`
6
+ - Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`
7
+ - Scope is optional but recommended (for example: `auth`, `api`, `ui`)
8
+ - Subject must be imperative, lowercase, without a trailing period, and roughly 50 characters
9
+ - Wrap commit body lines near 72 characters and include footers such as `BREAKING CHANGE:` or `Closes #123` when needed
10
+
3
11
  ## Expo-Specific Guidelines
4
12
 
5
13
  ### iOS Pod Configuration
@@ -58,6 +58,6 @@ dependencies {
58
58
  implementation project(":openiap-google")
59
59
  } else {
60
60
  // Fallback to published artifact when local project isn't linked
61
- implementation "io.github.hyochan.openiap:openiap-google:1.1.10"
61
+ implementation "io.github.hyochan.openiap:openiap-google:1.1.11"
62
62
  }
63
63
  }
@@ -7,6 +7,7 @@ import dev.hyo.openiap.OpenIapModule
7
7
  import dev.hyo.openiap.models.DeepLinkOptions
8
8
  import dev.hyo.openiap.models.ProductRequest
9
9
  import dev.hyo.openiap.models.RequestPurchaseParams
10
+ import dev.hyo.openiap.models.RequestSubscriptionAndroidProps
10
11
  import expo.modules.kotlin.Promise
11
12
  import expo.modules.kotlin.exception.Exceptions
12
13
  import expo.modules.kotlin.modules.Module
@@ -196,12 +197,45 @@ class ExpoIapModule : Module() {
196
197
  val obfuscatedProfileId =
197
198
  (params["obfuscatedProfileIdAndroid"] ?: params["obfuscatedProfileId"]) as? String
198
199
  val isOfferPersonalized = params["isOfferPersonalized"] as? Boolean ?: false
200
+ val offerTokenArr =
201
+ (params["offerTokenArr"] as? List<*>)?.filterIsInstance<String>() ?: emptyList()
202
+ val subscriptionOffersParam =
203
+ (params["subscriptionOffers"] as? List<*>)?.mapNotNull { rawOffer ->
204
+ val offerMap = rawOffer as? Map<*, *> ?: return@mapNotNull null
205
+ val sku = offerMap["sku"] as? String
206
+ val offerToken = offerMap["offerToken"] as? String
207
+ if (sku.isNullOrEmpty() || offerToken.isNullOrEmpty()) {
208
+ null
209
+ } else {
210
+ RequestSubscriptionAndroidProps.SubscriptionOffer(sku = sku, offerToken = offerToken)
211
+ }
212
+ } ?: emptyList()
199
213
 
200
214
  PromiseUtils.addPromiseForKey(PromiseUtils.PROMISE_BUY_ITEM, promise)
201
215
  scope.launch {
202
216
  try {
203
217
  openIap.setActivity(currentActivity)
204
218
  val reqType = ProductRequest.ProductRequestType.fromString(type)
219
+ val subscriptionOffers =
220
+ if (reqType == ProductRequest.ProductRequestType.Subs) {
221
+ when {
222
+ subscriptionOffersParam.isNotEmpty() -> subscriptionOffersParam
223
+ offerTokenArr.isNotEmpty() ->
224
+ skus.zip(offerTokenArr).mapNotNull { (sku, token) ->
225
+ if (token.isNotEmpty()) {
226
+ RequestSubscriptionAndroidProps.SubscriptionOffer(
227
+ sku = sku,
228
+ offerToken = token,
229
+ )
230
+ } else {
231
+ null
232
+ }
233
+ }
234
+ else -> emptyList()
235
+ }
236
+ } else {
237
+ emptyList()
238
+ }
205
239
  val result =
206
240
  openIap.requestPurchase(
207
241
  RequestPurchaseParams(
@@ -209,6 +243,7 @@ class ExpoIapModule : Module() {
209
243
  obfuscatedAccountIdAndroid = obfuscatedAccountId,
210
244
  obfuscatedProfileIdAndroid = obfuscatedProfileId,
211
245
  isOfferPersonalized = isOfferPersonalized,
246
+ subscriptionOffers = subscriptionOffers,
212
247
  ),
213
248
  reqType,
214
249
  )
package/build/index.d.ts CHANGED
@@ -12,12 +12,19 @@ export declare enum OpenIapEvent {
12
12
  PromotedProductIOS = "promoted-product-ios"
13
13
  }
14
14
  export declare function setValueAsync(value: string): any;
15
- export declare const emitter: {
16
- addListener: (eventName: string, listener: (...args: any[]) => void) => {
15
+ type ExpoIapEventPayloads = {
16
+ [OpenIapEvent.PurchaseUpdated]: Purchase;
17
+ [OpenIapEvent.PurchaseError]: PurchaseError;
18
+ [OpenIapEvent.PromotedProductIOS]: Product;
19
+ };
20
+ type ExpoIapEventListener<E extends OpenIapEvent> = (payload: ExpoIapEventPayloads[E]) => void;
21
+ type ExpoIapEmitter = {
22
+ addListener<E extends OpenIapEvent>(eventName: E, listener: ExpoIapEventListener<E>): {
17
23
  remove: () => void;
18
24
  };
19
- removeListener: (eventName: string, listener: (...args: any[]) => void) => void;
25
+ removeListener<E extends OpenIapEvent>(eventName: E, listener: ExpoIapEventListener<E>): void;
20
26
  };
27
+ export declare const emitter: ExpoIapEmitter;
21
28
  /**
22
29
  * TODO(v3.1.0): Remove legacy 'inapp' alias once downstream apps migrate to 'in-app'.
23
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,OAAO,EACP,QAAQ,EAER,oBAAoB,EACpB,+BAA+B,EAC/B,mCAAmC,EACnC,mBAAmB,EAGnB,UAAU,EACV,uBAAuB,EACxB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAG/C,cAAc,SAAS,CAAC;AACxB,OAAO,EAAC,cAAc,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAClE,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAG9B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,EAAE,KAAmB,CAAC;AAEnC,oBAAY,YAAY;IACtB,eAAe,qBAAqB;IACpC,aAAa,mBAAmB;IAChC,kBAAkB,yBAAyB;CAC5C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,OAE1C;AAGD,eAAO,MAAM,OAAO,EAAoD;IACtE,WAAW,EAAE,CACX,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAC/B;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAC,CAAC;IAC1B,cAAc,EAAE,CACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAC/B,IAAI,CAAC;CACX,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAE/D,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,+BAA+B,CAAC;IACzC,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,OAAO,EAAE,mCAAmC,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B,oBAAoB,GACpB,2BAA2B,CAAC;AAEhC,MAAM,MAAM,eAAe,GACvB;IACE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB,GACD;IACE,OAAO,EAAE,mCAAmC,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAwBN,eAAO,MAAM,uBAAuB,GAClC,UAAU,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI;YA5DrB,MAAM,IAAI;CAyEzB,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,UAAU,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI;YA5E1B,MAAM,IAAI;CAyFzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI;YAhHtB,MAAM,IAAI;CAyHzB,CAAC;AAEF,wBAAgB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAGjD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,aAAa,GAAU,iBAGjC;IACD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB,KAAG,OAAO,CAAC,OAAO,EAAE,GAAG,mBAAmB,EAAE,CAkD5C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,gEAGnC;IACD,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAChC,KAAG,OAAO,CAAC,QAAQ,EAAE,CAUtB,CAAC;AAEN;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAS;IACP,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAChC,KACL,OAAO,CAAC,QAAQ,EAAE,CAcpB,CAAC;AA4BF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,eAAe,GAC1B,YAAY,oBAAoB,KAC/B,OAAO,CAAC,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,CAkGtC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,6BAG/B;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,KAAG,OAAO,CAAC,UAAU,GAAG,OAAO,CAsC/B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,QAAO,OAAO,CAAC,MAAM,CAMjD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,QAAO,OAAO,CAAC,MAAM,CAS9C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,MAAM,EACX,iBAAiB;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,KACA,OAAO,CAAC,uBAAuB,CAwBjC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,KAAG,OAAO,CAAC,IAAI,CAaf,CAAC;AAEF,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -27,7 +27,8 @@ export function setValueAsync(value) {
27
27
  return ExpoIapModule.setValueAsync(value);
28
28
  }
29
29
  // Ensure the emitter has proper EventEmitter interface
30
- export const emitter = (ExpoIapModule || NativeModulesProxy.ExpoIap);
30
+ export const emitter = (ExpoIapModule ||
31
+ NativeModulesProxy.ExpoIap);
31
32
  const normalizeProductType = (type) => {
32
33
  if (type === 'inapp') {
33
34
  console.warn("expo-iap: 'inapp' product type is deprecated and will be removed in v3.1.0. Use 'in-app' instead.");
@@ -204,13 +205,10 @@ const offerToRecordIOS = (offer) => {
204
205
  timestamp: offer.timestamp.toString(),
205
206
  };
206
207
  };
207
- /**
208
- * Helper to normalize request props to platform-specific format
209
- */
210
- const normalizeRequestProps = (request, platform) => {
208
+ function normalizeRequestProps(request, platform) {
211
209
  // Platform-specific format - directly return the appropriate platform data
212
210
  return platform === 'ios' ? request.ios : request.android;
213
- };
211
+ }
214
212
  /**
215
213
  * Request a purchase for products or subscriptions.
216
214
  *
@@ -253,7 +251,7 @@ export const requestPurchase = (requestObj) => {
253
251
  }
254
252
  const { sku, andDangerouslyFinishTransactionAutomatically = false, appAccountToken, quantity, withOffer, } = normalizedRequest;
255
253
  return (async () => {
256
- const offer = offerToRecordIOS(withOffer);
254
+ const offer = offerToRecordIOS(withOffer ?? undefined);
257
255
  const purchase = await ExpoIapModule.requestPurchase({
258
256
  sku,
259
257
  andDangerouslyFinishTransactionAutomatically,
@@ -265,11 +263,11 @@ export const requestPurchase = (requestObj) => {
265
263
  })();
266
264
  }
267
265
  if (Platform.OS === 'android') {
268
- const normalizedRequest = normalizeRequestProps(request, 'android');
269
- if (!normalizedRequest?.skus?.length) {
270
- throw new Error('Invalid request for Android. The `skus` property is required and must be a non-empty array.');
271
- }
272
266
  if (isInAppPurchase) {
267
+ const normalizedRequest = normalizeRequestProps(request, 'android');
268
+ if (!normalizedRequest?.skus?.length) {
269
+ throw new Error('Invalid request for Android. The `skus` property is required and must be a non-empty array.');
270
+ }
273
271
  const { skus, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, isOfferPersonalized, } = normalizedRequest;
274
272
  return (async () => {
275
273
  return ExpoIapModule.requestPurchase({
@@ -285,16 +283,27 @@ export const requestPurchase = (requestObj) => {
285
283
  })();
286
284
  }
287
285
  if (canonical === 'subs') {
288
- const { skus, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, isOfferPersonalized, subscriptionOffers = [], replacementModeAndroid = -1, purchaseToken, } = normalizedRequest;
286
+ const normalizedRequest = normalizeRequestProps(request, 'android');
287
+ if (!normalizedRequest?.skus?.length) {
288
+ throw new Error('Invalid request for Android. The `skus` property is required and must be a non-empty array.');
289
+ }
290
+ const { skus, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, isOfferPersonalized, subscriptionOffers, replacementModeAndroid, purchaseTokenAndroid, } = normalizedRequest;
291
+ const normalizedOffers = subscriptionOffers ?? [];
292
+ const replacementMode = replacementModeAndroid ?? -1;
293
+ const purchaseToken = purchaseTokenAndroid ?? undefined;
289
294
  return (async () => {
290
295
  return ExpoIapModule.requestPurchase({
291
296
  type: native,
292
297
  skuArr: skus,
293
298
  purchaseToken,
294
- replacementMode: replacementModeAndroid,
299
+ replacementMode,
295
300
  obfuscatedAccountId: obfuscatedAccountIdAndroid,
296
301
  obfuscatedProfileId: obfuscatedProfileIdAndroid,
297
- offerTokenArr: subscriptionOffers.map((so) => so.offerToken),
302
+ offerTokenArr: normalizedOffers.map((so) => so.offerToken),
303
+ subscriptionOffers: normalizedOffers.map((so) => ({
304
+ sku: so.sku,
305
+ offerToken: so.offerToken,
306
+ })),
298
307
  isOfferPersonalized: isOfferPersonalized ?? false,
299
308
  });
300
309
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// External dependencies\nimport {NativeModulesProxy} from 'expo-modules-core';\nimport {Platform} from 'react-native';\n\n// Internal modules\nimport ExpoIapModule from './ExpoIapModule';\nimport {\n isProductIOS,\n validateReceiptIOS,\n deepLinkToSubscriptionsIOS,\n syncIOS,\n} from './modules/ios';\nimport {\n isProductAndroid,\n validateReceiptAndroid,\n deepLinkToSubscriptionsAndroid,\n} from './modules/android';\n\n// Types\nimport {\n Product,\n Purchase,\n ErrorCode,\n RequestPurchaseProps,\n RequestPurchasePropsByPlatforms,\n RequestSubscriptionPropsByPlatforms,\n ProductSubscription,\n PurchaseAndroid,\n DiscountOfferInputIOS,\n VoidResult,\n ReceiptValidationResult,\n} from './types';\nimport {PurchaseError} from './purchase-error';\n\n// Export all types\nexport * from './types';\nexport {ErrorCodeUtils, ErrorCodeMapping} from './purchase-error';\nexport * from './modules/android';\nexport * from './modules/ios';\n\n// Export subscription helpers\nexport {\n getActiveSubscriptions,\n hasActiveSubscriptions,\n} from './helpers/subscription';\n\n// Get the native constant value\nexport const PI = ExpoIapModule.PI;\n\nexport enum OpenIapEvent {\n PurchaseUpdated = 'purchase-updated',\n PurchaseError = 'purchase-error',\n PromotedProductIOS = 'promoted-product-ios',\n}\n\nexport function setValueAsync(value: string) {\n return ExpoIapModule.setValueAsync(value);\n}\n\n// Ensure the emitter has proper EventEmitter interface\nexport const emitter = (ExpoIapModule || NativeModulesProxy.ExpoIap) as {\n addListener: (\n eventName: string,\n listener: (...args: any[]) => void,\n ) => {remove: () => void};\n removeListener: (\n eventName: string,\n listener: (...args: any[]) => void,\n ) => void;\n};\n\n/**\n * TODO(v3.1.0): Remove legacy 'inapp' alias once downstream apps migrate to 'in-app'.\n */\nexport type ProductTypeInput = 'inapp' | 'in-app' | 'subs';\nexport type InAppTypeInput = Exclude<ProductTypeInput, 'subs'>;\n\ntype PurchaseRequestInApp = {\n request: RequestPurchasePropsByPlatforms;\n type?: InAppTypeInput;\n};\n\ntype PurchaseRequestSubscription = {\n request: RequestSubscriptionPropsByPlatforms;\n type: 'subs';\n};\n\nexport type PurchaseRequestInput =\n | PurchaseRequestInApp\n | PurchaseRequestSubscription;\n\nexport type PurchaseRequest =\n | {\n request: RequestPurchaseProps;\n type?: InAppTypeInput;\n }\n | {\n request: RequestSubscriptionPropsByPlatforms;\n type: 'subs';\n };\n\nconst normalizeProductType = (type?: ProductTypeInput) => {\n if (type === 'inapp') {\n console.warn(\n \"expo-iap: 'inapp' product type is deprecated and will be removed in v3.1.0. Use 'in-app' instead.\",\n );\n }\n\n if (!type || type === 'inapp' || type === 'in-app') {\n return {\n canonical: 'in-app' as const,\n native: 'inapp' as const,\n };\n }\n if (type === 'subs') {\n return {\n canonical: 'subs' as const,\n native: 'subs' as const,\n };\n }\n throw new Error(`Unsupported product type: ${type}`);\n};\n\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n) => {\n console.log('[JS] Registering purchaseUpdatedListener');\n const wrappedListener = (event: Purchase) => {\n console.log('[JS] purchaseUpdatedListener fired:', event);\n listener(event);\n };\n const emitterSubscription = emitter.addListener(\n OpenIapEvent.PurchaseUpdated,\n wrappedListener,\n );\n console.log('[JS] purchaseUpdatedListener registered successfully');\n return emitterSubscription;\n};\n\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n) => {\n console.log('[JS] Registering purchaseErrorListener');\n const wrappedListener = (error: PurchaseError) => {\n console.log('[JS] purchaseErrorListener fired:', error);\n listener(error);\n };\n const emitterSubscription = emitter.addListener(\n OpenIapEvent.PurchaseError,\n wrappedListener,\n );\n console.log('[JS] purchaseErrorListener registered successfully');\n return emitterSubscription;\n};\n\n/**\n * iOS-only listener for App Store promoted product events.\n * This fires when a user taps on a promoted product in the App Store.\n *\n * @param listener - Callback function that receives the promoted product details\n * @returns EventSubscription that can be used to unsubscribe\n *\n * @example\n * ```typescript\n * const subscription = promotedProductListenerIOS((product) => {\n * console.log('Promoted product:', product);\n * // Handle the promoted product\n * });\n *\n * // Later, clean up\n * subscription.remove();\n * ```\n *\n * @platform iOS\n */\nexport const promotedProductListenerIOS = (\n listener: (product: Product) => void,\n) => {\n if (Platform.OS !== 'ios') {\n console.warn(\n 'promotedProductListenerIOS: This listener is only available on iOS',\n );\n return {remove: () => {}};\n }\n return emitter.addListener(OpenIapEvent.PromotedProductIOS, listener);\n};\n\nexport function initConnection(): Promise<boolean> {\n const result = ExpoIapModule.initConnection();\n return Promise.resolve(result);\n}\n\nexport async function endConnection(): Promise<boolean> {\n return ExpoIapModule.endConnection();\n}\n\n/**\n * Fetch products with unified API (v2.7.0+)\n *\n * @param params - Product fetch configuration\n * @param params.skus - Array of product SKUs to fetch\n * @param params.type - Type of products: 'in-app' for regular products (default) or 'subs' for subscriptions\n *\n * @example\n * ```typescript\n * // Regular products\n * const products = await fetchProducts({\n * skus: ['product1', 'product2'],\n * type: 'in-app'\n * });\n *\n * // Subscriptions\n * const subscriptions = await fetchProducts({\n * skus: ['sub1', 'sub2'],\n * type: 'subs'\n * });\n * ```\n */\nexport const fetchProducts = async ({\n skus,\n type,\n}: {\n skus: string[];\n type?: ProductTypeInput;\n}): Promise<Product[] | ProductSubscription[]> => {\n if (!skus?.length) {\n throw new PurchaseError({\n message: 'No SKUs provided',\n code: ErrorCode.EmptySkuList,\n });\n }\n\n const {canonical, native} = normalizeProductType(type);\n\n if (Platform.OS === 'ios') {\n const rawItems = await ExpoIapModule.fetchProducts({skus, type: native});\n\n const filteredItems = rawItems.filter((item: unknown) => {\n if (!isProductIOS(item)) {\n return false;\n }\n const isValid =\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id);\n return isValid;\n });\n\n return canonical === 'in-app'\n ? (filteredItems as Product[])\n : (filteredItems as ProductSubscription[]);\n }\n\n if (Platform.OS === 'android') {\n const items = await ExpoIapModule.fetchProducts(native, skus);\n const filteredItems = items.filter((item: unknown) => {\n if (!isProductAndroid(item)) return false;\n return (\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id)\n );\n });\n\n return canonical === 'in-app'\n ? (filteredItems as Product[])\n : (filteredItems as ProductSubscription[]);\n }\n\n throw new Error('Unsupported platform');\n};\n\nexport const getAvailablePurchases = ({\n alsoPublishToEventListenerIOS = false,\n onlyIncludeActiveItemsIOS = true,\n}: {\n alsoPublishToEventListenerIOS?: boolean;\n onlyIncludeActiveItemsIOS?: boolean;\n} = {}): Promise<Purchase[]> =>\n (\n Platform.select({\n ios: () =>\n ExpoIapModule.getAvailableItems(\n alsoPublishToEventListenerIOS,\n onlyIncludeActiveItemsIOS,\n ),\n android: () => ExpoIapModule.getAvailableItems(),\n }) || (() => Promise.resolve([]))\n )();\n\n/**\n * Restore completed transactions (cross-platform behavior)\n *\n * - iOS: perform a lightweight sync to refresh transactions and ignore sync errors,\n * then fetch available purchases to surface restored items to the app.\n * - Android: simply fetch available purchases (restoration happens via query).\n *\n * This helper returns the restored/available purchases so callers can update UI/state.\n *\n * @param options.alsoPublishToEventListenerIOS - iOS only: whether to also publish to the event listener\n * @param options.onlyIncludeActiveItemsIOS - iOS only: whether to only include active items\n * @returns Promise resolving to the list of available/restored purchases\n */\nexport const restorePurchases = async (\n options: {\n alsoPublishToEventListenerIOS?: boolean;\n onlyIncludeActiveItemsIOS?: boolean;\n } = {},\n): Promise<Purchase[]> => {\n if (Platform.OS === 'ios') {\n // Perform best-effort sync on iOS and ignore sync errors to avoid blocking restore flow\n await syncIOS().catch(() => undefined);\n }\n\n // Then, fetch available purchases for both platforms\n const purchases = await getAvailablePurchases({\n alsoPublishToEventListenerIOS:\n options.alsoPublishToEventListenerIOS ?? false,\n onlyIncludeActiveItemsIOS: options.onlyIncludeActiveItemsIOS ?? true,\n });\n\n return purchases;\n};\n\nconst offerToRecordIOS = (\n offer: DiscountOfferInputIOS | undefined,\n): Record<keyof DiscountOfferInputIOS, string> | undefined => {\n if (!offer) return undefined;\n return {\n identifier: offer.identifier,\n keyIdentifier: offer.keyIdentifier,\n nonce: offer.nonce,\n signature: offer.signature,\n timestamp: offer.timestamp.toString(),\n };\n};\n\n/**\n * Helper to normalize request props to platform-specific format\n */\nconst normalizeRequestProps = (\n request:\n | RequestPurchasePropsByPlatforms\n | RequestSubscriptionPropsByPlatforms,\n platform: 'ios' | 'android',\n): any => {\n // Platform-specific format - directly return the appropriate platform data\n return platform === 'ios' ? request.ios : request.android;\n};\n\n/**\n * Request a purchase for products or subscriptions.\n *\n * @param requestObj - Purchase request configuration\n * @param requestObj.request - Platform-specific purchase parameters\n * @param requestObj.type - Type of purchase: 'in-app' for products (default) or 'subs' for subscriptions\n *\n * @example\n * ```typescript\n * // Product purchase\n * await requestPurchase({\n * request: {\n * ios: { sku: productId },\n * android: { skus: [productId] }\n * },\n * type: 'in-app'\n * });\n *\n * // Subscription purchase\n * await requestPurchase({\n * request: {\n * ios: { sku: subscriptionId },\n * android: {\n * skus: [subscriptionId],\n * subscriptionOffers: [{ sku: subscriptionId, offerToken: 'token' }]\n * }\n * },\n * type: 'subs'\n * });\n * ```\n */\nexport const requestPurchase = (\n requestObj: PurchaseRequestInput,\n): Promise<Purchase | Purchase[] | void> => {\n const {request, type} = requestObj;\n const {canonical, native} = normalizeProductType(type);\n const isInAppPurchase = canonical === 'in-app';\n\n if (Platform.OS === 'ios') {\n const normalizedRequest = normalizeRequestProps(request, 'ios');\n\n if (!normalizedRequest?.sku) {\n throw new Error(\n 'Invalid request for iOS. The `sku` property is required and must be a string.',\n );\n }\n\n const {\n sku,\n andDangerouslyFinishTransactionAutomatically = false,\n appAccountToken,\n quantity,\n withOffer,\n } = normalizedRequest;\n\n return (async () => {\n const offer = offerToRecordIOS(withOffer);\n const purchase = await ExpoIapModule.requestPurchase({\n sku,\n andDangerouslyFinishTransactionAutomatically,\n appAccountToken,\n quantity,\n withOffer: offer,\n });\n\n return purchase as Purchase;\n })();\n }\n\n if (Platform.OS === 'android') {\n const normalizedRequest = normalizeRequestProps(request, 'android');\n\n if (!normalizedRequest?.skus?.length) {\n throw new Error(\n 'Invalid request for Android. The `skus` property is required and must be a non-empty array.',\n );\n }\n\n if (isInAppPurchase) {\n const {\n skus,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n isOfferPersonalized,\n } = normalizedRequest;\n\n return (async () => {\n return ExpoIapModule.requestPurchase({\n type: native,\n skuArr: skus,\n purchaseToken: undefined,\n replacementMode: -1,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: [],\n isOfferPersonalized: isOfferPersonalized ?? false,\n }) as Promise<Purchase[]>;\n })();\n }\n\n if (canonical === 'subs') {\n const {\n skus,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n isOfferPersonalized,\n subscriptionOffers = [],\n replacementModeAndroid = -1,\n purchaseToken,\n } = normalizedRequest;\n\n return (async () => {\n return ExpoIapModule.requestPurchase({\n type: native,\n skuArr: skus,\n purchaseToken,\n replacementMode: replacementModeAndroid,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: subscriptionOffers.map((so: any) => so.offerToken),\n isOfferPersonalized: isOfferPersonalized ?? false,\n }) as Promise<Purchase[]>;\n })();\n }\n\n throw new Error(\n \"Invalid request for Android: Expected a valid request object with 'skus' array.\",\n );\n }\n\n return Promise.resolve(); // Fallback for unsupported platforms\n};\n\nexport const finishTransaction = ({\n purchase,\n isConsumable = false,\n}: {\n purchase: Purchase;\n isConsumable?: boolean;\n}): Promise<VoidResult | boolean> => {\n return (\n Platform.select({\n ios: async () => {\n const transactionId = purchase.id;\n if (!transactionId) {\n return Promise.reject(\n new Error('purchase.id required to finish iOS transaction'),\n );\n }\n await ExpoIapModule.finishTransaction(transactionId);\n return Promise.resolve(true);\n },\n android: async () => {\n const androidPurchase = purchase as PurchaseAndroid;\n\n // Use purchaseToken if available, fallback to purchaseTokenAndroid for backward compatibility\n const token = androidPurchase.purchaseToken;\n\n if (!token) {\n return Promise.reject(\n new PurchaseError({\n message: 'Purchase token is required to finish transaction',\n code: ErrorCode.DeveloperError,\n productId: androidPurchase.productId,\n platform: 'android',\n }),\n );\n }\n\n if (isConsumable) {\n return ExpoIapModule.consumePurchaseAndroid(token);\n }\n\n return ExpoIapModule.acknowledgePurchaseAndroid(token);\n },\n }) || (() => Promise.reject(new Error('Unsupported Platform')))\n )();\n};\n\n/**\n * Retrieves the current storefront information from iOS App Store\n *\n * @returns Promise resolving to the storefront country code\n * @throws Error if called on non-iOS platform\n *\n * @example\n * ```typescript\n * const storefront = await getStorefrontIOS();\n * console.log(storefront); // 'US'\n * ```\n *\n * @platform iOS\n */\nexport const getStorefrontIOS = (): Promise<string> => {\n if (Platform.OS !== 'ios') {\n console.warn('getStorefrontIOS: This method is only available on iOS');\n return Promise.resolve('');\n }\n return ExpoIapModule.getStorefrontIOS();\n};\n\n/**\n * Gets the storefront country code from the underlying native store.\n * Returns a two-letter country code such as 'US', 'KR', or empty string on failure.\n *\n * @platform ios\n * @platform android\n */\nexport const getStorefront = (): Promise<string> => {\n // Cross-platform storefront\n if (Platform.OS === 'android') {\n if (typeof (ExpoIapModule as any).getStorefrontAndroid === 'function') {\n return (ExpoIapModule as any).getStorefrontAndroid();\n }\n return Promise.resolve('');\n }\n return getStorefrontIOS();\n};\n\n/**\n * Internal receipt validation function (NOT RECOMMENDED for production use)\n *\n * WARNING: This function performs client-side validation which is NOT secure.\n * For production apps, always validate receipts on your secure server:\n * - iOS: Send receipt data to Apple's verification endpoint from your server\n * - Android: Use Google Play Developer API with service account credentials\n */\nexport const validateReceipt = async (\n sku: string,\n androidOptions?: {\n packageName: string;\n productToken: string;\n accessToken: string;\n isSub?: boolean;\n },\n): Promise<ReceiptValidationResult> => {\n if (Platform.OS === 'ios') {\n return await validateReceiptIOS(sku);\n } else if (Platform.OS === 'android') {\n if (\n !androidOptions ||\n !androidOptions.packageName ||\n !androidOptions.productToken ||\n !androidOptions.accessToken\n ) {\n throw new Error(\n 'Android validation requires packageName, productToken, and accessToken',\n );\n }\n return await validateReceiptAndroid({\n packageName: androidOptions.packageName,\n productId: sku,\n productToken: androidOptions.productToken,\n accessToken: androidOptions.accessToken,\n isSub: androidOptions.isSub,\n });\n } else {\n throw new Error('Platform not supported');\n }\n};\n\n/**\n * Deeplinks to native interface that allows users to manage their subscriptions\n * @param options.skuAndroid - Required for Android to locate specific subscription (ignored on iOS)\n * @param options.packageNameAndroid - Required for Android to identify your app (ignored on iOS)\n *\n * @returns Promise that resolves when the deep link is successfully opened\n *\n * @throws {Error} When called on unsupported platform or when required Android parameters are missing\n *\n * @example\n * import { deepLinkToSubscriptions } from 'expo-iap';\n *\n * // Works on both iOS and Android\n * await deepLinkToSubscriptions({\n * skuAndroid: 'your_subscription_sku',\n * packageNameAndroid: 'com.example.app'\n * });\n */\nexport const deepLinkToSubscriptions = (options: {\n skuAndroid?: string;\n packageNameAndroid?: string;\n}): Promise<void> => {\n if (Platform.OS === 'ios') {\n return deepLinkToSubscriptionsIOS();\n }\n\n if (Platform.OS === 'android') {\n return deepLinkToSubscriptionsAndroid({\n sku: options?.skuAndroid,\n packageName: options?.packageNameAndroid,\n });\n }\n\n return Promise.reject(new Error(`Unsupported platform: ${Platform.OS}`));\n};\n\nexport * from './useIAP';\nexport * from './utils/errorMapping';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,OAAO,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AAEtC,mBAAmB;AACnB,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,0BAA0B,EAC1B,OAAO,GACR,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAE3B,QAAQ;AACR,OAAO,EAGL,SAAS,GAcV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAE/C,mBAAmB;AACnB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAC,cAAc,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAClE,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAE9B,8BAA8B;AAC9B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,gCAAgC;AAChC,MAAM,CAAC,MAAM,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC;AAEnC,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,oDAAoC,CAAA;IACpC,gDAAgC,CAAA;IAChC,2DAA2C,CAAA;AAC7C,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAuBD,uDAAuD;AACvD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,aAAa;IACnC,kBAAkB,CAAC,OAAO,CAAmB,CAAC;AAgChD,MAAM,oBAAoB,GAAG,CAAC,IAAuB,EAAE,EAAE;IACvD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,mGAAmG,CACpG,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACnD,OAAO;YACL,SAAS,EAAE,QAAiB;YAC5B,MAAM,EAAE,OAAgB;SACzB,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO;YACL,SAAS,EAAE,MAAe;YAC1B,MAAM,EAAE,MAAe;SACxB,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,QAAmC,EACnC,EAAE;IACF,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,CAAC,KAAe,EAAE,EAAE;QAC1C,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;QAC1D,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,MAAM,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAC7C,YAAY,CAAC,eAAe,EAC5B,eAAe,CAChB,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACpE,OAAO,mBAAmB,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,QAAwC,EACxC,EAAE;IACF,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,CAAC,KAAoB,EAAE,EAAE;QAC/C,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QACxD,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,MAAM,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAC7C,YAAY,CAAC,aAAa,EAC1B,eAAe,CAChB,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAClE,OAAO,mBAAmB,CAAC;AAC7B,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,QAAoC,EACpC,EAAE;IACF,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CACV,oEAAoE,CACrE,CAAC;QACF,OAAO,EAAC,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,EAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,EAAE,CAAC;IAC9C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,aAAa,CAAC,aAAa,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,IAAI,EACJ,IAAI,GAIL,EAA8C,EAAE;IAC/C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,aAAa,CAAC;YACtB,OAAO,EAAE,kBAAkB;YAC3B,IAAI,EAAE,SAAS,CAAC,YAAY;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAC,SAAS,EAAE,MAAM,EAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAEvD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,EAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,CAAC,CAAC;QAEzE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAa,EAAE,EAAE;YACtD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,OAAO,GACX,OAAO,IAAI,KAAK,QAAQ;gBACxB,IAAI,KAAK,IAAI;gBACb,IAAI,IAAI,IAAI;gBACZ,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;gBAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzB,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,OAAO,SAAS,KAAK,QAAQ;YAC3B,CAAC,CAAE,aAA2B;YAC9B,CAAC,CAAE,aAAuC,CAAC;IAC/C,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9D,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAa,EAAE,EAAE;YACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC1C,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;gBACxB,IAAI,KAAK,IAAI;gBACb,IAAI,IAAI,IAAI;gBACZ,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;gBAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CACvB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,SAAS,KAAK,QAAQ;YAC3B,CAAC,CAAE,aAA2B;YAC9B,CAAC,CAAE,aAAuC,CAAC;IAC/C,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EACpC,6BAA6B,GAAG,KAAK,EACrC,yBAAyB,GAAG,IAAI,MAI9B,EAAE,EAAuB,EAAE,CAC7B,CACE,QAAQ,CAAC,MAAM,CAAC;IACd,GAAG,EAAE,GAAG,EAAE,CACR,aAAa,CAAC,iBAAiB,CAC7B,6BAA6B,EAC7B,yBAAyB,CAC1B;IACH,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE;CACjD,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAClC,EAAE,CAAC;AAEN;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,UAGI,EAAE,EACe,EAAE;IACvB,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,wFAAwF;QACxF,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,qDAAqD;IACrD,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC;QAC5C,6BAA6B,EAC3B,OAAO,CAAC,6BAA6B,IAAI,KAAK;QAChD,yBAAyB,EAAE,OAAO,CAAC,yBAAyB,IAAI,IAAI;KACrE,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CACvB,KAAwC,EACiB,EAAE;IAC3D,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE;KACtC,CAAC;AACJ,CAAC,CAAC;AAqBF,SAAS,qBAAqB,CAC5B,OAEuC,EACvC,QAA2B;IAE3B,2EAA2E;IAC3E,OAAO,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,UAAgC,EACO,EAAE;IACzC,MAAM,EAAC,OAAO,EAAE,IAAI,EAAC,GAAG,UAAU,CAAC;IACnC,MAAM,EAAC,SAAS,EAAE,MAAM,EAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,eAAe,GAAG,SAAS,KAAK,QAAQ,CAAC;IAE/C,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAEhE,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;QACJ,CAAC;QAED,MAAM,EACJ,GAAG,EACH,4CAA4C,GAAG,KAAK,EACpD,eAAe,EACf,QAAQ,EACR,SAAS,GACV,GAAG,iBAAiB,CAAC;QAEtB,OAAO,CAAC,KAAK,IAAI,EAAE;YACjB,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,eAAe,CAAC;gBACnD,GAAG;gBACH,4CAA4C;gBAC5C,eAAe;gBACf,QAAQ;gBACR,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,OAAO,QAAoB,CAAC;QAC9B,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,iBAAiB,GACrB,qBAAqB,CACnB,OAA0C,EAC1C,SAAS,CACV,CAAC;YAEJ,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;YACJ,CAAC;YAED,MAAM,EACJ,IAAI,EACJ,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,GACpB,GAAG,iBAAiB,CAAC;YAEtB,OAAO,CAAC,KAAK,IAAI,EAAE;gBACjB,OAAO,aAAa,CAAC,eAAe,CAAC;oBACnC,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,IAAI;oBACZ,aAAa,EAAE,SAAS;oBACxB,eAAe,EAAE,CAAC,CAAC;oBACnB,mBAAmB,EAAE,0BAA0B;oBAC/C,mBAAmB,EAAE,0BAA0B;oBAC/C,aAAa,EAAE,EAAE;oBACjB,mBAAmB,EAAE,mBAAmB,IAAI,KAAK;iBAClD,CAAwB,CAAC;YAC5B,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QAED,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,iBAAiB,GAGP,qBAAqB,CACnC,OAA8C,EAC9C,SAAS,CACV,CAAC;YAEF,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;YACJ,CAAC;YAED,MAAM,EACJ,IAAI,EACJ,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,GAAG,iBAAiB,CAAC;YAEtB,MAAM,gBAAgB,GAAG,kBAAkB,IAAI,EAAE,CAAC;YAClD,MAAM,eAAe,GAAG,sBAAsB,IAAI,CAAC,CAAC,CAAC;YACrD,MAAM,aAAa,GAAG,oBAAoB,IAAI,SAAS,CAAC;YAExD,OAAO,CAAC,KAAK,IAAI,EAAE;gBACjB,OAAO,aAAa,CAAC,eAAe,CAAC;oBACnC,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,IAAI;oBACZ,aAAa;oBACb,eAAe;oBACf,mBAAmB,EAAE,0BAA0B;oBAC/C,mBAAmB,EAAE,0BAA0B;oBAC/C,aAAa,EAAE,gBAAgB,CAAC,GAAG,CACjC,CAAC,EAAiC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CACrD;oBACD,kBAAkB,EAAE,gBAAgB,CAAC,GAAG,CACtC,CAAC,EAAiC,EAAE,EAAE,CAAC,CAAC;wBACtC,GAAG,EAAE,EAAE,CAAC,GAAG;wBACX,UAAU,EAAE,EAAE,CAAC,UAAU;qBAC1B,CAAC,CACH;oBACD,mBAAmB,EAAE,mBAAmB,IAAI,KAAK;iBAClD,CAAwB,CAAC;YAC5B,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QAED,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,qCAAqC;AACjE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAChC,QAAQ,EACR,YAAY,GAAG,KAAK,GAIrB,EAAiC,EAAE;IAClC,OAAO,CACL,QAAQ,CAAC,MAAM,CAAC;QACd,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,MAAM,aAAa,GAAG,QAAQ,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAC5D,CAAC;YACJ,CAAC;YACD,MAAM,aAAa,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;YACrD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,eAAe,GAAG,QAA2B,CAAC;YAEpD,8FAA8F;YAC9F,MAAM,KAAK,GAAG,eAAe,CAAC,aAAa,CAAC;YAE5C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,aAAa,CAAC;oBAChB,OAAO,EAAE,kDAAkD;oBAC3D,IAAI,EAAE,SAAS,CAAC,cAAc;oBAC9B,SAAS,EAAE,eAAe,CAAC,SAAS;oBACpC,QAAQ,EAAE,SAAS;iBACpB,CAAC,CACH,CAAC;YACJ,CAAC;YAED,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,aAAa,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,aAAa,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;KACF,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAChE,EAAE,CAAC;AACN,CAAC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAoB,EAAE;IACpD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;QACvE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,aAAa,CAAC,gBAAgB,EAAE,CAAC;AAC1C,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAoB,EAAE;IACjD,4BAA4B;IAC5B,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,OAAO,aAAa,CAAC,oBAAoB,KAAK,UAAU,EAAE,CAAC;YAC7D,OAAO,aAAa,CAAC,oBAAoB,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,gBAAgB,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,GAAW,EACX,cAKC,EACiC,EAAE;IACpC,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;SAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QACrC,IACE,CAAC,cAAc;YACf,CAAC,cAAc,CAAC,WAAW;YAC3B,CAAC,cAAc,CAAC,YAAY;YAC5B,CAAC,cAAc,CAAC,WAAW,EAC3B,CAAC;YACD,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,sBAAsB,CAAC;YAClC,WAAW,EAAE,cAAc,CAAC,WAAW;YACvC,SAAS,EAAE,GAAG;YACd,YAAY,EAAE,cAAc,CAAC,YAAY;YACzC,WAAW,EAAE,cAAc,CAAC,WAAW;YACvC,KAAK,EAAE,cAAc,CAAC,KAAK;SAC5B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,OAGvC,EAAiB,EAAE;IAClB,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,0BAA0B,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,8BAA8B,CAAC;YACpC,GAAG,EAAE,OAAO,EAAE,UAAU;YACxB,WAAW,EAAE,OAAO,EAAE,kBAAkB;SACzC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC","sourcesContent":["// External dependencies\nimport {NativeModulesProxy} from 'expo-modules-core';\nimport {Platform} from 'react-native';\n\n// Internal modules\nimport ExpoIapModule from './ExpoIapModule';\nimport {\n isProductIOS,\n validateReceiptIOS,\n deepLinkToSubscriptionsIOS,\n syncIOS,\n} from './modules/ios';\nimport {\n isProductAndroid,\n validateReceiptAndroid,\n deepLinkToSubscriptionsAndroid,\n} from './modules/android';\n\n// Types\nimport {\n Product,\n Purchase,\n ErrorCode,\n RequestPurchaseProps,\n RequestPurchasePropsByPlatforms,\n RequestPurchaseAndroidProps,\n RequestPurchaseIosProps,\n RequestSubscriptionPropsByPlatforms,\n RequestSubscriptionAndroidProps,\n RequestSubscriptionIosProps,\n ProductSubscription,\n PurchaseAndroid,\n DiscountOfferInputIOS,\n VoidResult,\n ReceiptValidationResult,\n AndroidSubscriptionOfferInput,\n} from './types';\nimport {PurchaseError} from './purchase-error';\n\n// Export all types\nexport * from './types';\nexport {ErrorCodeUtils, ErrorCodeMapping} from './purchase-error';\nexport * from './modules/android';\nexport * from './modules/ios';\n\n// Export subscription helpers\nexport {\n getActiveSubscriptions,\n hasActiveSubscriptions,\n} from './helpers/subscription';\n\n// Get the native constant value\nexport const PI = ExpoIapModule.PI;\n\nexport enum OpenIapEvent {\n PurchaseUpdated = 'purchase-updated',\n PurchaseError = 'purchase-error',\n PromotedProductIOS = 'promoted-product-ios',\n}\n\nexport function setValueAsync(value: string) {\n return ExpoIapModule.setValueAsync(value);\n}\n\ntype ExpoIapEventPayloads = {\n [OpenIapEvent.PurchaseUpdated]: Purchase;\n [OpenIapEvent.PurchaseError]: PurchaseError;\n [OpenIapEvent.PromotedProductIOS]: Product;\n};\n\ntype ExpoIapEventListener<E extends OpenIapEvent> = (\n payload: ExpoIapEventPayloads[E],\n) => void;\n\ntype ExpoIapEmitter = {\n addListener<E extends OpenIapEvent>(\n eventName: E,\n listener: ExpoIapEventListener<E>,\n ): {remove: () => void};\n removeListener<E extends OpenIapEvent>(\n eventName: E,\n listener: ExpoIapEventListener<E>,\n ): void;\n};\n\n// Ensure the emitter has proper EventEmitter interface\nexport const emitter = (ExpoIapModule ||\n NativeModulesProxy.ExpoIap) as ExpoIapEmitter;\n\n/**\n * TODO(v3.1.0): Remove legacy 'inapp' alias once downstream apps migrate to 'in-app'.\n */\nexport type ProductTypeInput = 'inapp' | 'in-app' | 'subs';\nexport type InAppTypeInput = Exclude<ProductTypeInput, 'subs'>;\n\ntype PurchaseRequestInApp = {\n request: RequestPurchasePropsByPlatforms;\n type?: InAppTypeInput;\n};\n\ntype PurchaseRequestSubscription = {\n request: RequestSubscriptionPropsByPlatforms;\n type: 'subs';\n};\n\nexport type PurchaseRequestInput =\n | PurchaseRequestInApp\n | PurchaseRequestSubscription;\n\nexport type PurchaseRequest =\n | {\n request: RequestPurchaseProps;\n type?: InAppTypeInput;\n }\n | {\n request: RequestSubscriptionPropsByPlatforms;\n type: 'subs';\n };\n\nconst normalizeProductType = (type?: ProductTypeInput) => {\n if (type === 'inapp') {\n console.warn(\n \"expo-iap: 'inapp' product type is deprecated and will be removed in v3.1.0. Use 'in-app' instead.\",\n );\n }\n\n if (!type || type === 'inapp' || type === 'in-app') {\n return {\n canonical: 'in-app' as const,\n native: 'inapp' as const,\n };\n }\n if (type === 'subs') {\n return {\n canonical: 'subs' as const,\n native: 'subs' as const,\n };\n }\n throw new Error(`Unsupported product type: ${type}`);\n};\n\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n) => {\n console.log('[JS] Registering purchaseUpdatedListener');\n const wrappedListener = (event: Purchase) => {\n console.log('[JS] purchaseUpdatedListener fired:', event);\n listener(event);\n };\n const emitterSubscription = emitter.addListener(\n OpenIapEvent.PurchaseUpdated,\n wrappedListener,\n );\n console.log('[JS] purchaseUpdatedListener registered successfully');\n return emitterSubscription;\n};\n\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n) => {\n console.log('[JS] Registering purchaseErrorListener');\n const wrappedListener = (error: PurchaseError) => {\n console.log('[JS] purchaseErrorListener fired:', error);\n listener(error);\n };\n const emitterSubscription = emitter.addListener(\n OpenIapEvent.PurchaseError,\n wrappedListener,\n );\n console.log('[JS] purchaseErrorListener registered successfully');\n return emitterSubscription;\n};\n\n/**\n * iOS-only listener for App Store promoted product events.\n * This fires when a user taps on a promoted product in the App Store.\n *\n * @param listener - Callback function that receives the promoted product details\n * @returns EventSubscription that can be used to unsubscribe\n *\n * @example\n * ```typescript\n * const subscription = promotedProductListenerIOS((product) => {\n * console.log('Promoted product:', product);\n * // Handle the promoted product\n * });\n *\n * // Later, clean up\n * subscription.remove();\n * ```\n *\n * @platform iOS\n */\nexport const promotedProductListenerIOS = (\n listener: (product: Product) => void,\n) => {\n if (Platform.OS !== 'ios') {\n console.warn(\n 'promotedProductListenerIOS: This listener is only available on iOS',\n );\n return {remove: () => {}};\n }\n return emitter.addListener(OpenIapEvent.PromotedProductIOS, listener);\n};\n\nexport function initConnection(): Promise<boolean> {\n const result = ExpoIapModule.initConnection();\n return Promise.resolve(result);\n}\n\nexport async function endConnection(): Promise<boolean> {\n return ExpoIapModule.endConnection();\n}\n\n/**\n * Fetch products with unified API (v2.7.0+)\n *\n * @param params - Product fetch configuration\n * @param params.skus - Array of product SKUs to fetch\n * @param params.type - Type of products: 'in-app' for regular products (default) or 'subs' for subscriptions\n *\n * @example\n * ```typescript\n * // Regular products\n * const products = await fetchProducts({\n * skus: ['product1', 'product2'],\n * type: 'in-app'\n * });\n *\n * // Subscriptions\n * const subscriptions = await fetchProducts({\n * skus: ['sub1', 'sub2'],\n * type: 'subs'\n * });\n * ```\n */\nexport const fetchProducts = async ({\n skus,\n type,\n}: {\n skus: string[];\n type?: ProductTypeInput;\n}): Promise<Product[] | ProductSubscription[]> => {\n if (!skus?.length) {\n throw new PurchaseError({\n message: 'No SKUs provided',\n code: ErrorCode.EmptySkuList,\n });\n }\n\n const {canonical, native} = normalizeProductType(type);\n\n if (Platform.OS === 'ios') {\n const rawItems = await ExpoIapModule.fetchProducts({skus, type: native});\n\n const filteredItems = rawItems.filter((item: unknown) => {\n if (!isProductIOS(item)) {\n return false;\n }\n const isValid =\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id);\n return isValid;\n });\n\n return canonical === 'in-app'\n ? (filteredItems as Product[])\n : (filteredItems as ProductSubscription[]);\n }\n\n if (Platform.OS === 'android') {\n const items = await ExpoIapModule.fetchProducts(native, skus);\n const filteredItems = items.filter((item: unknown) => {\n if (!isProductAndroid(item)) return false;\n return (\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id)\n );\n });\n\n return canonical === 'in-app'\n ? (filteredItems as Product[])\n : (filteredItems as ProductSubscription[]);\n }\n\n throw new Error('Unsupported platform');\n};\n\nexport const getAvailablePurchases = ({\n alsoPublishToEventListenerIOS = false,\n onlyIncludeActiveItemsIOS = true,\n}: {\n alsoPublishToEventListenerIOS?: boolean;\n onlyIncludeActiveItemsIOS?: boolean;\n} = {}): Promise<Purchase[]> =>\n (\n Platform.select({\n ios: () =>\n ExpoIapModule.getAvailableItems(\n alsoPublishToEventListenerIOS,\n onlyIncludeActiveItemsIOS,\n ),\n android: () => ExpoIapModule.getAvailableItems(),\n }) || (() => Promise.resolve([]))\n )();\n\n/**\n * Restore completed transactions (cross-platform behavior)\n *\n * - iOS: perform a lightweight sync to refresh transactions and ignore sync errors,\n * then fetch available purchases to surface restored items to the app.\n * - Android: simply fetch available purchases (restoration happens via query).\n *\n * This helper returns the restored/available purchases so callers can update UI/state.\n *\n * @param options.alsoPublishToEventListenerIOS - iOS only: whether to also publish to the event listener\n * @param options.onlyIncludeActiveItemsIOS - iOS only: whether to only include active items\n * @returns Promise resolving to the list of available/restored purchases\n */\nexport const restorePurchases = async (\n options: {\n alsoPublishToEventListenerIOS?: boolean;\n onlyIncludeActiveItemsIOS?: boolean;\n } = {},\n): Promise<Purchase[]> => {\n if (Platform.OS === 'ios') {\n // Perform best-effort sync on iOS and ignore sync errors to avoid blocking restore flow\n await syncIOS().catch(() => undefined);\n }\n\n // Then, fetch available purchases for both platforms\n const purchases = await getAvailablePurchases({\n alsoPublishToEventListenerIOS:\n options.alsoPublishToEventListenerIOS ?? false,\n onlyIncludeActiveItemsIOS: options.onlyIncludeActiveItemsIOS ?? true,\n });\n\n return purchases;\n};\n\nconst offerToRecordIOS = (\n offer: DiscountOfferInputIOS | undefined,\n): Record<keyof DiscountOfferInputIOS, string> | undefined => {\n if (!offer) return undefined;\n return {\n identifier: offer.identifier,\n keyIdentifier: offer.keyIdentifier,\n nonce: offer.nonce,\n signature: offer.signature,\n timestamp: offer.timestamp.toString(),\n };\n};\n\n/**\n * Helper to normalize request props to platform-specific format\n */\nfunction normalizeRequestProps(\n request: RequestPurchasePropsByPlatforms,\n platform: 'ios',\n): RequestPurchaseIosProps | null | undefined;\nfunction normalizeRequestProps(\n request: RequestPurchasePropsByPlatforms,\n platform: 'android',\n): RequestPurchaseAndroidProps | null | undefined;\nfunction normalizeRequestProps(\n request: RequestSubscriptionPropsByPlatforms,\n platform: 'ios',\n): RequestSubscriptionIosProps | null | undefined;\nfunction normalizeRequestProps(\n request: RequestSubscriptionPropsByPlatforms,\n platform: 'android',\n): RequestSubscriptionAndroidProps | null | undefined;\nfunction normalizeRequestProps(\n request:\n | RequestPurchasePropsByPlatforms\n | RequestSubscriptionPropsByPlatforms,\n platform: 'ios' | 'android',\n) {\n // Platform-specific format - directly return the appropriate platform data\n return platform === 'ios' ? request.ios : request.android;\n}\n\n/**\n * Request a purchase for products or subscriptions.\n *\n * @param requestObj - Purchase request configuration\n * @param requestObj.request - Platform-specific purchase parameters\n * @param requestObj.type - Type of purchase: 'in-app' for products (default) or 'subs' for subscriptions\n *\n * @example\n * ```typescript\n * // Product purchase\n * await requestPurchase({\n * request: {\n * ios: { sku: productId },\n * android: { skus: [productId] }\n * },\n * type: 'in-app'\n * });\n *\n * // Subscription purchase\n * await requestPurchase({\n * request: {\n * ios: { sku: subscriptionId },\n * android: {\n * skus: [subscriptionId],\n * subscriptionOffers: [{ sku: subscriptionId, offerToken: 'token' }]\n * }\n * },\n * type: 'subs'\n * });\n * ```\n */\nexport const requestPurchase = (\n requestObj: PurchaseRequestInput,\n): Promise<Purchase | Purchase[] | void> => {\n const {request, type} = requestObj;\n const {canonical, native} = normalizeProductType(type);\n const isInAppPurchase = canonical === 'in-app';\n\n if (Platform.OS === 'ios') {\n const normalizedRequest = normalizeRequestProps(request, 'ios');\n\n if (!normalizedRequest?.sku) {\n throw new Error(\n 'Invalid request for iOS. The `sku` property is required and must be a string.',\n );\n }\n\n const {\n sku,\n andDangerouslyFinishTransactionAutomatically = false,\n appAccountToken,\n quantity,\n withOffer,\n } = normalizedRequest;\n\n return (async () => {\n const offer = offerToRecordIOS(withOffer ?? undefined);\n const purchase = await ExpoIapModule.requestPurchase({\n sku,\n andDangerouslyFinishTransactionAutomatically,\n appAccountToken,\n quantity,\n withOffer: offer,\n });\n\n return purchase as Purchase;\n })();\n }\n\n if (Platform.OS === 'android') {\n if (isInAppPurchase) {\n const normalizedRequest: RequestPurchaseAndroidProps | null | undefined =\n normalizeRequestProps(\n request as RequestPurchasePropsByPlatforms,\n 'android',\n );\n\n if (!normalizedRequest?.skus?.length) {\n throw new Error(\n 'Invalid request for Android. The `skus` property is required and must be a non-empty array.',\n );\n }\n\n const {\n skus,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n isOfferPersonalized,\n } = normalizedRequest;\n\n return (async () => {\n return ExpoIapModule.requestPurchase({\n type: native,\n skuArr: skus,\n purchaseToken: undefined,\n replacementMode: -1,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: [],\n isOfferPersonalized: isOfferPersonalized ?? false,\n }) as Promise<Purchase[]>;\n })();\n }\n\n if (canonical === 'subs') {\n const normalizedRequest:\n | RequestSubscriptionAndroidProps\n | null\n | undefined = normalizeRequestProps(\n request as RequestSubscriptionPropsByPlatforms,\n 'android',\n );\n\n if (!normalizedRequest?.skus?.length) {\n throw new Error(\n 'Invalid request for Android. The `skus` property is required and must be a non-empty array.',\n );\n }\n\n const {\n skus,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n isOfferPersonalized,\n subscriptionOffers,\n replacementModeAndroid,\n purchaseTokenAndroid,\n } = normalizedRequest;\n\n const normalizedOffers = subscriptionOffers ?? [];\n const replacementMode = replacementModeAndroid ?? -1;\n const purchaseToken = purchaseTokenAndroid ?? undefined;\n\n return (async () => {\n return ExpoIapModule.requestPurchase({\n type: native,\n skuArr: skus,\n purchaseToken,\n replacementMode,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: normalizedOffers.map(\n (so: AndroidSubscriptionOfferInput) => so.offerToken,\n ),\n subscriptionOffers: normalizedOffers.map(\n (so: AndroidSubscriptionOfferInput) => ({\n sku: so.sku,\n offerToken: so.offerToken,\n }),\n ),\n isOfferPersonalized: isOfferPersonalized ?? false,\n }) as Promise<Purchase[]>;\n })();\n }\n\n throw new Error(\n \"Invalid request for Android: Expected a valid request object with 'skus' array.\",\n );\n }\n\n return Promise.resolve(); // Fallback for unsupported platforms\n};\n\nexport const finishTransaction = ({\n purchase,\n isConsumable = false,\n}: {\n purchase: Purchase;\n isConsumable?: boolean;\n}): Promise<VoidResult | boolean> => {\n return (\n Platform.select({\n ios: async () => {\n const transactionId = purchase.id;\n if (!transactionId) {\n return Promise.reject(\n new Error('purchase.id required to finish iOS transaction'),\n );\n }\n await ExpoIapModule.finishTransaction(transactionId);\n return Promise.resolve(true);\n },\n android: async () => {\n const androidPurchase = purchase as PurchaseAndroid;\n\n // Use purchaseToken if available, fallback to purchaseTokenAndroid for backward compatibility\n const token = androidPurchase.purchaseToken;\n\n if (!token) {\n return Promise.reject(\n new PurchaseError({\n message: 'Purchase token is required to finish transaction',\n code: ErrorCode.DeveloperError,\n productId: androidPurchase.productId,\n platform: 'android',\n }),\n );\n }\n\n if (isConsumable) {\n return ExpoIapModule.consumePurchaseAndroid(token);\n }\n\n return ExpoIapModule.acknowledgePurchaseAndroid(token);\n },\n }) || (() => Promise.reject(new Error('Unsupported Platform')))\n )();\n};\n\n/**\n * Retrieves the current storefront information from iOS App Store\n *\n * @returns Promise resolving to the storefront country code\n * @throws Error if called on non-iOS platform\n *\n * @example\n * ```typescript\n * const storefront = await getStorefrontIOS();\n * console.log(storefront); // 'US'\n * ```\n *\n * @platform iOS\n */\nexport const getStorefrontIOS = (): Promise<string> => {\n if (Platform.OS !== 'ios') {\n console.warn('getStorefrontIOS: This method is only available on iOS');\n return Promise.resolve('');\n }\n return ExpoIapModule.getStorefrontIOS();\n};\n\n/**\n * Gets the storefront country code from the underlying native store.\n * Returns a two-letter country code such as 'US', 'KR', or empty string on failure.\n *\n * @platform ios\n * @platform android\n */\nexport const getStorefront = (): Promise<string> => {\n // Cross-platform storefront\n if (Platform.OS === 'android') {\n if (typeof ExpoIapModule.getStorefrontAndroid === 'function') {\n return ExpoIapModule.getStorefrontAndroid();\n }\n return Promise.resolve('');\n }\n return getStorefrontIOS();\n};\n\n/**\n * Internal receipt validation function (NOT RECOMMENDED for production use)\n *\n * WARNING: This function performs client-side validation which is NOT secure.\n * For production apps, always validate receipts on your secure server:\n * - iOS: Send receipt data to Apple's verification endpoint from your server\n * - Android: Use Google Play Developer API with service account credentials\n */\nexport const validateReceipt = async (\n sku: string,\n androidOptions?: {\n packageName: string;\n productToken: string;\n accessToken: string;\n isSub?: boolean;\n },\n): Promise<ReceiptValidationResult> => {\n if (Platform.OS === 'ios') {\n return await validateReceiptIOS(sku);\n } else if (Platform.OS === 'android') {\n if (\n !androidOptions ||\n !androidOptions.packageName ||\n !androidOptions.productToken ||\n !androidOptions.accessToken\n ) {\n throw new Error(\n 'Android validation requires packageName, productToken, and accessToken',\n );\n }\n return await validateReceiptAndroid({\n packageName: androidOptions.packageName,\n productId: sku,\n productToken: androidOptions.productToken,\n accessToken: androidOptions.accessToken,\n isSub: androidOptions.isSub,\n });\n } else {\n throw new Error('Platform not supported');\n }\n};\n\n/**\n * Deeplinks to native interface that allows users to manage their subscriptions\n * @param options.skuAndroid - Required for Android to locate specific subscription (ignored on iOS)\n * @param options.packageNameAndroid - Required for Android to identify your app (ignored on iOS)\n *\n * @returns Promise that resolves when the deep link is successfully opened\n *\n * @throws {Error} When called on unsupported platform or when required Android parameters are missing\n *\n * @example\n * import { deepLinkToSubscriptions } from 'expo-iap';\n *\n * // Works on both iOS and Android\n * await deepLinkToSubscriptions({\n * skuAndroid: 'your_subscription_sku',\n * packageNameAndroid: 'com.example.app'\n * });\n */\nexport const deepLinkToSubscriptions = (options: {\n skuAndroid?: string;\n packageNameAndroid?: string;\n}): Promise<void> => {\n if (Platform.OS === 'ios') {\n return deepLinkToSubscriptionsIOS();\n }\n\n if (Platform.OS === 'android') {\n return deepLinkToSubscriptionsAndroid({\n sku: options?.skuAndroid,\n packageName: options?.packageNameAndroid,\n });\n }\n\n return Promise.reject(new Error(`Unsupported platform: ${Platform.OS}`));\n};\n\nexport * from './useIAP';\nexport * from './utils/errorMapping';\n"]}
package/build/useIAP.d.ts CHANGED
@@ -8,12 +8,8 @@ type UseIap = {
8
8
  promotedProductIdIOS?: string;
9
9
  subscriptions: ProductSubscription[];
10
10
  availablePurchases: Purchase[];
11
- currentPurchase?: Purchase;
12
- currentPurchaseError?: PurchaseError;
13
11
  promotedProductIOS?: Product;
14
12
  activeSubscriptions: ActiveSubscription[];
15
- clearCurrentPurchase: () => void;
16
- clearCurrentPurchaseError: () => void;
17
13
  finishTransaction: ({ purchase, isConsumable, }: {
18
14
  purchase: Purchase;
19
15
  isConsumable?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useIAP.d.ts","sourceRoot":"","sources":["../src/useIAP.ts"],"names":[],"mappings":"AAMA,OAAO,EAQL,eAAe,IAAI,uBAAuB,EAK1C,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAE1B,MAAM,SAAS,CAAC;AAOjB,OAAO,EACL,OAAO,EACP,QAAQ,EACR,mBAAmB,EAEnB,UAAU,EACV,uBAAuB,EACxB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAW/C,KAAK,MAAM,GAAG;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,mBAAmB,EAAE,QAAQ,EAAE,CAAC;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,kBAAkB,EAAE,QAAQ,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,iBAAiB,EAAE,CAAC,EAClB,QAAQ,EACR,YAAY,GACb,EAAE;QACD,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,KAAK,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC;IACpC,qBAAqB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,aAAa,EAAE,CAAC,MAAM,EAAE;QACtB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;KACzB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpB,eAAe,EAAE,CACf,MAAM,EAAE,oBAAoB,KACzB,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAChD,eAAe,EAAE,CACf,GAAG,EAAE,MAAM,EACX,cAAc,CAAC,EAAE;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,KACE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACtC,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,qBAAqB,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrD,mCAAmC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,sBAAsB,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,sBAAsB,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1E,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACjD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAuXtD"}
1
+ {"version":3,"file":"useIAP.d.ts","sourceRoot":"","sources":["../src/useIAP.ts"],"names":[],"mappings":"AAMA,OAAO,EAQL,eAAe,IAAI,uBAAuB,EAK1C,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAE1B,MAAM,SAAS,CAAC;AAOjB,OAAO,EACL,OAAO,EACP,QAAQ,EACR,mBAAmB,EAEnB,UAAU,EACV,uBAAuB,EACxB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAO/C,KAAK,MAAM,GAAG;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,mBAAmB,EAAE,QAAQ,EAAE,CAAC;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,kBAAkB,EAAE,QAAQ,EAAE,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,iBAAiB,EAAE,CAAC,EAClB,QAAQ,EACR,YAAY,GACb,EAAE;QACD,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,KAAK,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC;IACpC,qBAAqB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,aAAa,EAAE,CAAC,MAAM,EAAE;QACtB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;KACzB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpB,eAAe,EAAE,CACf,MAAM,EAAE,oBAAoB,KACzB,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAChD,eAAe,EAAE,CACf,GAAG,EAAE,MAAM,EACX,cAAc,CAAC,EAAE;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,KACE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACtC,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,qBAAqB,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrD,mCAAmC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,sBAAsB,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,sBAAsB,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1E,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACjD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAoTtD"}
package/build/useIAP.js CHANGED
@@ -7,9 +7,6 @@ import { getPromotedProductIOS, requestPurchaseOnPromotedProductIOS, } from './m
7
7
  // Types
8
8
  import { ErrorCode, } from './types';
9
9
  import { getUserFriendlyErrorMessage, isUserCancelledError, isRecoverableError, } from './utils/errorMapping';
10
- // Deduplicate purchase success events across re-mounts (dev StrictMode, nav returns)
11
- // Keep minimal in-memory state; safe for subscriptions since renewals use new ids
12
- const handledPurchaseIds = new Set();
13
10
  /**
14
11
  * React Hook for managing In-App Purchases.
15
12
  * See documentation at https://hyochan.github.io/expo-iap/docs/hooks/useIAP
@@ -20,9 +17,7 @@ export function useIAP(options) {
20
17
  const [promotedProductsIOS] = useState([]);
21
18
  const [subscriptions, setSubscriptions] = useState([]);
22
19
  const [availablePurchases, setAvailablePurchases] = useState([]);
23
- const [currentPurchase, setCurrentPurchase] = useState();
24
20
  const [promotedProductIOS, setPromotedProductIOS] = useState();
25
- const [currentPurchaseError, setCurrentPurchaseError] = useState();
26
21
  const [promotedProductIdIOS] = useState();
27
22
  const [activeSubscriptions, setActiveSubscriptions] = useState([]);
28
23
  const optionsRef = useRef(options);
@@ -49,12 +44,6 @@ export function useIAP(options) {
49
44
  useEffect(() => {
50
45
  subscriptionsRefState.current = subscriptions;
51
46
  }, [subscriptions]);
52
- const clearCurrentPurchase = useCallback(() => {
53
- setCurrentPurchase(undefined);
54
- }, []);
55
- const clearCurrentPurchaseError = useCallback(() => {
56
- setCurrentPurchaseError(undefined);
57
- }, []);
58
47
  const getSubscriptionsInternal = useCallback(async (skus) => {
59
48
  try {
60
49
  const result = await fetchProducts({ skus, type: 'subs' });
@@ -109,40 +98,15 @@ export function useIAP(options) {
109
98
  return false;
110
99
  }
111
100
  }, []);
112
- const finishTransaction = useCallback(async ({ purchase, isConsumable, }) => {
113
- try {
114
- return await finishTransactionInternal({
115
- purchase,
116
- isConsumable,
117
- });
118
- }
119
- catch (err) {
120
- throw err;
121
- }
122
- finally {
123
- if (purchase.id === currentPurchase?.id) {
124
- clearCurrentPurchase();
125
- }
126
- if (purchase.id === currentPurchaseError?.productId) {
127
- clearCurrentPurchaseError();
128
- }
129
- }
130
- }, [
131
- currentPurchase?.id,
132
- currentPurchaseError?.productId,
133
- clearCurrentPurchase,
134
- clearCurrentPurchaseError,
135
- ]);
136
- const requestPurchaseWithReset = useCallback(async (requestObj) => {
137
- clearCurrentPurchase();
138
- clearCurrentPurchaseError();
139
- try {
140
- return await requestPurchaseInternal(requestObj);
141
- }
142
- catch (error) {
143
- throw error;
144
- }
145
- }, [clearCurrentPurchase, clearCurrentPurchaseError]);
101
+ const finishTransaction = useCallback(({ purchase, isConsumable, }) => {
102
+ return finishTransactionInternal({
103
+ purchase,
104
+ isConsumable,
105
+ });
106
+ }, []);
107
+ const requestPurchaseWithReset = useCallback((requestObj) => {
108
+ return requestPurchaseInternal(requestObj);
109
+ }, []);
146
110
  const refreshSubscriptionStatus = useCallback(async (productId) => {
147
111
  try {
148
112
  if (subscriptionsRefState.current.some((sub) => sub.id === productId)) {
@@ -175,20 +139,8 @@ export function useIAP(options) {
175
139
  const initIapWithSubscriptions = useCallback(async () => {
176
140
  // CRITICAL: Register listeners BEFORE initConnection to avoid race condition
177
141
  // Events might fire immediately after initConnection, so listeners must be ready
178
- console.log('[useIAP] Setting up event listeners BEFORE initConnection...');
179
142
  // Register purchase update listener BEFORE initConnection to avoid race conditions.
180
143
  subscriptionsRef.current.purchaseUpdate = purchaseUpdatedListener(async (purchase) => {
181
- console.log('[useIAP] Purchase success callback triggered:', purchase);
182
- // Guard against duplicate emissions for the same transaction
183
- const dedupeKey = purchase.id;
184
- if (dedupeKey && handledPurchaseIds.has(dedupeKey)) {
185
- console.log('[useIAP] Duplicate purchase event ignored:', dedupeKey);
186
- return;
187
- }
188
- if (dedupeKey)
189
- handledPurchaseIds.add(dedupeKey);
190
- setCurrentPurchaseError(undefined);
191
- setCurrentPurchase(purchase);
192
144
  if ('expirationDateIOS' in purchase) {
193
145
  await refreshSubscriptionStatus(purchase.id);
194
146
  }
@@ -202,18 +154,9 @@ export function useIAP(options) {
202
154
  return; // Ignore initialization error before connected
203
155
  }
204
156
  const friendly = getUserFriendlyErrorMessage(error);
205
- console.log('[useIAP] Purchase error callback triggered:', error);
206
- if (isUserCancelledError(error)) {
207
- console.log('[useIAP] User cancelled purchase');
208
- }
209
- else if (isRecoverableError(error)) {
210
- console.log('[useIAP] Recoverable purchase error:', friendly);
211
- }
212
- else {
157
+ if (!isUserCancelledError(error) && !isRecoverableError(error)) {
213
158
  console.warn('[useIAP] Purchase error:', friendly);
214
159
  }
215
- setCurrentPurchase(undefined);
216
- setCurrentPurchaseError(error);
217
160
  if (optionsRef.current?.onPurchaseError) {
218
161
  optionsRef.current.onPurchaseError(error);
219
162
  }
@@ -221,18 +164,15 @@ export function useIAP(options) {
221
164
  if (Platform.OS === 'ios') {
222
165
  // iOS promoted products listener
223
166
  subscriptionsRef.current.promotedProductsIOS = promotedProductListenerIOS((product) => {
224
- console.log('[useIAP] Promoted product callback triggered:', product);
225
167
  setPromotedProductIOS(product);
226
168
  if (optionsRef.current?.onPromotedProductIOS) {
227
169
  optionsRef.current.onPromotedProductIOS(product);
228
170
  }
229
171
  });
230
172
  }
231
- console.log('[useIAP] Event listeners registered, now calling initConnection...');
232
173
  // NOW call initConnection after listeners are ready
233
174
  const result = await initConnection();
234
175
  setConnected(result);
235
- console.log('[useIAP] initConnection result:', result);
236
176
  if (!result) {
237
177
  // If connection failed, clean up listeners
238
178
  console.warn('[useIAP] Connection failed, cleaning up listeners...');
@@ -254,7 +194,6 @@ export function useIAP(options) {
254
194
  currentSubscriptions.promotedProductIOS?.remove();
255
195
  endConnection();
256
196
  setConnected(false);
257
- handledPurchaseIds.clear();
258
197
  };
259
198
  }, [initIapWithSubscriptions]);
260
199
  return {
@@ -265,12 +204,8 @@ export function useIAP(options) {
265
204
  subscriptions,
266
205
  finishTransaction,
267
206
  availablePurchases,
268
- currentPurchase,
269
- currentPurchaseError,
270
207
  promotedProductIOS,
271
208
  activeSubscriptions,
272
- clearCurrentPurchase,
273
- clearCurrentPurchaseError,
274
209
  getAvailablePurchases: getAvailablePurchasesInternal,
275
210
  fetchProducts: fetchProductsInternal,
276
211
  requestPurchase: requestPurchaseWithReset,