react-native-iap 14.5.1-rc.1 → 14.6.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +1 -0
  2. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +198 -36
  3. package/ios/HybridRnIap.swift +32 -2
  4. package/lib/module/hooks/useIAP.js +1 -6
  5. package/lib/module/hooks/useIAP.js.map +1 -1
  6. package/lib/module/index.js +228 -10
  7. package/lib/module/index.js.map +1 -1
  8. package/lib/module/types.js +116 -0
  9. package/lib/module/types.js.map +1 -1
  10. package/lib/typescript/plugin/src/withIAP.d.ts +6 -0
  11. package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
  12. package/lib/typescript/src/hooks/useIAP.d.ts +5 -7
  13. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  14. package/lib/typescript/src/index.d.ts +144 -2
  15. package/lib/typescript/src/index.d.ts.map +1 -1
  16. package/lib/typescript/src/specs/RnIap.nitro.d.ts +90 -8
  17. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  18. package/lib/typescript/src/types.d.ts +194 -10
  19. package/lib/typescript/src/types.d.ts.map +1 -1
  20. package/nitrogen/generated/android/c++/JBillingProgramAndroid.hpp +62 -0
  21. package/nitrogen/generated/android/c++/JExternalLinkLaunchModeAndroid.hpp +62 -0
  22. package/nitrogen/generated/android/c++/JExternalLinkTypeAndroid.hpp +62 -0
  23. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +88 -4
  24. package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +4 -0
  25. package/nitrogen/generated/android/c++/JNitroBillingProgramAvailabilityResultAndroid.hpp +62 -0
  26. package/nitrogen/generated/android/c++/JNitroBillingProgramReportingDetailsAndroid.hpp +63 -0
  27. package/nitrogen/generated/android/c++/JNitroLaunchExternalLinkParamsAndroid.hpp +75 -0
  28. package/nitrogen/generated/android/c++/JNitroReceiptValidationAppleOptions.hpp +57 -0
  29. package/nitrogen/generated/android/c++/{JNitroReceiptValidationAndroidOptions.hpp → JNitroReceiptValidationGoogleOptions.hpp} +18 -14
  30. package/nitrogen/generated/android/c++/JNitroReceiptValidationHorizonOptions.hpp +65 -0
  31. package/nitrogen/generated/android/c++/JNitroReceiptValidationParams.hpp +19 -11
  32. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/BillingProgramAndroid.kt +22 -0
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/ExternalLinkLaunchModeAndroid.kt +22 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/ExternalLinkTypeAndroid.kt +22 -0
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +16 -0
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroBillingProgramAvailabilityResultAndroid.kt +39 -0
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroBillingProgramReportingDetailsAndroid.kt +39 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroLaunchExternalLinkParamsAndroid.kt +45 -0
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationAppleOptions.kt +36 -0
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/{NitroReceiptValidationAndroidOptions.kt → NitroReceiptValidationGoogleOptions.kt} +9 -6
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationHorizonOptions.kt +42 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationParams.kt +7 -4
  43. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.cpp +16 -0
  44. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +141 -10
  45. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +27 -3
  46. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +57 -3
  47. package/nitrogen/generated/ios/swift/BillingProgramAndroid.swift +44 -0
  48. package/nitrogen/generated/ios/swift/ExternalLinkLaunchModeAndroid.swift +44 -0
  49. package/nitrogen/generated/ios/swift/ExternalLinkTypeAndroid.swift +44 -0
  50. package/nitrogen/generated/ios/swift/Func_void_NitroBillingProgramAvailabilityResultAndroid.swift +47 -0
  51. package/nitrogen/generated/ios/swift/Func_void_NitroBillingProgramReportingDetailsAndroid.swift +47 -0
  52. package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +4 -0
  53. package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +68 -0
  54. package/nitrogen/generated/ios/swift/NitroBillingProgramAvailabilityResultAndroid.swift +46 -0
  55. package/nitrogen/generated/ios/swift/NitroBillingProgramReportingDetailsAndroid.swift +46 -0
  56. package/nitrogen/generated/ios/swift/NitroLaunchExternalLinkParamsAndroid.swift +68 -0
  57. package/nitrogen/generated/ios/swift/NitroReceiptValidationAppleOptions.swift +35 -0
  58. package/nitrogen/generated/ios/swift/{NitroReceiptValidationAndroidOptions.swift → NitroReceiptValidationGoogleOptions.swift} +21 -10
  59. package/nitrogen/generated/ios/swift/NitroReceiptValidationHorizonOptions.swift +57 -0
  60. package/nitrogen/generated/ios/swift/NitroReceiptValidationParams.swift +46 -11
  61. package/nitrogen/generated/shared/c++/BillingProgramAndroid.hpp +80 -0
  62. package/nitrogen/generated/shared/c++/ExternalLinkLaunchModeAndroid.hpp +80 -0
  63. package/nitrogen/generated/shared/c++/ExternalLinkTypeAndroid.hpp +80 -0
  64. package/nitrogen/generated/shared/c++/HybridRnIapSpec.cpp +4 -0
  65. package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +16 -0
  66. package/nitrogen/generated/shared/c++/NitroBillingProgramAvailabilityResultAndroid.hpp +80 -0
  67. package/nitrogen/generated/shared/c++/NitroBillingProgramReportingDetailsAndroid.hpp +81 -0
  68. package/nitrogen/generated/shared/c++/NitroLaunchExternalLinkParamsAndroid.hpp +95 -0
  69. package/nitrogen/generated/shared/c++/NitroReceiptValidationAppleOptions.hpp +75 -0
  70. package/nitrogen/generated/shared/c++/{NitroReceiptValidationAndroidOptions.hpp → NitroReceiptValidationGoogleOptions.hpp} +18 -14
  71. package/nitrogen/generated/shared/c++/NitroReceiptValidationHorizonOptions.hpp +83 -0
  72. package/nitrogen/generated/shared/c++/NitroReceiptValidationParams.hpp +22 -13
  73. package/openiap-versions.json +3 -3
  74. package/package.json +1 -1
  75. package/plugin/build/withIAP.d.ts +6 -0
  76. package/plugin/build/withIAP.js +46 -2
  77. package/plugin/src/withIAP.ts +67 -2
  78. package/src/hooks/useIAP.ts +8 -23
  79. package/src/index.ts +297 -14
  80. package/src/specs/RnIap.nitro.ts +125 -10
  81. package/src/types.ts +207 -10
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  <img src="https://hyochan.github.io/react-native-iap/img/icon.png" alt="React Native IAP Logo" width="150" />
5
5
 
