expo-iap 4.4.0-rc.7 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/README.md +1 -1
  3. package/android/src/main/java/expo/modules/iap/ExpoIapHelper.kt +14 -1
  4. package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +138 -6
  5. package/build/index.d.ts +19 -17
  6. package/build/index.d.ts.map +1 -1
  7. package/build/index.js +24 -19
  8. package/build/index.js.map +1 -1
  9. package/build/index.kepler.d.ts +3 -0
  10. package/build/index.kepler.d.ts.map +1 -1
  11. package/build/index.kepler.js +3 -0
  12. package/build/index.kepler.js.map +1 -1
  13. package/build/modules/android.d.ts +35 -19
  14. package/build/modules/android.d.ts.map +1 -1
  15. package/build/modules/android.js +57 -6
  16. package/build/modules/android.js.map +1 -1
  17. package/build/modules/ios.d.ts +6 -6
  18. package/build/modules/ios.d.ts.map +1 -1
  19. package/build/modules/ios.js.map +1 -1
  20. package/build/types.d.ts +223 -35
  21. package/build/types.d.ts.map +1 -1
  22. package/build/types.js.map +1 -1
  23. package/build/useIAP.d.ts +23 -3
  24. package/build/useIAP.d.ts.map +1 -1
  25. package/build/useIAP.js +43 -7
  26. package/build/useIAP.js.map +1 -1
  27. package/build/vega-adapter.d.ts.map +1 -1
  28. package/build/vega-adapter.js +15 -2
  29. package/build/vega-adapter.js.map +1 -1
  30. package/openiap-versions.json +3 -3
  31. package/package.json +1 -1
  32. package/plugin/build/withIAP.js +16 -9
  33. package/plugin/src/withIAP.ts +20 -12
  34. package/src/index.kepler.ts +9 -0
  35. package/src/index.ts +26 -17
  36. package/src/modules/android.ts +105 -7
  37. package/src/modules/ios.ts +23 -22
  38. package/src/types.ts +238 -35
  39. package/src/useIAP.ts +102 -17
  40. package/src/vega-adapter.ts +32 -5
package/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
1
  # CHANGELOG
2
2
 
3
- [Check release notes](https://github.com/hyochan/expo-iap/releases)
3
+ OpenIAP keeps detailed release history centralized to avoid package-local drift.
4
+
5
+ - Consolidated release notes: [openiap.dev/docs/updates/releases](https://openiap.dev/docs/updates/releases)
6
+ - Expo package releases: [hyodotdev/openiap/releases?q=expo-iap](https://github.com/hyodotdev/openiap/releases?q=expo-iap&expanded=true)
package/README.md CHANGED
@@ -85,7 +85,7 @@ Expo IAP conforms to the **[OpenIAP specification](https://openiap.dev)** — an
85
85
 
86
86
  - **Shared specification** — Common types, error codes, and purchase flows across all platforms
87
87
  - **Generated type-safe bindings** — Swift, Kotlin, Dart, and GDScript from a single GraphQL schema
88
- - **Platform implementations** — [openiap-apple](https://github.com/hyodotdev/openiap/tree/main/packages/apple) (StoreKit 2) and [openiap-google](https://github.com/hyodotdev/openiap/tree/main/packages/google) (Play Billing 8.x)
88
+ - **Platform implementations** — [openiap-apple](https://github.com/hyodotdev/openiap/tree/main/packages/apple) (StoreKit 2) and [openiap-google](https://github.com/hyodotdev/openiap/tree/main/packages/google) (Play Billing 9.1.0)
89
89
  - **Verification profiles** — Standardized receipt validation and purchase verification patterns
90
90
 
91
91
  Other libraries built on OpenIAP: [react-native-iap](https://github.com/hyodotdev/openiap/tree/main/libraries/react-native-iap) · [flutter_inapp_purchase](https://github.com/hyodotdev/openiap/tree/main/libraries/flutter_inapp_purchase) · [kmp-iap](https://github.com/hyodotdev/openiap/tree/main/libraries/kmp-iap) · [godot-iap](https://github.com/hyodotdev/openiap/tree/main/libraries/godot-iap)
@@ -1,6 +1,7 @@
1
1
  package expo.modules.iap
2
2
 
3
3
  import dev.hyo.openiap.AndroidSubscriptionOfferInput
4
+ import dev.hyo.openiap.DeveloperBillingOptionParamsAndroid
4
5
  import dev.hyo.openiap.OpenIapError
5
6
  import dev.hyo.openiap.OpenIapModule
6
7
  import dev.hyo.openiap.ProductQueryType
@@ -102,7 +103,15 @@ object ExpoIapHelper {
102
103
  }
103
104
  } ?: emptyList()
104
105
  val purchaseToken = effective["purchaseToken"] as? String
106
+ val originalExternalTransactionId = effective["originalExternalTransactionId"] as? String
105
107
  val replacementMode = effective["replacementMode"] as? Number
108
+ val developerBillingOption =
109
+ (effective["developerBillingOption"] as? Map<*, *>)?.let { optionMap ->
110
+ val json = optionMap.entries.mapNotNull { (key, value) ->
111
+ (key as? String)?.let { it to value }
112
+ }.toMap()
113
+ DeveloperBillingOptionParamsAndroid.fromJson(json)
114
+ }
106
115
  val subscriptionProductReplacementParams =
107
116
  (effective["subscriptionProductReplacementParams"] as? Map<*, *>)?.let { paramsMap ->
108
117
  val oldProductId = paramsMap["oldProductId"] as? String
@@ -128,6 +137,8 @@ object ExpoIapHelper {
128
137
  offerToken = offerToken,
129
138
  offerTokenArr = offerTokenArr,
130
139
  explicitSubscriptionOffers = explicitSubscriptionOffers,
140
+ developerBillingOption = developerBillingOption,
141
+ originalExternalTransactionId = originalExternalTransactionId,
131
142
  purchaseToken = purchaseToken,
132
143
  replacementMode = replacementMode,
133
144
  subscriptionProductReplacementParams = subscriptionProductReplacementParams,
@@ -155,6 +166,8 @@ object ExpoIapHelper {
155
166
  val offerToken: String?,
156
167
  val offerTokenArr: List<String>,
157
168
  val explicitSubscriptionOffers: List<AndroidSubscriptionOfferInput>,
169
+ val developerBillingOption: DeveloperBillingOptionParamsAndroid?,
170
+ val originalExternalTransactionId: String?,
158
171
  val purchaseToken: String?,
159
172
  val replacementMode: Number?,
160
173
  val subscriptionProductReplacementParams: SubscriptionProductReplacementParamsAndroid?,
@@ -306,7 +319,7 @@ object ExpoIapHelper {
306
319
  "USER_CHOICE_BILLING",
307
320
  )
308
321
  }
309
- // Developer Provided Billing listener for External Payments (8.3.0+)
322
+ // Developer Provided Billing listener for External Payments (8.3.0+) and Billing Choice (9.1.0+)
310
323
  openIap.addDeveloperProvidedBillingListener { details ->
311
324
  safeEmitEvent(
312
325
  module,
@@ -36,9 +36,15 @@ import kotlinx.coroutines.sync.Mutex
36
36
  import kotlinx.coroutines.sync.withLock
37
37
  import java.util.concurrent.ConcurrentLinkedQueue
38
38
  import java.util.concurrent.atomic.AtomicBoolean
39
+ import dev.hyo.openiap.BillingChoiceImageLayoutAndroid as OpenIapBillingChoiceImageLayout
40
+ import dev.hyo.openiap.BillingProgramInformationDialogParamsAndroid as OpenIapBillingProgramInformationDialogParams
39
41
  import dev.hyo.openiap.BillingProgramAndroid as OpenIapBillingProgram
42
+ import dev.hyo.openiap.DeveloperBillingTypeAndroid as OpenIapDeveloperBillingType
40
43
  import dev.hyo.openiap.ExternalLinkLaunchModeAndroid as OpenIapExternalLinkLaunchMode
41
44
  import dev.hyo.openiap.ExternalLinkTypeAndroid as OpenIapExternalLinkType
45
+ import dev.hyo.openiap.GetBillingChoiceInfoParamsAndroid as OpenIapGetBillingChoiceInfoParams
46
+ import dev.hyo.openiap.InAppMessageCategoryAndroid as OpenIapInAppMessageCategory
47
+ import dev.hyo.openiap.InAppMessageParamsAndroid as OpenIapInAppMessageParams
42
48
  import dev.hyo.openiap.LaunchExternalLinkParamsAndroid as OpenIapLaunchExternalLinkParams
43
49
 
44
50
  class ExpoIapModule : Module() {
@@ -280,6 +286,8 @@ class ExpoIapModule : Module() {
280
286
  isOfferPersonalized = parsedParams.isOfferPersonalized,
281
287
  obfuscatedAccountId = parsedParams.obfuscatedAccountId,
282
288
  obfuscatedProfileId = parsedParams.obfuscatedProfileId,
289
+ developerBillingOption = parsedParams.developerBillingOption,
290
+ originalExternalTransactionId = parsedParams.originalExternalTransactionId,
283
291
  purchaseToken = parsedParams.purchaseToken,
284
292
  replacementMode = parsedParams.replacementMode?.toInt(),
285
293
  skus = parsedParams.skus,
@@ -289,7 +297,7 @@ class ExpoIapModule : Module() {
289
297
  RequestPurchaseProps(
290
298
  request =
291
299
  RequestPurchaseProps.Request.Subscription(
292
- RequestSubscriptionPropsByPlatforms(android = android),
300
+ RequestSubscriptionPropsByPlatforms(google = android),
293
301
  ),
294
302
  type = ProductQueryType.Subs,
295
303
  )
@@ -301,13 +309,14 @@ class ExpoIapModule : Module() {
301
309
  isOfferPersonalized = parsedParams.isOfferPersonalized,
302
310
  obfuscatedAccountId = parsedParams.obfuscatedAccountId,
303
311
  obfuscatedProfileId = parsedParams.obfuscatedProfileId,
312
+ developerBillingOption = parsedParams.developerBillingOption,
304
313
  offerToken = parsedParams.offerToken,
305
314
  skus = parsedParams.skus,
306
315
  )
307
316
  RequestPurchaseProps(
308
317
  request =
309
318
  RequestPurchaseProps.Request.Purchase(
310
- RequestPurchasePropsByPlatforms(android = android),
319
+ RequestPurchasePropsByPlatforms(google = android),
311
320
  ),
312
321
  type = ProductQueryType.InApp,
313
322
  )
@@ -569,8 +578,10 @@ class ExpoIapModule : Module() {
569
578
  val result = openIapStore.isBillingProgramAvailable(openIapProgram)
570
579
  val response =
571
580
  mapOf(
572
- "billingProgram" to program,
581
+ "billingProgram" to result.billingProgram.toJson(),
582
+ "choiceScreenType" to result.choiceScreenType?.toJson(),
573
583
  "isAvailable" to result.isAvailable,
584
+ "isExternalLinkAvailable" to result.isExternalLinkAvailable,
574
585
  )
575
586
  ExpoIapLog.result("isBillingProgramAvailableAndroid", response)
576
587
  promise.resolve(response)
@@ -581,12 +592,41 @@ class ExpoIapModule : Module() {
581
592
  }
582
593
  }
583
594
 
584
- AsyncFunction("createBillingProgramReportingDetailsAndroid") { program: String, promise: Promise ->
585
- ExpoIapLog.payload("createBillingProgramReportingDetailsAndroid", mapOf("program" to program))
595
+ AsyncFunction("getBillingChoiceInfoAndroid") { params: Map<String, Any?>, promise: Promise ->
596
+ ExpoIapLog.payload("getBillingChoiceInfoAndroid", params)
597
+ scope.launch {
598
+ try {
599
+ val request =
600
+ OpenIapGetBillingChoiceInfoParams(
601
+ billingProgram = mapBillingProgram(params["billingProgram"] as? String ?: "billing-choice"),
602
+ playBillingChoiceImageLayout = mapBillingChoiceImageLayout(
603
+ params["playBillingChoiceImageLayout"] as? String ?: "rectangular-four-by-one",
604
+ ),
605
+ userLocale = params["userLocale"] as? String,
606
+ )
607
+ val result = openIapStore.getBillingChoiceInfo(request)
608
+ ExpoIapLog.result("getBillingChoiceInfoAndroid", mapOf("hasImageUrl" to result.playBillingChoiceImageUrl.isNotBlank()))
609
+ promise.resolve(result.toJson())
610
+ } catch (e: Exception) {
611
+ ExpoIapLog.failure("getBillingChoiceInfoAndroid", e)
612
+ promise.reject(OpenIapError.ServiceUnavailable.CODE, e.message, e)
613
+ }
614
+ }
615
+ }
616
+
617
+ AsyncFunction("createBillingProgramReportingDetailsAndroid") { program: String, developerBillingType: String?, promise: Promise ->
618
+ ExpoIapLog.payload(
619
+ "createBillingProgramReportingDetailsAndroid",
620
+ mapOf("program" to program, "developerBillingType" to developerBillingType),
621
+ )
586
622
  scope.launch {
587
623
  try {
588
624
  val openIapProgram = mapBillingProgram(program)
589
- val result = openIapStore.createBillingProgramReportingDetails(openIapProgram)
625
+ val result =
626
+ openIapStore.createBillingProgramReportingDetails(
627
+ openIapProgram,
628
+ mapDeveloperBillingType(developerBillingType),
629
+ )
590
630
  val response =
591
631
  mapOf(
592
632
  "billingProgram" to program,
@@ -604,6 +644,74 @@ class ExpoIapModule : Module() {
604
644
  }
605
645
  }
606
646
 
647
+ AsyncFunction("showBillingProgramInformationDialogAndroid") { params: Map<String, Any?>, promise: Promise ->
648
+ ExpoIapLog.payload("showBillingProgramInformationDialogAndroid", params)
649
+ scope.launch {
650
+ try {
651
+ val activity =
652
+ runCatching { currentActivity }
653
+ .onFailure {
654
+ ExpoIapLog.failure("showBillingProgramInformationDialogAndroid activity", it)
655
+ }.getOrNull() ?: run {
656
+ promise.reject(OpenIapError.ServiceUnavailable.CODE, "Activity not available", null)
657
+ return@launch
658
+ }
659
+ val token = params["externalTransactionToken"] as? String
660
+ if (token.isNullOrBlank()) {
661
+ promise.reject(OpenIapError.DeveloperError.CODE, "`externalTransactionToken` is a required parameter.", null)
662
+ return@launch
663
+ }
664
+ val result =
665
+ openIapStore.showBillingProgramInformationDialog(
666
+ activity,
667
+ OpenIapBillingProgramInformationDialogParams(
668
+ billingProgram = mapBillingProgram(params["billingProgram"] as? String ?: "billing-choice"),
669
+ externalTransactionToken = token,
670
+ ),
671
+ )
672
+ ExpoIapLog.result("showBillingProgramInformationDialogAndroid", result.toJson())
673
+ promise.resolve(result.toJson())
674
+ } catch (e: Exception) {
675
+ ExpoIapLog.failure("showBillingProgramInformationDialogAndroid", e)
676
+ promise.reject(OpenIapError.ServiceUnavailable.CODE, e.message, e)
677
+ }
678
+ }
679
+ }
680
+
681
+ AsyncFunction("showInAppMessagesAndroid") { params: Map<String, Any?>?, promise: Promise ->
682
+ ExpoIapLog.payload("showInAppMessagesAndroid", params ?: emptyMap<String, Any?>())
683
+ scope.launch {
684
+ try {
685
+ val activity =
686
+ runCatching { currentActivity }
687
+ .onFailure {
688
+ ExpoIapLog.failure("showInAppMessagesAndroid activity", it)
689
+ }.getOrNull() ?: run {
690
+ promise.reject(OpenIapError.ServiceUnavailable.CODE, "Activity not available", null)
691
+ return@launch
692
+ }
693
+ val categories =
694
+ (params?.get("categories") as? List<*>)
695
+ ?.map { entry ->
696
+ val category = entry as? String
697
+ ?: throw IllegalArgumentException("In-app message category must be a string: $entry")
698
+ mapInAppMessageCategory(category)
699
+ ?: throw IllegalArgumentException("Unknown in-app message category: $category")
700
+ }
701
+ val result =
702
+ openIapStore.showInAppMessages(
703
+ activity,
704
+ OpenIapInAppMessageParams(categories = categories),
705
+ )
706
+ ExpoIapLog.result("showInAppMessagesAndroid", result.toJson())
707
+ promise.resolve(result.toJson())
708
+ } catch (e: Exception) {
709
+ ExpoIapLog.failure("showInAppMessagesAndroid", e)
710
+ promise.reject(OpenIapError.ServiceUnavailable.CODE, e.message, e)
711
+ }
712
+ }
713
+ }
714
+
607
715
  AsyncFunction("launchExternalLinkAndroid") { params: Map<String, Any?>, promise: Promise ->
608
716
  ExpoIapLog.payload("launchExternalLinkAndroid", params)
609
717
  scope.launch {
@@ -618,6 +726,7 @@ class ExpoIapModule : Module() {
618
726
  }
619
727
 
620
728
  val billingProgram = params["billingProgram"] as? String
729
+ val externalTransactionToken = params["externalTransactionToken"] as? String
621
730
  val launchMode = params["launchMode"] as? String ?: "unspecified"
622
731
  val linkType = params["linkType"] as? String ?: "unspecified"
623
732
  val linkUri = params["linkUri"] as? String
@@ -635,6 +744,7 @@ class ExpoIapModule : Module() {
635
744
  val openIapParams =
636
745
  OpenIapLaunchExternalLinkParams(
637
746
  billingProgram = mapBillingProgram(billingProgram),
747
+ externalTransactionToken = externalTransactionToken,
638
748
  launchMode = mapExternalLinkLaunchMode(launchMode),
639
749
  linkType = mapExternalLinkType(linkType),
640
750
  linkUri = linkUri,
@@ -666,9 +776,31 @@ class ExpoIapModule : Module() {
666
776
  "external-content-link" -> OpenIapBillingProgram.ExternalContentLink
667
777
  "external-payments" -> OpenIapBillingProgram.ExternalPayments
668
778
  "user-choice-billing" -> OpenIapBillingProgram.UserChoiceBilling
779
+ "billing-choice" -> OpenIapBillingProgram.BillingChoice
669
780
  else -> OpenIapBillingProgram.Unspecified
670
781
  }
671
782
 
783
+ private fun mapBillingChoiceImageLayout(layout: String): OpenIapBillingChoiceImageLayout =
784
+ when (layout) {
785
+ "rectangular-three-by-one" -> OpenIapBillingChoiceImageLayout.RectangularThreeByOne
786
+ "rectangular-two-by-two" -> OpenIapBillingChoiceImageLayout.RectangularTwoByTwo
787
+ else -> OpenIapBillingChoiceImageLayout.RectangularFourByOne
788
+ }
789
+
790
+ private fun mapDeveloperBillingType(type: String?): OpenIapDeveloperBillingType? =
791
+ when (type) {
792
+ "in-app" -> OpenIapDeveloperBillingType.InApp
793
+ "external-link" -> OpenIapDeveloperBillingType.ExternalLink
794
+ else -> null
795
+ }
796
+
797
+ private fun mapInAppMessageCategory(category: String): OpenIapInAppMessageCategory? =
798
+ when (category) {
799
+ "unknown-in-app-message-category-id" -> OpenIapInAppMessageCategory.UnknownInAppMessageCategoryId
800
+ "transactional" -> OpenIapInAppMessageCategory.Transactional
801
+ else -> null
802
+ }
803
+
672
804
  private fun mapExternalLinkLaunchMode(mode: String): OpenIapExternalLinkLaunchMode =
673
805
  when (mode) {
674
806
  "launch-in-external-browser-or-app" -> OpenIapExternalLinkLaunchMode.LaunchInExternalBrowserOrApp
package/build/index.d.ts CHANGED
@@ -11,8 +11,8 @@ export declare enum OpenIapEvent {
11
11
  PromotedProductIOS = "promoted-product-ios",
12
12
  UserChoiceBillingAndroid = "user-choice-billing-android",
13
13
  /**
14
- * Fired when user selects developer billing in External Payments flow (Android 8.3.0+)
15
- * Only available in Japan. Contains externalTransactionToken for reporting.
14
+ * Fired for External Payments (8.3.0+) and Billing Choice (9.1.0+)
15
+ * developer billing flows. Nullable fields depend on the selected flow.
16
16
  */
17
17
  DeveloperProvidedBillingAndroid = "developer-provided-billing-android",
18
18
  /**
@@ -103,33 +103,29 @@ export declare const userChoiceBillingListenerAndroid: (listener: (details: User
103
103
  remove: () => void;
104
104
  };
105
105
  /**
106
- * Android-only listener for Developer Provided Billing events (External Payments).
107
- * This fires when a user selects the developer's payment option in the External Payments
108
- * side-by-side choice dialog during purchase flow.
106
+ * Android-only listener for Developer Provided Billing events.
107
+ * This fires when a user selects the developer's option in an External Payments
108
+ * or Billing Choice purchase flow.
109
109
  *
110
- * Requires Google Play Billing Library 8.3.0+ and is currently only available in Japan.
110
+ * Requires Google Play Billing Library 8.3.0+; Billing Choice fields require 9.1.0+.
111
111
  *
112
- * @param listener - Callback function that receives the external transaction token
112
+ * @param listener - Callback that receives selected products and flow details
113
113
  * @returns EventSubscription that can be used to unsubscribe
114
114
  *
115
115
  * @example
116
116
  * ```typescript
117
117
  * const subscription = developerProvidedBillingListenerAndroid(async (details) => {
118
- * console.log('User selected developer billing');
119
- * console.log('External transaction token received; send it to your backend without logging it.');
120
- *
121
- * // Process payment with your payment gateway
122
- * await processPaymentWithYourGateway(details.externalTransactionToken);
123
- *
124
- * // IMPORTANT: Report the token to Google Play within 24 hours
125
- * await reportExternalTransactionToGoogle(details.externalTransactionToken);
118
+ * await processPaymentWithYourGateway(details.products, details.linkUri);
119
+ * if (details.externalTransactionToken) {
120
+ * await reportExternalTransactionToGoogle(details.externalTransactionToken);
121
+ * }
126
122
  * });
127
123
  *
128
124
  * // Later, clean up
129
125
  * subscription.remove();
130
126
  * ```
131
127
  *
132
- * @platform Android (8.3.0+, Japan only)
128
+ * @platform Android (8.3.0+; Billing Choice 9.1.0+)
133
129
  */
134
130
  export declare const developerProvidedBillingListenerAndroid: (listener: (details: DeveloperProvidedBillingDetailsAndroid) => void) => {
135
131
  remove: () => void;
@@ -164,7 +160,9 @@ export declare const subscriptionBillingIssueListener: (listener: (purchase: Pur
164
160
  * Initialize the store connection. Must be called before any other IAP API.
165
161
  *
166
162
  * @param config Optional connection config. Use `enableBillingProgramAndroid` (Android,
167
- * Play Billing 8.2.0+) to opt into External Payments etc. iOS ignores Android-specific fields.
163
+ * Play Billing 8.2.0+) to opt into a billing program. For Billing Choice 9.1.0+, set
164
+ * `billingChoiceScreenTypeAndroid` to the renderer configured in Play Console.
165
+ * iOS ignores Android-specific fields.
168
166
  * @returns Promise resolving to `true` when the platform billing client is connected.
169
167
  * @throws When the platform billing client fails to initialize.
170
168
  *
@@ -172,6 +170,10 @@ export declare const subscriptionBillingIssueListener: (listener: (purchase: Pur
172
170
  * ```ts
173
171
  * await initConnection();
174
172
  * await initConnection({ enableBillingProgramAndroid: 'external-offer' });
173
+ * await initConnection({
174
+ * enableBillingProgramAndroid: 'billing-choice',
175
+ * billingChoiceScreenTypeAndroid: 'developer-rendered',
176
+ * });
175
177
  * ```
176
178
  *
177
179
  * @remarks When using `useIAP()`, connection is auto-managed on mount/unmount —
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -22,8 +22,8 @@ export var OpenIapEvent;
22
22
  OpenIapEvent["PromotedProductIOS"] = "promoted-product-ios";
23
23
  OpenIapEvent["UserChoiceBillingAndroid"] = "user-choice-billing-android";
24
24
  /**
25
- * Fired when user selects developer billing in External Payments flow (Android 8.3.0+)
26
- * Only available in Japan. Contains externalTransactionToken for reporting.
25
+ * Fired for External Payments (8.3.0+) and Billing Choice (9.1.0+)
26
+ * developer billing flows. Nullable fields depend on the selected flow.
27
27
  */
28
28
  OpenIapEvent["DeveloperProvidedBillingAndroid"] = "developer-provided-billing-android";
29
29
  /**
@@ -308,33 +308,29 @@ export const userChoiceBillingListenerAndroid = (listener) => {
308
308
  return emitter.addListener(OpenIapEvent.UserChoiceBillingAndroid, listener);
309
309
  };
310
310
  /**
311
- * Android-only listener for Developer Provided Billing events (External Payments).
312
- * This fires when a user selects the developer's payment option in the External Payments
313
- * side-by-side choice dialog during purchase flow.
311
+ * Android-only listener for Developer Provided Billing events.
312
+ * This fires when a user selects the developer's option in an External Payments
313
+ * or Billing Choice purchase flow.
314
314
  *
315
- * Requires Google Play Billing Library 8.3.0+ and is currently only available in Japan.
315
+ * Requires Google Play Billing Library 8.3.0+; Billing Choice fields require 9.1.0+.
316
316
  *
317
- * @param listener - Callback function that receives the external transaction token
317
+ * @param listener - Callback that receives selected products and flow details
318
318
  * @returns EventSubscription that can be used to unsubscribe
319
319
  *
320
320
  * @example
321
321
  * ```typescript
322
322
  * const subscription = developerProvidedBillingListenerAndroid(async (details) => {
323
- * console.log('User selected developer billing');
324
- * console.log('External transaction token received; send it to your backend without logging it.');
325
- *
326
- * // Process payment with your payment gateway
327
- * await processPaymentWithYourGateway(details.externalTransactionToken);
328
- *
329
- * // IMPORTANT: Report the token to Google Play within 24 hours
330
- * await reportExternalTransactionToGoogle(details.externalTransactionToken);
323
+ * await processPaymentWithYourGateway(details.products, details.linkUri);
324
+ * if (details.externalTransactionToken) {
325
+ * await reportExternalTransactionToGoogle(details.externalTransactionToken);
326
+ * }
331
327
  * });
332
328
  *
333
329
  * // Later, clean up
334
330
  * subscription.remove();
335
331
  * ```
336
332
  *
337
- * @platform Android (8.3.0+, Japan only)
333
+ * @platform Android (8.3.0+; Billing Choice 9.1.0+)
338
334
  */
339
335
  export const developerProvidedBillingListenerAndroid = (listener) => {
340
336
  if (Platform.OS !== 'android') {
@@ -378,7 +374,9 @@ export const subscriptionBillingIssueListener = (listener) => {
378
374
  * Initialize the store connection. Must be called before any other IAP API.
379
375
  *
380
376
  * @param config Optional connection config. Use `enableBillingProgramAndroid` (Android,
381
- * Play Billing 8.2.0+) to opt into External Payments etc. iOS ignores Android-specific fields.
377
+ * Play Billing 8.2.0+) to opt into a billing program. For Billing Choice 9.1.0+, set
378
+ * `billingChoiceScreenTypeAndroid` to the renderer configured in Play Console.
379
+ * iOS ignores Android-specific fields.
382
380
  * @returns Promise resolving to `true` when the platform billing client is connected.
383
381
  * @throws When the platform billing client fails to initialize.
384
382
  *
@@ -386,6 +384,10 @@ export const subscriptionBillingIssueListener = (listener) => {
386
384
  * ```ts
387
385
  * await initConnection();
388
386
  * await initConnection({ enableBillingProgramAndroid: 'external-offer' });
387
+ * await initConnection({
388
+ * enableBillingProgramAndroid: 'billing-choice',
389
+ * billingChoiceScreenTypeAndroid: 'developer-rendered',
390
+ * });
389
391
  * ```
390
392
  *
391
393
  * @remarks When using `useIAP()`, connection is auto-managed on mount/unmount —
@@ -679,7 +681,7 @@ export const requestPurchase = async (args) => {
679
681
  ' })\n\n' +
680
682
  'See: https://openiap.dev/docs/apis/request-purchase');
681
683
  }
682
- const { skus, obfuscatedAccountId, obfuscatedProfileId, isOfferPersonalized, offerToken, } = normalizedRequest;
684
+ const { skus, obfuscatedAccountId, obfuscatedProfileId, isOfferPersonalized, offerToken, developerBillingOption, } = normalizedRequest;
683
685
  const result = (await ExpoIapModule.requestPurchase({
684
686
  type: native,
685
687
  skuArr: skus,
@@ -688,6 +690,7 @@ export const requestPurchase = async (args) => {
688
690
  obfuscatedAccountId: obfuscatedAccountId,
689
691
  obfuscatedProfileId: obfuscatedProfileId,
690
692
  offerToken: offerToken,
693
+ developerBillingOption: developerBillingOption ?? undefined,
691
694
  offerTokenArr: [],
692
695
  isOfferPersonalized: isOfferPersonalized ?? false,
693
696
  }));
@@ -707,7 +710,7 @@ export const requestPurchase = async (args) => {
707
710
  ' })\n\n' +
708
711
  'See: https://openiap.dev/docs/apis/request-purchase');
709
712
  }
710
- const { skus, obfuscatedAccountId, obfuscatedProfileId, isOfferPersonalized, subscriptionOffers, replacementMode: replacementModeInput, purchaseToken: purchaseTokenInput, subscriptionProductReplacementParams, } = normalizedRequest;
713
+ const { skus, obfuscatedAccountId, obfuscatedProfileId, isOfferPersonalized, subscriptionOffers, replacementMode: replacementModeInput, purchaseToken: purchaseTokenInput, originalExternalTransactionId, developerBillingOption, subscriptionProductReplacementParams, } = normalizedRequest;
711
714
  const normalizedOffers = subscriptionOffers ?? [];
712
715
  const replacementMode = replacementModeInput ?? -1;
713
716
  const purchaseToken = purchaseTokenInput ?? undefined;
@@ -715,12 +718,14 @@ export const requestPurchase = async (args) => {
715
718
  type: native,
716
719
  skuArr: skus,
717
720
  purchaseToken,
721
+ originalExternalTransactionId: originalExternalTransactionId ?? undefined,
718
722
  replacementMode,
719
723
  obfuscatedAccountId: obfuscatedAccountId,
720
724
  obfuscatedProfileId: obfuscatedProfileId,
721
725
  offerTokenArr: normalizedOffers.map((offer) => offer.offerToken),
722
726
  subscriptionOffers: normalizedOffers,
723
727
  isOfferPersonalized: isOfferPersonalized ?? false,
728
+ developerBillingOption: developerBillingOption ?? undefined,
724
729
  subscriptionProductReplacementParams: subscriptionProductReplacementParams ?? undefined,
725
730
  }));
726
731
  return normalizePurchaseArray(result);