6
6
  [![Version](http://img.shields.io/npm/v/react-native-iap.svg?style=flat-square)](https://npmjs.org/package/react-native-iap)
7
+ [![Next Version](https://img.shields.io/npm/v/react-native-iap/next.svg?style=flat-square&label=next)](https://npmjs.org/package/react-native-iap)
7
8
  [![Download](http://img.shields.io/npm/dm/react-native-iap.svg?style=flat-square)](https://npmjs.org/package/react-native-iap)
8
9
  [![Backers and Sponsors](https://img.shields.io/opencollective/all/react-native-iap.svg)](https://opencollective.com/react-native-iap)
9
10
  [![CI - Test](https://github.com/hyochan/react-native-iap/actions/workflows/ci-test.yml/badge.svg)](https://github.com/hyochan/react-native-iap/actions/workflows/ci-test.yml)
@@ -27,10 +27,18 @@ import dev.hyo.openiap.RequestPurchaseResultPurchase
27
27
  import dev.hyo.openiap.RequestPurchaseResultPurchases
28
28
  import dev.hyo.openiap.RequestSubscriptionAndroidProps
29
29
  import dev.hyo.openiap.RequestSubscriptionPropsByPlatforms
30
+ import dev.hyo.openiap.VerifyPurchaseGoogleOptions
31
+ import dev.hyo.openiap.VerifyPurchaseProps
32
+ import dev.hyo.openiap.VerifyPurchaseResultAndroid
30
33
  import dev.hyo.openiap.InitConnectionConfig as OpenIapInitConnectionConfig
31
34
  import dev.hyo.openiap.listener.OpenIapPurchaseErrorListener
32
35
  import dev.hyo.openiap.listener.OpenIapPurchaseUpdateListener
33
36
  import dev.hyo.openiap.listener.OpenIapUserChoiceBillingListener
37
+ import dev.hyo.openiap.BillingProgramAndroid as OpenIapBillingProgramAndroid
38
+ import dev.hyo.openiap.LaunchExternalLinkParamsAndroid as OpenIapLaunchExternalLinkParams
39
+ import dev.hyo.openiap.ExternalLinkLaunchModeAndroid as OpenIapExternalLinkLaunchMode
40
+ import dev.hyo.openiap.ExternalLinkTypeAndroid as OpenIapExternalLinkType
41
+ import dev.hyo.openiap.store.OpenIapStore
34
42
  import kotlinx.coroutines.Dispatchers
35
43
  import kotlinx.coroutines.withContext
36
44
  import kotlinx.coroutines.CompletableDeferred
@@ -1114,51 +1122,84 @@ class HybridRnIap : HybridRnIapSpec() {
1114
1122
  }
1115
1123
  }
1116
1124
 
1117
- // Receipt validation
1125
+ // Receipt validation - calls OpenIAP's verifyPurchase
1118
1126
  override fun validateReceipt(params: NitroReceiptValidationParams): Promise<Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid> {
1119
1127
  return Promise.async {
1120
1128
  try {
1121
- // For Android, we need the androidOptions to be provided
1122
- val androidOptions = params.androidOptions
1123
- ?: throw OpenIapException(toErrorJson(OpenIAPError.DeveloperError))
1124
-
1125
- // Android receipt validation would typically involve server-side validation
1126
- // using Google Play Developer API. Here we provide a simplified implementation
1127
- // that demonstrates the expected structure.
1128
-
1129
- // In a real implementation, you would make an HTTP request to Google Play API
1130
- // using the androidOptions.accessToken, androidOptions.packageName, etc.
1131
-
1132
- // For now, we'll return a mock successful validation result
1133
- // This should be replaced with actual Google Play Developer API calls
1134
- val currentTime = System.currentTimeMillis()
1135
-
1129
+ // For Android, we need the google options to be provided (new platform-specific structure)
1130
+ val nitroGoogleOptions = params.google
1131
+ ?: throw OpenIapException(toErrorJson(OpenIAPError.DeveloperError, debugMessage = "Missing required parameter: google options"))
1132
+
1133
+ // Validate required google fields
1134
+ val validations = mapOf(
1135
+ "google.sku" to nitroGoogleOptions.sku,
1136
+ "google.accessToken" to nitroGoogleOptions.accessToken,
1137
+ "google.packageName" to nitroGoogleOptions.packageName,
1138
+ "google.purchaseToken" to nitroGoogleOptions.purchaseToken
1139
+ )
1140
+ for ((name, value) in validations) {
1141
+ if (value.isEmpty()) {
1142
+ throw OpenIapException(toErrorJson(OpenIAPError.DeveloperError, debugMessage = "Missing or empty required parameter: $name"))
1143
+ }
1144
+ }
1145
+
1146
+ RnIapLog.payload("validateReceipt", mapOf(
1147
+ "sku" to nitroGoogleOptions.sku,
1148
+ "packageName" to nitroGoogleOptions.packageName,
1149
+ "isSub" to nitroGoogleOptions.isSub
1150
+ ))
1151
+
1152
+ // Create OpenIAP VerifyPurchaseGoogleOptions
1153
+ val googleOptions = VerifyPurchaseGoogleOptions(
1154
+ sku = nitroGoogleOptions.sku,
1155
+ accessToken = nitroGoogleOptions.accessToken,
1156
+ packageName = nitroGoogleOptions.packageName,
1157
+ purchaseToken = nitroGoogleOptions.purchaseToken,
1158
+ isSub = nitroGoogleOptions.isSub
1159
+ )
1160
+
1161
+ // Create OpenIAP VerifyPurchaseProps
1162
+ val props = VerifyPurchaseProps(google = googleOptions)
1163
+
1164
+ // Call OpenIAP's verifyPurchase - this makes the actual Google Play API call
1165
+ val verifyResult = openIap.verifyPurchase(props)
1166
+ RnIapLog.result("validateReceipt", verifyResult.toString())
1167
+
1168
+ // Cast to Android result type (on Android, verifyPurchase returns VerifyPurchaseResultAndroid)
1169
+ val androidResult = verifyResult as? VerifyPurchaseResultAndroid
1170
+ ?: throw OpenIapException(toErrorJson(OpenIAPError.InvalidPurchaseVerification, debugMessage = "Unexpected result type from verifyPurchase"))
1171
+
1172
+ // Convert OpenIAP result to Nitro result
1136
1173
  val result = NitroReceiptValidationResultAndroid(
1137
- autoRenewing = androidOptions.isSub ?: false,
1138
- betaProduct = false,
1139
- cancelDate = null,
1140
- cancelReason = "",
1141
- deferredDate = null,
1142
- deferredSku = null,
1143
- freeTrialEndDate = 0.0,
1144
- gracePeriodEndDate = 0.0,
1145
- parentProductId = params.sku,
1146
- productId = params.sku,
1147
- productType = if (androidOptions.isSub == true) "subs" else "inapp",
1148
- purchaseDate = currentTime.toDouble(),
1149
- quantity = 1.0,
1150
- receiptId = androidOptions.productToken,
1151
- renewalDate = if (androidOptions.isSub == true) (currentTime + (30L * 24 * 60 * 60 * 1000)).toDouble() else 0.0, // 30 days from now if subscription
1152
- term = if (androidOptions.isSub == true) "P1M" else "", // P1M = 1 month
1153
- termSku = params.sku,
1154
- testTransaction = false
1174
+ autoRenewing = androidResult.autoRenewing,
1175
+ betaProduct = androidResult.betaProduct,
1176
+ cancelDate = androidResult.cancelDate,
1177
+ cancelReason = androidResult.cancelReason,
1178
+ deferredDate = androidResult.deferredDate,
1179
+ deferredSku = androidResult.deferredSku,
1180
+ freeTrialEndDate = androidResult.freeTrialEndDate,
1181
+ gracePeriodEndDate = androidResult.gracePeriodEndDate,
1182
+ parentProductId = androidResult.parentProductId,
1183
+ productId = androidResult.productId,
1184
+ productType = androidResult.productType,
1185
+ purchaseDate = androidResult.purchaseDate,
1186
+ quantity = androidResult.quantity.toDouble(),
1187
+ receiptId = androidResult.receiptId,
1188
+ renewalDate = androidResult.renewalDate,
1189
+ term = androidResult.term,
1190
+ termSku = androidResult.termSku,
1191
+ testTransaction = androidResult.testTransaction
1155
1192
  )
1156
-
1193
+
1157
1194
  Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.Second(result)
1158
1195
 
1196
+ } catch (e: OpenIapException) {
1197
+ RnIapLog.failure("validateReceipt", e)
1198
+ throw e
1159
1199
  } catch (e: Exception) {
1200
+ RnIapLog.failure("validateReceipt", e)
1160
1201
  val debugMessage = e.message
1161
- val error = OpenIAPError.InvalidReceipt
1202
+ val error = OpenIAPError.InvalidPurchaseVerification
1162
1203
  throw OpenIapException(
1163
1204
  toErrorJson(
1164
1205
  error = error,
@@ -1381,6 +1422,127 @@ class HybridRnIap : HybridRnIapSpec() {
1381
1422
  }
1382
1423
  }
1383
1424
 
1425
+ // -------------------------------------------------------------------------
1426
+ // Billing Programs API (Android 8.2.0+)
1427
+ // -------------------------------------------------------------------------
1428
+
1429
+ // Create OpenIapStore lazily for Billing Programs API
1430
+ private val openIapStore: OpenIapStore by lazy { OpenIapStore(context) }
1431
+
1432
+ override fun enableBillingProgramAndroid(program: BillingProgramAndroid) {
1433
+ RnIapLog.payload("enableBillingProgramAndroid", mapOf("program" to program.name))
1434
+ try {
1435
+ val openIapProgram = mapBillingProgram(program)
1436
+ openIapStore.enableBillingProgram(openIapProgram)
1437
+ RnIapLog.result("enableBillingProgramAndroid", true)
1438
+ } catch (err: Throwable) {
1439
+ RnIapLog.failure("enableBillingProgramAndroid", err)
1440
+ // enableBillingProgram is void, so we just log the error
1441
+ }
1442
+ }
1443
+
1444
+ override fun isBillingProgramAvailableAndroid(program: BillingProgramAndroid): Promise<NitroBillingProgramAvailabilityResultAndroid> {
1445
+ return Promise.async {
1446
+ RnIapLog.payload("isBillingProgramAvailableAndroid", mapOf("program" to program.name))
1447
+ try {
1448
+ initConnection(null).await()
1449
+ val openIapProgram = mapBillingProgram(program)
1450
+ val result = openIapStore.isBillingProgramAvailable(openIapProgram)
1451
+ val nitroResult = NitroBillingProgramAvailabilityResultAndroid(
1452
+ billingProgram = program,
1453
+ isAvailable = result.isAvailable
1454
+ )
1455
+ RnIapLog.result("isBillingProgramAvailableAndroid", mapOf("isAvailable" to result.isAvailable))
1456
+ nitroResult
1457
+ } catch (err: Throwable) {
1458
+ RnIapLog.failure("isBillingProgramAvailableAndroid", err)
1459
+ val errorType = parseOpenIapError(err)
1460
+ throw OpenIapException(toErrorJson(errorType, debugMessage = err.message))
1461
+ }
1462
+ }
1463
+ }
1464
+
1465
+ override fun createBillingProgramReportingDetailsAndroid(program: BillingProgramAndroid): Promise<NitroBillingProgramReportingDetailsAndroid> {
1466
+ return Promise.async {
1467
+ RnIapLog.payload("createBillingProgramReportingDetailsAndroid", mapOf("program" to program.name))
1468
+ try {
1469
+ initConnection(null).await()
1470
+ val openIapProgram = mapBillingProgram(program)
1471
+ val result = openIapStore.createBillingProgramReportingDetails(openIapProgram)
1472
+ val nitroResult = NitroBillingProgramReportingDetailsAndroid(
1473
+ billingProgram = program,
1474
+ externalTransactionToken = result.externalTransactionToken
1475
+ )
1476
+ RnIapLog.result("createBillingProgramReportingDetailsAndroid", mapOf("hasToken" to true))
1477
+ nitroResult
1478
+ } catch (err: Throwable) {
1479
+ RnIapLog.failure("createBillingProgramReportingDetailsAndroid", err)
1480
+ val errorType = parseOpenIapError(err)
1481
+ throw OpenIapException(toErrorJson(errorType, debugMessage = err.message))
1482
+ }
1483
+ }
1484
+ }
1485
+
1486
+ override fun launchExternalLinkAndroid(params: NitroLaunchExternalLinkParamsAndroid): Promise<Boolean> {
1487
+ return Promise.async {
1488
+ RnIapLog.payload("launchExternalLinkAndroid", mapOf(
1489
+ "billingProgram" to params.billingProgram.name,
1490
+ "launchMode" to params.launchMode.name,
1491
+ "linkType" to params.linkType.name,
1492
+ "linkUri" to params.linkUri
1493
+ ))
1494
+ try {
1495
+ initConnection(null).await()
1496
+
1497
+ val activity = withContext(Dispatchers.Main) {
1498
+ runCatching { context.currentActivity }.getOrNull()
1499
+ } ?: throw OpenIapException(toErrorJson(OpenIAPError.DeveloperError, debugMessage = "Activity not available"))
1500
+
1501
+ val openIapParams = OpenIapLaunchExternalLinkParams(
1502
+ billingProgram = mapBillingProgram(params.billingProgram),
1503
+ launchMode = mapExternalLinkLaunchMode(params.launchMode),
1504
+ linkType = mapExternalLinkType(params.linkType),
1505
+ linkUri = params.linkUri
1506
+ )
1507
+
1508
+ val result = withContext(Dispatchers.Main) {
1509
+ openIapStore.launchExternalLink(activity, openIapParams)
1510
+ }
1511
+ RnIapLog.result("launchExternalLinkAndroid", result)
1512
+ result
1513
+ } catch (err: Throwable) {
1514
+ RnIapLog.failure("launchExternalLinkAndroid", err)
1515
+ val errorType = parseOpenIapError(err)
1516
+ throw OpenIapException(toErrorJson(errorType, debugMessage = err.message))
1517
+ }
1518
+ }
1519
+ }
1520
+
1521
+ // Billing Programs helper functions
1522
+ private fun mapBillingProgram(program: BillingProgramAndroid): OpenIapBillingProgramAndroid {
1523
+ return when (program) {
1524
+ BillingProgramAndroid.UNSPECIFIED -> OpenIapBillingProgramAndroid.Unspecified
1525
+ BillingProgramAndroid.EXTERNAL_CONTENT_LINK -> OpenIapBillingProgramAndroid.ExternalContentLink
1526
+ BillingProgramAndroid.EXTERNAL_OFFER -> OpenIapBillingProgramAndroid.ExternalOffer
1527
+ }
1528
+ }
1529
+
1530
+ private fun mapExternalLinkLaunchMode(mode: ExternalLinkLaunchModeAndroid): OpenIapExternalLinkLaunchMode {
1531
+ return when (mode) {
1532
+ ExternalLinkLaunchModeAndroid.UNSPECIFIED -> OpenIapExternalLinkLaunchMode.Unspecified
1533
+ ExternalLinkLaunchModeAndroid.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP -> OpenIapExternalLinkLaunchMode.LaunchInExternalBrowserOrApp
1534
+ ExternalLinkLaunchModeAndroid.CALLER_WILL_LAUNCH_LINK -> OpenIapExternalLinkLaunchMode.CallerWillLaunchLink
1535
+ }
1536
+ }
1537
+
1538
+ private fun mapExternalLinkType(type: ExternalLinkTypeAndroid): OpenIapExternalLinkType {
1539
+ return when (type) {
1540
+ ExternalLinkTypeAndroid.UNSPECIFIED -> OpenIapExternalLinkType.Unspecified
1541
+ ExternalLinkTypeAndroid.LINK_TO_DIGITAL_CONTENT_OFFER -> OpenIapExternalLinkType.LinkToDigitalContentOffer
1542
+ ExternalLinkTypeAndroid.LINK_TO_APP_DOWNLOAD -> OpenIapExternalLinkType.LinkToAppDownload
1543
+ }
1544
+ }
1545
+
1384
1546
  // -------------------------------------------------------------------------
1385
1547
  // External Purchase (iOS) - Not supported on Android
1386
1548
  // -------------------------------------------------------------------------
@@ -319,8 +319,14 @@ class HybridRnIap: HybridRnIapSpec {
319
319
  func validateReceipt(params: NitroReceiptValidationParams) throws -> Promise<Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid> {
320
320
  return Promise.async {
321
321
  do {
322
- RnIapLog.payload("validateReceiptIOS", ["sku": params.sku])
323
- let props = try OpenIapSerialization.verifyPurchaseProps(from: ["sku": params.sku])
322
+ // Extract SKU from apple options (new platform-specific structure)
323
+ guard let appleOptions = params.apple, !appleOptions.sku.isEmpty else {
324
+ throw PurchaseError.make(code: .developerError, message: "Missing required parameter: apple.sku")
325
+ }
326
+ let sku = appleOptions.sku
327
+
328
+ RnIapLog.payload("validateReceiptIOS", ["sku": sku])
329
+ let props = try OpenIapSerialization.verifyPurchaseProps(from: ["apple": ["sku": sku]])
324
330
  let result = try await OpenIapModule.shared.validateReceiptIOS(props)
325
331
  var encoded = RnIapHelper.sanitizeDictionary(OpenIapSerialization.encode(result))
326
332
  if encoded["receiptData"] != nil {
@@ -1047,6 +1053,30 @@ class HybridRnIap: HybridRnIapSpec {
1047
1053
  // No-op on iOS
1048
1054
  }
1049
1055
 
1056
+ // MARK: - Billing Programs API (Android 8.2.0+) - Not supported on iOS
1057
+
1058
+ func enableBillingProgramAndroid(program: BillingProgramAndroid) throws {
1059
+ // No-op on iOS - Billing Programs are Android-only
1060
+ }
1061
+
1062
+ func isBillingProgramAvailableAndroid(program: BillingProgramAndroid) throws -> Promise<NitroBillingProgramAvailabilityResultAndroid> {
1063
+ return Promise.async {
1064
+ throw PurchaseError.make(code: .featureNotSupported, message: "Billing Programs API is Android-only")
1065
+ }
1066
+ }
1067
+
1068
+ func createBillingProgramReportingDetailsAndroid(program: BillingProgramAndroid) throws -> Promise<NitroBillingProgramReportingDetailsAndroid> {
1069
+ return Promise.async {
1070
+ throw PurchaseError.make(code: .featureNotSupported, message: "Billing Programs API is Android-only")
1071
+ }
1072
+ }
1073
+
1074
+ func launchExternalLinkAndroid(params: NitroLaunchExternalLinkParamsAndroid) throws -> Promise<Bool> {
1075
+ return Promise.async {
1076
+ throw PurchaseError.make(code: .featureNotSupported, message: "Billing Programs API is Android-only")
1077
+ }
1078
+ }
1079
+
1050
1080
  // MARK: - External Purchase (iOS 16.0+)
1051
1081
 
1052
1082
  func canPresentExternalPurchaseNoticeIOS() throws -> Promise<Bool> {
@@ -132,12 +132,7 @@ export function useIAP(options) {
132
132
 
133
133
  // No local restorePurchases; use the top-level helper via returned API
134
134
 
135
- const validateReceipt = useCallback(async (sku, androidOptions) => {
136
- return validateReceiptInternal({
137
- sku,
138
- androidOptions
139
- });
140
- }, []);
135
+ const validateReceipt = useCallback(async options => validateReceiptInternal(options), []);
141
136
  const verifyPurchase = useCallback(async options => {
142
137
  return verifyPurchaseTopLevel(options);
143
138
  }, []);
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useEffect","useState","useRef","Platform","RnIapConsole","initConnection","purchaseErrorListener","purchaseUpdatedListener","promotedProductListenerIOS","getAvailablePurchases","finishTransaction","finishTransactionInternal","requestPurchase","requestPurchaseInternal","fetchProducts","validateReceipt","validateReceiptInternal","verifyPurchase","verifyPurchaseTopLevel","verifyPurchaseWithProvider","verifyPurchaseWithProviderTopLevel","getActiveSubscriptions","hasActiveSubscriptions","restorePurchases","restorePurchasesTopLevel","getPromotedProductIOS","requestPurchaseOnPromotedProductIOS","checkAlternativeBillingAvailabilityAndroid","showAlternativeBillingDialogAndroid","createAlternativeBillingTokenAndroid","userChoiceBillingListenerAndroid","ErrorCode","normalizeErrorCodeFromNative","useIAP","options","connected","setConnected","products","setProducts","subscriptions","setSubscriptions","availablePurchases","setAvailablePurchases","promotedProductIOS","setPromotedProductIOS","activeSubscriptions","setActiveSubscriptions","optionsRef","connectedRef","mergeWithDuplicateCheck","existingItems","newItems","getKey","merged","forEach","newItem","isDuplicate","some","existingItem","push","current","subscriptionsRef","subscriptionsRefState","fetchProductsInternal","params","warn","requestType","type","debug","skus","result","items","prevSubscriptions","subscription","id","newProducts","filter","item","newSubscriptions","prevProducts","product","error","getAvailablePurchasesInternal","_skus","alsoPublishToEventListenerIOS","onlyIncludeActiveItemsIOS","getActiveSubscriptionsInternal","subscriptionIds","hasActiveSubscriptionsInternal","args","requestObj","sku","androidOptions","initIapWithSubscriptions","purchaseUpdate","purchase","e","onPurchaseSuccess","purchaseError","mappedError","code","message","productId","undefined","InitConnection","onPurchaseError","OS","onPromotedProductIOS","onUserChoiceBillingAndroid","userChoiceBillingAndroid","details","config","alternativeBillingModeAndroid","remove","currentSubscriptions"],"sourceRoot":"../../../src","sources":["hooks/useIAP.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useCallback","useEffect","useState","useRef","Platform","RnIapConsole","initConnection","purchaseErrorListener","purchaseUpdatedListener","promotedProductListenerIOS","getAvailablePurchases","finishTransaction","finishTransactionInternal","requestPurchase","requestPurchaseInternal","fetchProducts","validateReceipt","validateReceiptInternal","verifyPurchase","verifyPurchaseTopLevel","verifyPurchaseWithProvider","verifyPurchaseWithProviderTopLevel","getActiveSubscriptions","hasActiveSubscriptions","restorePurchases","restorePurchasesTopLevel","getPromotedProductIOS","requestPurchaseOnPromotedProductIOS","checkAlternativeBillingAvailabilityAndroid","showAlternativeBillingDialogAndroid","createAlternativeBillingTokenAndroid","userChoiceBillingListenerAndroid","ErrorCode","normalizeErrorCodeFromNative","useIAP","options","connected","setConnected","products","setProducts","subscriptions","setSubscriptions","availablePurchases","setAvailablePurchases","promotedProductIOS","setPromotedProductIOS","activeSubscriptions","setActiveSubscriptions","optionsRef","connectedRef","mergeWithDuplicateCheck","existingItems","newItems","getKey","merged","forEach","newItem","isDuplicate","some","existingItem","push","current","subscriptionsRef","subscriptionsRefState","fetchProductsInternal","params","warn","requestType","type","debug","skus","result","items","prevSubscriptions","subscription","id","newProducts","filter","item","newSubscriptions","prevProducts","product","error","getAvailablePurchasesInternal","_skus","alsoPublishToEventListenerIOS","onlyIncludeActiveItemsIOS","getActiveSubscriptionsInternal","subscriptionIds","hasActiveSubscriptionsInternal","args","requestObj","initIapWithSubscriptions","purchaseUpdate","purchase","e","onPurchaseSuccess","purchaseError","mappedError","code","message","productId","undefined","InitConnection","onPurchaseError","OS","onPromotedProductIOS","onUserChoiceBillingAndroid","userChoiceBillingAndroid","details","config","alternativeBillingModeAndroid","remove","currentSubscriptions"],"sourceRoot":"../../../src","sources":["hooks/useIAP.ts"],"mappings":"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","ignoreList":[]}
@@ -1009,23 +1009,75 @@ export const consumePurchaseAndroid = async purchaseToken => {
1009
1009
 
1010
1010
  /**
1011
1011
  * Validate receipt on both iOS and Android platforms
1012
- * @param sku - Product SKU
1013
- * @param androidOptions - Android-specific validation options (required for Android)
1012
+ * @deprecated Use `verifyPurchase` instead. This function will be removed in a future version.
1013
+ * @param options - Platform-specific verification options
1014
+ * @param options.apple - Apple App Store verification options (iOS)
1015
+ * @param options.google - Google Play verification options (Android)
1016
+ * @param options.horizon - Meta Horizon (Quest) verification options
1014
1017
  * @returns Promise<VerifyPurchaseResultIOS | VerifyPurchaseResultAndroid> - Platform-specific receipt validation result
1018
+ *
1019
+ * @example
1020
+ * ```typescript
1021
+ * // Use verifyPurchase instead:
1022
+ * const result = await verifyPurchase({
1023
+ * apple: { sku: 'premium_monthly' },
1024
+ * google: {
1025
+ * sku: 'premium_monthly',
1026
+ * packageName: 'com.example.app',
1027
+ * purchaseToken: 'token...',
1028
+ * accessToken: 'oauth_token...',
1029
+ * isSub: true
1030
+ * }
1031
+ * });
1032
+ * ```
1015
1033
  */
1016
1034
  export const validateReceipt = async options => {
1017
1035
  const {
1018
- sku,
1019
- androidOptions
1036
+ apple,
1037
+ google,
1038
+ horizon
1020
1039
  } = options;
1021
1040
  try {
1022
- const normalizedAndroidOptions = androidOptions != null ? {
1023
- ...androidOptions,
1024
- isSub: androidOptions.isSub == null ? undefined : Boolean(androidOptions.isSub)
1025
- } : undefined;
1041
+ // Validate required fields based on platform
1042
+ if (Platform.OS === 'ios') {
1043
+ if (!apple?.sku) {
1044
+ throw new Error('Missing required parameter: apple.sku');
1045
+ }
1046
+ } else if (Platform.OS === 'android') {
1047
+ // Horizon verification path (e.g., Meta Quest) - skip Google validation
1048
+ if (horizon?.sku) {
1049
+ // Validate all required Horizon fields
1050
+ if (!horizon.userId || !horizon.accessToken) {
1051
+ throw new Error('Missing required Horizon parameters: userId and accessToken are required when horizon.sku is provided');
1052
+ }
1053
+ // Horizon verification will be handled by native layer
1054
+ } else if (!google) {
1055
+ throw new Error('Missing required parameter: google options');
1056
+ } else {
1057
+ const requiredFields = ['sku', 'accessToken', 'packageName', 'purchaseToken'];
1058
+ for (const field of requiredFields) {
1059
+ if (!google[field]) {
1060
+ throw new Error(`Missing or empty required parameter: google.${field}`);
1061
+ }
1062
+ }
1063
+ }
1064
+ }
1026
1065
  const params = {
1027
- sku,
1028
- androidOptions: normalizedAndroidOptions
1066
+ apple: apple?.sku ? {
1067
+ sku: apple.sku
1068
+ } : null,
1069
+ google: google?.sku && google.accessToken && google.packageName && google.purchaseToken ? {
1070
+ sku: google.sku,
1071
+ accessToken: google.accessToken,
1072
+ packageName: google.packageName,
1073
+ purchaseToken: google.purchaseToken,
1074
+ isSub: google.isSub == null ? undefined : Boolean(google.isSub)
1075
+ } : null,
1076
+ horizon: horizon?.sku && horizon.userId && horizon.accessToken ? {
1077
+ sku: horizon.sku,
1078
+ userId: horizon.userId,
1079
+ accessToken: horizon.accessToken
1080
+ } : null
1029
1081
  };
1030
1082
  const nitroResult = await IAP.instance.validateReceipt(params);
1031
1083
 
@@ -1745,6 +1797,172 @@ export const createAlternativeBillingTokenAndroid = async sku => {
1745
1797
  }
1746
1798
  };
1747
1799
 
1800
+ // ------------------------------
1801
+ // Billing Programs API (Android 8.2.0+)
1802
+ // ------------------------------
1803
+
1804
+ /**
1805
+ * Billing program type for external content links and external offers.
1806
+ * @platform Android
1807
+ * @since Google Play Billing Library 8.2.0+
1808
+ */
1809
+
1810
+ /**
1811
+ * Launch mode for external link flow.
1812
+ * @platform Android
1813
+ * @since Google Play Billing Library 8.2.0+
1814
+ */
1815
+
1816
+ /**
1817
+ * Link type for external link flow.
1818
+ * @platform Android
1819
+ * @since Google Play Billing Library 8.2.0+
1820
+ */
1821
+
1822
+ /**
1823
+ * Parameters for launching an external link (Android 8.2.0+).
1824
+ */
1825
+
1826
+ /**
1827
+ * Result of checking billing program availability (Android 8.2.0+).
1828
+ */
1829
+
1830
+ /**
1831
+ * Reporting details for external transactions (Android 8.2.0+).
1832
+ */
1833
+
1834
+ /**
1835
+ * Enable a billing program before initConnection (Android only).
1836
+ * Must be called BEFORE initConnection() to configure the BillingClient.
1837
+ *
1838
+ * @param program - The billing program to enable (external-content-link or external-offer)
1839
+ * @platform Android
1840
+ * @since Google Play Billing Library 8.2.0+
1841
+ *
1842
+ * @example
1843
+ * ```typescript
1844
+ * // Enable external offers before connecting
1845
+ * enableBillingProgramAndroid('external-offer');
1846
+ * await initConnection();
1847
+ * ```
1848
+ */
1849
+ export const enableBillingProgramAndroid = program => {
1850
+ if (Platform.OS !== 'android') {
1851
+ RnIapConsole.warn('enableBillingProgramAndroid is only supported on Android');
1852
+ return;
1853
+ }
1854
+ try {
1855
+ IAP.instance.enableBillingProgramAndroid(program);
1856
+ } catch (error) {
1857
+ RnIapConsole.error('Failed to enable billing program:', error);
1858
+ }
1859
+ };
1860
+
1861
+ /**
1862
+ * Check if a billing program is available for this user/device (Android only).
1863
+ *
1864
+ * @param program - The billing program to check
1865
+ * @returns Promise with availability result
1866
+ * @platform Android
1867
+ * @since Google Play Billing Library 8.2.0+
1868
+ *
1869
+ * @example
1870
+ * ```typescript
1871
+ * const result = await isBillingProgramAvailableAndroid('external-offer');
1872
+ * if (result.isAvailable) {
1873
+ * // External offers are available for this user
1874
+ * }
1875
+ * ```
1876
+ */
1877
+ export const isBillingProgramAvailableAndroid = async program => {
1878
+ if (Platform.OS !== 'android') {
1879
+ throw new Error('Billing Programs API is only supported on Android');
1880
+ }
1881
+ try {
1882
+ const result = await IAP.instance.isBillingProgramAvailableAndroid(program);
1883
+ return {
1884
+ billingProgram: result.billingProgram,
1885
+ isAvailable: result.isAvailable
1886
+ };
1887
+ } catch (error) {
1888
+ RnIapConsole.error('Failed to check billing program availability:', error);
1889
+ throw error;
1890
+ }
1891
+ };
1892
+
1893
+ /**
1894
+ * Create billing program reporting details for external transactions (Android only).
1895
+ * Used to get the external transaction token needed for reporting to Google.
1896
+ *
1897
+ * @param program - The billing program to create reporting details for
1898
+ * @returns Promise with reporting details including external transaction token
1899
+ * @platform Android
1900
+ * @since Google Play Billing Library 8.2.0+
1901
+ *
1902
+ * @example
1903
+ * ```typescript
1904
+ * const details = await createBillingProgramReportingDetailsAndroid('external-offer');
1905
+ * // Use details.externalTransactionToken to report the transaction
1906
+ * await fetch('/api/report-external-transaction', {
1907
+ * method: 'POST',
1908
+ * body: JSON.stringify({ token: details.externalTransactionToken })
1909
+ * });
1910
+ * ```
1911
+ */
1912
+ export const createBillingProgramReportingDetailsAndroid = async program => {
1913
+ if (Platform.OS !== 'android') {
1914
+ throw new Error('Billing Programs API is only supported on Android');
1915
+ }
1916
+ try {
1917
+ const result = await IAP.instance.createBillingProgramReportingDetailsAndroid(program);
1918
+ return {
1919
+ billingProgram: result.billingProgram,
1920
+ externalTransactionToken: result.externalTransactionToken
1921
+ };
1922
+ } catch (error) {
1923
+ RnIapConsole.error('Failed to create billing program reporting details:', error);
1924
+ throw error;
1925
+ }
1926
+ };
1927
+
1928
+ /**
1929
+ * Launch external link for external offers or app download (Android only).
1930
+ *
1931
+ * @param params - Parameters for launching the external link
1932
+ * @returns Promise<boolean> - true if user accepted, false otherwise
1933
+ * @platform Android
1934
+ * @since Google Play Billing Library 8.2.0+
1935
+ *
1936
+ * @example
1937
+ * ```typescript
1938
+ * const success = await launchExternalLinkAndroid({
1939
+ * billingProgram: 'external-offer',
1940
+ * launchMode: 'launch-in-external-browser-or-app',
1941
+ * linkType: 'link-to-digital-content-offer',
1942
+ * linkUri: 'https://your-website.com/purchase'
1943
+ * });
1944
+ * if (success) {
1945
+ * console.log('User accepted external link');
1946
+ * }
1947
+ * ```
1948
+ */
1949
+ export const launchExternalLinkAndroid = async params => {
1950
+ if (Platform.OS !== 'android') {
1951
+ throw new Error('Billing Programs API is only supported on Android');
1952
+ }
1953
+ try {
1954
+ return await IAP.instance.launchExternalLinkAndroid({
1955
+ billingProgram: params.billingProgram,
1956
+ launchMode: params.launchMode,
1957
+ linkType: params.linkType,
1958
+ linkUri: params.linkUri
1959
+ });
1960
+ } catch (error) {
1961
+ RnIapConsole.error('Failed to launch external link:', error);
1962
+ throw error;
1963
+ }
1964
+ };
1965
+
1748
1966
  // ------------------------------
1749
1967
  // iOS External Purchase
1750
1968
  // ------------------------------