react-native-iap 13.0.4 → 14.0.0-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 (381) hide show
  1. package/NitroIap.podspec +33 -0
  2. package/README.md +163 -51
  3. package/android/CMakeLists.txt +32 -0
  4. package/android/build.gradle +107 -138
  5. package/android/fix-prefab.gradle +51 -0
  6. package/android/gradle.properties +5 -13
  7. package/android/src/main/AndroidManifest.xml +1 -4
  8. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  9. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +843 -0
  10. package/android/src/main/java/com/margelo/nitro/iap/NitroIapPackage.java +33 -0
  11. package/android/src/main/java/com/margelo/nitro/iap/Types.kt +173 -0
  12. package/ios/Bridge.h +8 -0
  13. package/ios/ErrorUtils.swift +153 -0
  14. package/ios/HybridRnIap.swift +1326 -0
  15. package/ios/ProductStore.swift +33 -0
  16. package/ios/reactnativeiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  17. package/ios/reactnativeiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  18. package/lib/module/helpers/subscription.js +56 -0
  19. package/lib/module/helpers/subscription.js.map +1 -0
  20. package/lib/module/hooks/useIAP.js +175 -123
  21. package/lib/module/hooks/useIAP.js.map +1 -1
  22. package/lib/module/index.js +1015 -9
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/package.json +1 -0
  25. package/lib/module/specs/RnIap.nitro.js +4 -0
  26. package/lib/{commonjs/modules/common.js.map → module/specs/RnIap.nitro.js.map} +1 -1
  27. package/lib/module/types.js +187 -0
  28. package/lib/module/types.js.map +1 -0
  29. package/lib/module/utils/error.js +80 -0
  30. package/lib/module/utils/error.js.map +1 -0
  31. package/lib/module/utils/type-bridge.js +202 -0
  32. package/lib/module/utils/type-bridge.js.map +1 -0
  33. package/lib/typescript/package.json +1 -0
  34. package/lib/typescript/plugin/src/withIAP.d.ts +2 -7
  35. package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
  36. package/lib/typescript/scripts/check-nitro-versions.d.ts +3 -0
  37. package/lib/typescript/scripts/check-nitro-versions.d.ts.map +1 -0
  38. package/lib/typescript/src/helpers/subscription.d.ts +14 -0
  39. package/lib/typescript/src/helpers/subscription.d.ts.map +1 -0
  40. package/lib/typescript/src/hooks/useIAP.d.ts +42 -26
  41. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  42. package/lib/typescript/src/index.d.ts +356 -8
  43. package/lib/typescript/src/index.d.ts.map +1 -1
  44. package/lib/typescript/src/specs/RnIap.nitro.d.ts +404 -0
  45. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -0
  46. package/lib/typescript/src/types.d.ts +544 -0
  47. package/lib/typescript/src/types.d.ts.map +1 -0
  48. package/lib/typescript/src/utils/error.d.ts +30 -0
  49. package/lib/typescript/src/utils/error.d.ts.map +1 -0
  50. package/lib/typescript/src/utils/type-bridge.d.ts +40 -0
  51. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -0
  52. package/nitro.json +17 -0
  53. package/nitrogen/generated/android/NitroIap+autolinking.cmake +80 -0
  54. package/nitrogen/generated/android/NitroIap+autolinking.gradle +27 -0
  55. package/nitrogen/generated/android/NitroIapOnLoad.cpp +50 -0
  56. package/nitrogen/generated/android/NitroIapOnLoad.hpp +25 -0
  57. package/nitrogen/generated/android/c++/JFunc_void_NitroProduct.hpp +78 -0
  58. package/nitrogen/generated/android/c++/JFunc_void_NitroPurchase.hpp +78 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_NitroPurchaseResult.hpp +78 -0
  60. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +577 -0
  61. package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +93 -0
  62. package/nitrogen/generated/android/c++/JNitroAndroidReceiptValidationOptions.hpp +66 -0
  63. package/nitrogen/generated/android/c++/JNitroAvailablePurchasesAndroidOptions.hpp +54 -0
  64. package/nitrogen/generated/android/c++/JNitroAvailablePurchasesIosOptions.hpp +65 -0
  65. package/nitrogen/generated/android/c++/JNitroAvailablePurchasesOptions.hpp +62 -0
  66. package/nitrogen/generated/android/c++/JNitroFinishTransactionAndroidParams.hpp +58 -0
  67. package/nitrogen/generated/android/c++/JNitroFinishTransactionIosParams.hpp +53 -0
  68. package/nitrogen/generated/android/c++/JNitroFinishTransactionParams.hpp +62 -0
  69. package/nitrogen/generated/android/c++/JNitroProduct.hpp +154 -0
  70. package/nitrogen/generated/android/c++/JNitroPurchase.hpp +122 -0
  71. package/nitrogen/generated/android/c++/JNitroPurchaseRequest.hpp +66 -0
  72. package/nitrogen/generated/android/c++/JNitroPurchaseResult.hpp +70 -0
  73. package/nitrogen/generated/android/c++/JNitroReceiptValidationParams.hpp +60 -0
  74. package/nitrogen/generated/android/c++/JNitroReceiptValidationResultAndroid.hpp +122 -0
  75. package/nitrogen/generated/android/c++/JNitroReceiptValidationResultIOS.hpp +68 -0
  76. package/nitrogen/generated/android/c++/JNitroRequestPurchaseAndroid.hpp +115 -0
  77. package/nitrogen/generated/android/c++/JNitroRequestPurchaseIos.hpp +84 -0
  78. package/nitrogen/generated/android/c++/JNitroSubscriptionOffer.hpp +57 -0
  79. package/nitrogen/generated/android/c++/JNitroSubscriptionRenewalInfo.hpp +74 -0
  80. package/nitrogen/generated/android/c++/JNitroSubscriptionStatus.hpp +64 -0
  81. package/nitrogen/generated/android/c++/JVariant_Boolean_NitroPurchaseResult.cpp +26 -0
  82. package/nitrogen/generated/android/c++/JVariant_Boolean_NitroPurchaseResult.hpp +71 -0
  83. package/nitrogen/generated/android/c++/JVariant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.cpp +26 -0
  84. package/nitrogen/generated/android/c++/JVariant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.hpp +75 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroProduct.kt +81 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroPurchase.kt +81 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroPurchaseResult.kt +81 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +198 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAndroidReceiptValidationOptions.kt +38 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAvailablePurchasesAndroidOptions.kt +29 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAvailablePurchasesIosOptions.kt +38 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAvailablePurchasesOptions.kt +32 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroFinishTransactionAndroidParams.kt +32 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroFinishTransactionIosParams.kt +29 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroFinishTransactionParams.kt +32 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroIapOnLoad.kt +35 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroProduct.kt +104 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchase.kt +80 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchaseRequest.kt +32 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchaseResult.kt +41 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationParams.kt +32 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationResultAndroid.kt +80 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationResultIOS.kt +38 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroRequestPurchaseAndroid.kt +47 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroRequestPurchaseIos.kt +41 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroSubscriptionOffer.kt +32 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroSubscriptionRenewalInfo.kt +44 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroSubscriptionStatus.kt +35 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_Boolean_NitroPurchaseResult.kt +42 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.kt +42 -0
  111. package/nitrogen/generated/ios/NitroIap+autolinking.rb +60 -0
  112. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.cpp +152 -0
  113. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +1061 -0
  114. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +107 -0
  115. package/nitrogen/generated/ios/NitroIapAutolinking.mm +33 -0
  116. package/nitrogen/generated/ios/NitroIapAutolinking.swift +25 -0
  117. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.cpp +11 -0
  118. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +355 -0
  119. package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
  120. package/nitrogen/generated/ios/swift/Func_void_NitroProduct.swift +47 -0
  121. package/nitrogen/generated/ios/swift/Func_void_NitroPurchase.swift +47 -0
  122. package/nitrogen/generated/ios/swift/Func_void_NitroPurchaseResult.swift +47 -0
  123. package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
  124. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  125. package/nitrogen/generated/ios/swift/Func_void_std__optional_NitroProduct_.swift +54 -0
  126. package/nitrogen/generated/ios/swift/Func_void_std__optional_NitroPurchase_.swift +54 -0
  127. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +54 -0
  128. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__vector_NitroSubscriptionStatus__.swift +54 -0
  129. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  130. package/nitrogen/generated/ios/swift/Func_void_std__variant_NitroReceiptValidationResultIOS__NitroReceiptValidationResultAndroid_.swift +59 -0
  131. package/nitrogen/generated/ios/swift/Func_void_std__variant_bool__NitroPurchaseResult_.swift +59 -0
  132. package/nitrogen/generated/ios/swift/Func_void_std__vector_NitroProduct_.swift +47 -0
  133. package/nitrogen/generated/ios/swift/Func_void_std__vector_NitroPurchase_.swift +47 -0
  134. package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +78 -0
  135. package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +750 -0
  136. package/nitrogen/generated/ios/swift/NitroAndroidReceiptValidationOptions.swift +80 -0
  137. package/nitrogen/generated/ios/swift/NitroAvailablePurchasesAndroidOptions.swift +54 -0
  138. package/nitrogen/generated/ios/swift/NitroAvailablePurchasesIosOptions.swift +116 -0
  139. package/nitrogen/generated/ios/swift/NitroAvailablePurchasesOptions.swift +84 -0
  140. package/nitrogen/generated/ios/swift/NitroFinishTransactionAndroidParams.swift +58 -0
  141. package/nitrogen/generated/ios/swift/NitroFinishTransactionIosParams.swift +35 -0
  142. package/nitrogen/generated/ios/swift/NitroFinishTransactionParams.swift +84 -0
  143. package/nitrogen/generated/ios/swift/NitroProduct.swift +653 -0
  144. package/nitrogen/generated/ios/swift/NitroPurchase.swift +453 -0
  145. package/nitrogen/generated/ios/swift/NitroPurchaseRequest.swift +84 -0
  146. package/nitrogen/generated/ios/swift/NitroPurchaseResult.swift +117 -0
  147. package/nitrogen/generated/ios/swift/NitroReceiptValidationParams.swift +65 -0
  148. package/nitrogen/generated/ios/swift/NitroReceiptValidationResultAndroid.swift +258 -0
  149. package/nitrogen/generated/ios/swift/NitroReceiptValidationResultIOS.swift +87 -0
  150. package/nitrogen/generated/ios/swift/NitroRequestPurchaseAndroid.swift +225 -0
  151. package/nitrogen/generated/ios/swift/NitroRequestPurchaseIos.swift +161 -0
  152. package/nitrogen/generated/ios/swift/NitroSubscriptionOffer.swift +46 -0
  153. package/nitrogen/generated/ios/swift/NitroSubscriptionRenewalInfo.swift +152 -0
  154. package/nitrogen/generated/ios/swift/NitroSubscriptionStatus.swift +76 -0
  155. package/nitrogen/generated/ios/swift/Variant_Bool_NitroPurchaseResult.swift +18 -0
  156. package/nitrogen/generated/ios/swift/Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.swift +18 -0
  157. package/nitrogen/generated/shared/c++/HybridRnIapSpec.cpp +50 -0
  158. package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +125 -0
  159. package/nitrogen/generated/shared/c++/NitroAndroidReceiptValidationOptions.hpp +80 -0
  160. package/nitrogen/generated/shared/c++/NitroAvailablePurchasesAndroidOptions.hpp +68 -0
  161. package/nitrogen/generated/shared/c++/NitroAvailablePurchasesIosOptions.hpp +79 -0
  162. package/nitrogen/generated/shared/c++/NitroAvailablePurchasesOptions.hpp +76 -0
  163. package/nitrogen/generated/shared/c++/NitroFinishTransactionAndroidParams.hpp +72 -0
  164. package/nitrogen/generated/shared/c++/NitroFinishTransactionIosParams.hpp +67 -0
  165. package/nitrogen/generated/shared/c++/NitroFinishTransactionParams.hpp +76 -0
  166. package/nitrogen/generated/shared/c++/NitroProduct.hpp +168 -0
  167. package/nitrogen/generated/shared/c++/NitroPurchase.hpp +136 -0
  168. package/nitrogen/generated/shared/c++/NitroPurchaseRequest.hpp +76 -0
  169. package/nitrogen/generated/shared/c++/NitroPurchaseResult.hpp +84 -0
  170. package/nitrogen/generated/shared/c++/NitroReceiptValidationParams.hpp +74 -0
  171. package/nitrogen/generated/shared/c++/NitroReceiptValidationResultAndroid.hpp +136 -0
  172. package/nitrogen/generated/shared/c++/NitroReceiptValidationResultIOS.hpp +82 -0
  173. package/nitrogen/generated/shared/c++/NitroRequestPurchaseAndroid.hpp +95 -0
  174. package/nitrogen/generated/shared/c++/NitroRequestPurchaseIos.hpp +85 -0
  175. package/nitrogen/generated/shared/c++/NitroSubscriptionOffer.hpp +71 -0
  176. package/nitrogen/generated/shared/c++/NitroSubscriptionRenewalInfo.hpp +88 -0
  177. package/nitrogen/generated/shared/c++/NitroSubscriptionStatus.hpp +78 -0
  178. package/package.json +145 -104
  179. package/plugin/build/src/withIAP.d.ts +3 -0
  180. package/plugin/build/src/withIAP.js +81 -0
  181. package/plugin/build/tsconfig.tsbuildinfo +1 -0
  182. package/plugin/build/withIAP.d.ts +2 -7
  183. package/plugin/build/withIAP.js +62 -51
  184. package/plugin/src/withIAP.ts +119 -0
  185. package/plugin/tsconfig.json +18 -0
  186. package/plugin/tsconfig.tsbuildinfo +1 -0
  187. package/src/helpers/subscription.ts +65 -0
  188. package/src/hooks/useIAP.ts +361 -222
  189. package/src/index.ts +1194 -9
  190. package/src/specs/RnIap.nitro.ts +501 -0
  191. package/src/types.ts +680 -0
  192. package/src/utils/error.ts +97 -0
  193. package/src/utils/type-bridge.ts +209 -0
  194. package/LICENSE +0 -21
  195. package/RNIap.podspec +0 -36
  196. package/android/src/amazon/AndroidManifest.xml +0 -14
  197. package/android/src/amazon/java/com/dooboolab/rniap/EventSender.kt +0 -10
  198. package/android/src/amazon/java/com/dooboolab/rniap/PurchasingServiceProxy.kt +0 -29
  199. package/android/src/amazon/java/com/dooboolab/rniap/PurchasingServiceProxyAmazonImpl.kt +0 -31
  200. package/android/src/amazon/java/com/dooboolab/rniap/RNIapActivityListener.kt +0 -55
  201. package/android/src/amazon/java/com/dooboolab/rniap/RNIapAmazonListener.kt +0 -325
  202. package/android/src/amazon/java/com/dooboolab/rniap/RNIapAmazonModule.kt +0 -244
  203. package/android/src/amazon/java/com/dooboolab/rniap/RNIapPackage.kt +0 -17
  204. package/android/src/amazon/java/com/dooboolab/rniap/modifysubscription/RNIapAmazonModifySubscriptionListener.kt +0 -88
  205. package/android/src/amazon/java/com/dooboolab/rniap/utils/Extensions.kt +0 -22
  206. package/android/src/main/java/com/dooboolab/rniap/PromiseUtils.kt +0 -62
  207. package/android/src/main/java/com/dooboolab/rniap/PromiseUtlis.kt +0 -43
  208. package/android/src/play/java/com/dooboolab/rniap/PlayUtils.kt +0 -114
  209. package/android/src/play/java/com/dooboolab/rniap/RNIapActivityListener.kt +0 -15
  210. package/android/src/play/java/com/dooboolab/rniap/RNIapModule.kt +0 -911
  211. package/android/src/play/java/com/dooboolab/rniap/RNIapPackage.kt +0 -17
  212. package/android/src/testAmazon/java/com/dooboolab/rniap/RNIapAmazonModuleTest.kt +0 -170
  213. package/app.plugin.js +0 -1
  214. package/ios/IapSerializationUtils.swift +0 -290
  215. package/ios/IapTypes.swift +0 -56
  216. package/ios/IapUtils.swift +0 -40
  217. package/ios/LatestPromiseKeeper.swift +0 -52
  218. package/ios/RNIapIos-Bridging-Header.h +0 -2
  219. package/ios/RNIapIos.m +0 -69
  220. package/ios/RNIapIos.swift +0 -868
  221. package/ios/RNIapIos.xcodeproj/project.pbxproj +0 -289
  222. package/ios/RNIapIosSk2.m +0 -126
  223. package/ios/RNIapIosSk2.swift +0 -1413
  224. package/ios/ThreadSafe.swift +0 -18
  225. package/lib/commonjs/eventEmitter.js +0 -195
  226. package/lib/commonjs/eventEmitter.js.map +0 -1
  227. package/lib/commonjs/hooks/index.js +0 -17
  228. package/lib/commonjs/hooks/index.js.map +0 -1
  229. package/lib/commonjs/hooks/useIAP.js +0 -203
  230. package/lib/commonjs/hooks/useIAP.js.map +0 -1
  231. package/lib/commonjs/hooks/withIAPContext.js +0 -95
  232. package/lib/commonjs/hooks/withIAPContext.js.map +0 -1
  233. package/lib/commonjs/iap.js +0 -836
  234. package/lib/commonjs/iap.js.map +0 -1
  235. package/lib/commonjs/index.js +0 -105
  236. package/lib/commonjs/index.js.map +0 -1
  237. package/lib/commonjs/internal/enhancedFetch.js +0 -26
  238. package/lib/commonjs/internal/enhancedFetch.js.map +0 -1
  239. package/lib/commonjs/internal/fillProductsWithAdditionalData.js +0 -50
  240. package/lib/commonjs/internal/fillProductsWithAdditionalData.js.map +0 -1
  241. package/lib/commonjs/internal/index.js +0 -39
  242. package/lib/commonjs/internal/index.js.map +0 -1
  243. package/lib/commonjs/internal/platform.js +0 -119
  244. package/lib/commonjs/internal/platform.js.map +0 -1
  245. package/lib/commonjs/modules/amazon.js +0 -50
  246. package/lib/commonjs/modules/amazon.js.map +0 -1
  247. package/lib/commonjs/modules/android.js +0 -92
  248. package/lib/commonjs/modules/android.js.map +0 -1
  249. package/lib/commonjs/modules/common.js +0 -2
  250. package/lib/commonjs/modules/index.js +0 -50
  251. package/lib/commonjs/modules/index.js.map +0 -1
  252. package/lib/commonjs/modules/ios.js +0 -160
  253. package/lib/commonjs/modules/ios.js.map +0 -1
  254. package/lib/commonjs/modules/iosSk2.js +0 -113
  255. package/lib/commonjs/modules/iosSk2.js.map +0 -1
  256. package/lib/commonjs/purchaseError.js +0 -170
  257. package/lib/commonjs/purchaseError.js.map +0 -1
  258. package/lib/commonjs/types/amazon.js +0 -2
  259. package/lib/commonjs/types/amazon.js.map +0 -1
  260. package/lib/commonjs/types/android.js +0 -67
  261. package/lib/commonjs/types/android.js.map +0 -1
  262. package/lib/commonjs/types/apple.js +0 -24
  263. package/lib/commonjs/types/apple.js.map +0 -1
  264. package/lib/commonjs/types/appleSk2.js +0 -137
  265. package/lib/commonjs/types/appleSk2.js.map +0 -1
  266. package/lib/commonjs/types/index.js +0 -67
  267. package/lib/commonjs/types/index.js.map +0 -1
  268. package/lib/commonjs/utils/errorMapping.js +0 -83
  269. package/lib/commonjs/utils/errorMapping.js.map +0 -1
  270. package/lib/commonjs/utils/typeGuards.js +0 -74
  271. package/lib/commonjs/utils/typeGuards.js.map +0 -1
  272. package/lib/module/eventEmitter.js +0 -185
  273. package/lib/module/eventEmitter.js.map +0 -1
  274. package/lib/module/hooks/index.js +0 -2
  275. package/lib/module/hooks/index.js.map +0 -1
  276. package/lib/module/hooks/withIAPContext.js +0 -86
  277. package/lib/module/hooks/withIAPContext.js.map +0 -1
  278. package/lib/module/iap.js +0 -805
  279. package/lib/module/iap.js.map +0 -1
  280. package/lib/module/internal/enhancedFetch.js +0 -19
  281. package/lib/module/internal/enhancedFetch.js.map +0 -1
  282. package/lib/module/internal/fillProductsWithAdditionalData.js +0 -43
  283. package/lib/module/internal/fillProductsWithAdditionalData.js.map +0 -1
  284. package/lib/module/internal/index.js +0 -4
  285. package/lib/module/internal/index.js.map +0 -1
  286. package/lib/module/internal/platform.js +0 -102
  287. package/lib/module/internal/platform.js.map +0 -1
  288. package/lib/module/modules/amazon.js +0 -42
  289. package/lib/module/modules/amazon.js.map +0 -1
  290. package/lib/module/modules/android.js +0 -81
  291. package/lib/module/modules/android.js.map +0 -1
  292. package/lib/module/modules/common.js +0 -2
  293. package/lib/module/modules/common.js.map +0 -1
  294. package/lib/module/modules/index.js +0 -5
  295. package/lib/module/modules/index.js.map +0 -1
  296. package/lib/module/modules/ios.js +0 -145
  297. package/lib/module/modules/ios.js.map +0 -1
  298. package/lib/module/modules/iosSk2.js +0 -96
  299. package/lib/module/modules/iosSk2.js.map +0 -1
  300. package/lib/module/purchaseError.js +0 -164
  301. package/lib/module/purchaseError.js.map +0 -1
  302. package/lib/module/types/amazon.js +0 -2
  303. package/lib/module/types/amazon.js.map +0 -1
  304. package/lib/module/types/android.js +0 -63
  305. package/lib/module/types/android.js.map +0 -1
  306. package/lib/module/types/apple.js +0 -17
  307. package/lib/module/types/apple.js.map +0 -1
  308. package/lib/module/types/appleSk2.js +0 -129
  309. package/lib/module/types/appleSk2.js.map +0 -1
  310. package/lib/module/types/index.js +0 -75
  311. package/lib/module/types/index.js.map +0 -1
  312. package/lib/module/utils/errorMapping.js +0 -75
  313. package/lib/module/utils/errorMapping.js.map +0 -1
  314. package/lib/module/utils/typeGuards.js +0 -61
  315. package/lib/module/utils/typeGuards.js.map +0 -1
  316. package/lib/typescript/src/eventEmitter.d.ts +0 -151
  317. package/lib/typescript/src/eventEmitter.d.ts.map +0 -1
  318. package/lib/typescript/src/hooks/index.d.ts +0 -2
  319. package/lib/typescript/src/hooks/index.d.ts.map +0 -1
  320. package/lib/typescript/src/hooks/withIAPContext.d.ts +0 -27
  321. package/lib/typescript/src/hooks/withIAPContext.d.ts.map +0 -1
  322. package/lib/typescript/src/iap.d.ts +0 -503
  323. package/lib/typescript/src/iap.d.ts.map +0 -1
  324. package/lib/typescript/src/internal/enhancedFetch.d.ts +0 -6
  325. package/lib/typescript/src/internal/enhancedFetch.d.ts.map +0 -1
  326. package/lib/typescript/src/internal/fillProductsWithAdditionalData.d.ts +0 -7
  327. package/lib/typescript/src/internal/fillProductsWithAdditionalData.d.ts.map +0 -1
  328. package/lib/typescript/src/internal/index.d.ts +0 -4
  329. package/lib/typescript/src/internal/index.d.ts.map +0 -1
  330. package/lib/typescript/src/internal/platform.d.ts +0 -27
  331. package/lib/typescript/src/internal/platform.d.ts.map +0 -1
  332. package/lib/typescript/src/modules/amazon.d.ts +0 -55
  333. package/lib/typescript/src/modules/amazon.d.ts.map +0 -1
  334. package/lib/typescript/src/modules/android.d.ts +0 -74
  335. package/lib/typescript/src/modules/android.d.ts.map +0 -1
  336. package/lib/typescript/src/modules/common.d.ts +0 -14
  337. package/lib/typescript/src/modules/common.d.ts.map +0 -1
  338. package/lib/typescript/src/modules/index.d.ts +0 -5
  339. package/lib/typescript/src/modules/index.d.ts.map +0 -1
  340. package/lib/typescript/src/modules/ios.d.ts +0 -117
  341. package/lib/typescript/src/modules/ios.d.ts.map +0 -1
  342. package/lib/typescript/src/modules/iosSk2.d.ts +0 -140
  343. package/lib/typescript/src/modules/iosSk2.d.ts.map +0 -1
  344. package/lib/typescript/src/purchaseError.d.ts +0 -133
  345. package/lib/typescript/src/purchaseError.d.ts.map +0 -1
  346. package/lib/typescript/src/types/amazon.d.ts +0 -33
  347. package/lib/typescript/src/types/amazon.d.ts.map +0 -1
  348. package/lib/typescript/src/types/android.d.ts +0 -66
  349. package/lib/typescript/src/types/android.d.ts.map +0 -1
  350. package/lib/typescript/src/types/apple.d.ts +0 -27
  351. package/lib/typescript/src/types/apple.d.ts.map +0 -1
  352. package/lib/typescript/src/types/appleSk2.d.ts +0 -129
  353. package/lib/typescript/src/types/appleSk2.d.ts.map +0 -1
  354. package/lib/typescript/src/types/index.d.ts +0 -302
  355. package/lib/typescript/src/types/index.d.ts.map +0 -1
  356. package/lib/typescript/src/utils/errorMapping.d.ts +0 -29
  357. package/lib/typescript/src/utils/errorMapping.d.ts.map +0 -1
  358. package/lib/typescript/src/utils/typeGuards.d.ts +0 -53
  359. package/lib/typescript/src/utils/typeGuards.d.ts.map +0 -1
  360. package/src/eventEmitter.ts +0 -212
  361. package/src/hooks/index.ts +0 -1
  362. package/src/hooks/withIAPContext.tsx +0 -179
  363. package/src/iap.ts +0 -1046
  364. package/src/internal/enhancedFetch.ts +0 -25
  365. package/src/internal/fillProductsWithAdditionalData.ts +0 -47
  366. package/src/internal/index.ts +0 -3
  367. package/src/internal/platform.ts +0 -135
  368. package/src/modules/amazon.ts +0 -94
  369. package/src/modules/android.ts +0 -179
  370. package/src/modules/common.ts +0 -16
  371. package/src/modules/index.ts +0 -4
  372. package/src/modules/ios.ts +0 -229
  373. package/src/modules/iosSk2.ts +0 -194
  374. package/src/purchaseError.ts +0 -196
  375. package/src/types/amazon.ts +0 -40
  376. package/src/types/android.ts +0 -89
  377. package/src/types/apple.ts +0 -44
  378. package/src/types/appleSk2.ts +0 -275
  379. package/src/types/index.ts +0 -379
  380. package/src/utils/errorMapping.ts +0 -88
  381. package/src/utils/typeGuards.ts +0 -90
@@ -1,1413 +0,0 @@
1
- import Foundation
2
- import React
3
- import StoreKit
4
-
5
- protocol Sk2Delegate {
6
- func disable(
7
- _ resolve: @escaping RCTPromiseResolveBlock,
8
- reject: @escaping RCTPromiseRejectBlock
9
- )
10
-
11
- func initConnection(
12
- _ resolve: @escaping RCTPromiseResolveBlock,
13
- reject: @escaping RCTPromiseRejectBlock
14
- )
15
-
16
- func endConnection(
17
- _ resolve: @escaping RCTPromiseResolveBlock,
18
- reject: @escaping RCTPromiseRejectBlock
19
- )
20
-
21
- func getItems(
22
- _ skus: [String],
23
- resolve: @escaping RCTPromiseResolveBlock,
24
- reject: @escaping RCTPromiseRejectBlock
25
- )
26
-
27
- func getAvailableItems(
28
- _ alsoPublishToEventListener: Bool,
29
- onlyIncludeActiveItems: Bool,
30
- resolve: @escaping RCTPromiseResolveBlock,
31
- reject: @escaping RCTPromiseRejectBlock
32
- )
33
-
34
- func buyProduct(
35
- _ sku: String,
36
- andDangerouslyFinishTransactionAutomatically: Bool,
37
- appAccountToken: String?,
38
- quantity: Int,
39
- withOffer: [String: String],
40
- resolve: @escaping RCTPromiseResolveBlock,
41
- reject: @escaping RCTPromiseRejectBlock
42
- )
43
-
44
- func isEligibleForIntroOffer(
45
- _ groupID: String,
46
- resolve: @escaping RCTPromiseResolveBlock,
47
- reject: @escaping RCTPromiseRejectBlock
48
- )
49
-
50
- func subscriptionStatus(
51
- _ sku: String,
52
- resolve: @escaping RCTPromiseResolveBlock,
53
- reject: @escaping RCTPromiseRejectBlock
54
- )
55
-
56
- func currentEntitlement(
57
- _ sku: String,
58
- resolve: @escaping RCTPromiseResolveBlock,
59
- reject: @escaping RCTPromiseRejectBlock
60
- )
61
-
62
- func latestTransaction(
63
- _ sku: String,
64
- resolve: @escaping RCTPromiseResolveBlock,
65
- reject: @escaping RCTPromiseRejectBlock
66
- )
67
-
68
- func finishTransaction(
69
- _ transactionIdentifier: String,
70
- resolve: @escaping RCTPromiseResolveBlock,
71
- reject: @escaping RCTPromiseRejectBlock
72
- )
73
-
74
- func getPendingTransactions (
75
- _ resolve: @escaping RCTPromiseResolveBlock,
76
- reject: @escaping RCTPromiseRejectBlock
77
- )
78
-
79
- func sync(
80
- _ resolve: @escaping RCTPromiseResolveBlock,
81
- reject: @escaping RCTPromiseRejectBlock
82
- )
83
-
84
- func presentCodeRedemptionSheet(
85
- _ resolve: @escaping RCTPromiseResolveBlock,
86
- reject: @escaping RCTPromiseRejectBlock
87
- )
88
-
89
- func showManageSubscriptions(
90
- _ resolve: @escaping RCTPromiseResolveBlock,
91
- reject: @escaping RCTPromiseRejectBlock
92
- )
93
-
94
- func clearTransaction(
95
- _ resolve: @escaping RCTPromiseResolveBlock,
96
- reject: @escaping RCTPromiseRejectBlock
97
- )
98
-
99
- func beginRefundRequest(
100
- _ sku: String,
101
- resolve: @escaping RCTPromiseResolveBlock,
102
- reject: @escaping RCTPromiseRejectBlock
103
- )
104
-
105
- func getStorefront(
106
- _ resolve: @escaping RCTPromiseResolveBlock,
107
- reject: @escaping RCTPromiseRejectBlock
108
- )
109
-
110
- func getAppTransaction(
111
- _ resolve: @escaping RCTPromiseResolveBlock,
112
- reject: @escaping RCTPromiseRejectBlock
113
- )
114
-
115
- func getReceiptDataIos(
116
- _ resolve: @escaping RCTPromiseResolveBlock,
117
- reject: @escaping RCTPromiseRejectBlock
118
- )
119
-
120
- func isTransactionVerifiedIos(
121
- _ sku: String,
122
- resolve: @escaping RCTPromiseResolveBlock,
123
- reject: @escaping RCTPromiseRejectBlock
124
- )
125
-
126
- func getTransactionJwsIos(
127
- _ sku: String,
128
- resolve: @escaping RCTPromiseResolveBlock,
129
- reject: @escaping RCTPromiseRejectBlock
130
- )
131
-
132
- func validateReceiptIos(
133
- _ sku: String,
134
- resolve: @escaping RCTPromiseResolveBlock,
135
- reject: @escaping RCTPromiseRejectBlock
136
- )
137
-
138
- func startObserving()
139
- func stopObserving()
140
- }
141
-
142
- class DummySk2: Sk2Delegate {
143
- let errorCode = IapErrors.E_DEVELOPER_ERROR.rawValue
144
- let errorMessage = "Method only available on iOS 15 and up"
145
-
146
- func disable(
147
- _ resolve: @escaping RCTPromiseResolveBlock,
148
- reject: @escaping RCTPromiseRejectBlock
149
- ) {
150
- reject(errorCode, errorMessage, nil)
151
- }
152
-
153
- func initConnection(
154
- _ resolve: @escaping RCTPromiseResolveBlock,
155
- reject: @escaping RCTPromiseRejectBlock
156
- ) {
157
- reject(errorCode, errorMessage, nil)
158
- }
159
-
160
- func endConnection(
161
- _ resolve: @escaping RCTPromiseResolveBlock,
162
- reject: @escaping RCTPromiseRejectBlock
163
- ) {
164
- reject(errorCode, errorMessage, nil)
165
- }
166
-
167
- func getItems(
168
- _ skus: [String],
169
- resolve: @escaping RCTPromiseResolveBlock,
170
- reject: @escaping RCTPromiseRejectBlock
171
- ) {
172
- reject(errorCode, errorMessage, nil)
173
- }
174
-
175
- func getAvailableItems(
176
- _ alsoPublishToEventListener: Bool,
177
- onlyIncludeActiveItems: Bool,
178
- resolve: @escaping RCTPromiseResolveBlock,
179
- reject: @escaping RCTPromiseRejectBlock
180
- ) {
181
- reject(errorCode, errorMessage, nil)
182
- }
183
-
184
- func buyProduct(
185
- _ sku: String,
186
- andDangerouslyFinishTransactionAutomatically: Bool,
187
- appAccountToken: String?,
188
- quantity: Int,
189
- withOffer: [String: String],
190
- resolve: @escaping RCTPromiseResolveBlock,
191
- reject: @escaping RCTPromiseRejectBlock
192
- ) {
193
- reject(errorCode, errorMessage, nil)
194
- }
195
-
196
- func isEligibleForIntroOffer(
197
- _ groupID: String,
198
- resolve: @escaping RCTPromiseResolveBlock,
199
- reject: @escaping RCTPromiseRejectBlock
200
- ) {
201
- reject(errorCode, errorMessage, nil)
202
- }
203
-
204
- func subscriptionStatus(
205
- _ sku: String,
206
- resolve: @escaping RCTPromiseResolveBlock,
207
- reject: @escaping RCTPromiseRejectBlock
208
- ) {
209
- reject(errorCode, errorMessage, nil)
210
- }
211
-
212
- func currentEntitlement(
213
- _ sku: String,
214
- resolve: @escaping RCTPromiseResolveBlock,
215
- reject: @escaping RCTPromiseRejectBlock
216
- ) {
217
- reject(errorCode, errorMessage, nil)
218
- }
219
-
220
- func latestTransaction(
221
- _ sku: String,
222
- resolve: @escaping RCTPromiseResolveBlock,
223
- reject: @escaping RCTPromiseRejectBlock
224
- ) {
225
- reject(errorCode, errorMessage, nil)
226
- }
227
-
228
- func finishTransaction(
229
- _ transactionIdentifier: String,
230
- resolve: @escaping RCTPromiseResolveBlock,
231
- reject: @escaping RCTPromiseRejectBlock
232
- ) {
233
- reject(errorCode, errorMessage, nil)
234
- }
235
-
236
- func getPendingTransactions (
237
- _ resolve: @escaping RCTPromiseResolveBlock,
238
- reject: @escaping RCTPromiseRejectBlock
239
- ) {
240
- reject(errorCode, errorMessage, nil)
241
- }
242
-
243
- func sync(
244
- _ resolve: @escaping RCTPromiseResolveBlock,
245
- reject: @escaping RCTPromiseRejectBlock
246
- ) {
247
- reject(errorCode, errorMessage, nil)
248
- }
249
-
250
- func presentCodeRedemptionSheet(
251
- _ resolve: @escaping RCTPromiseResolveBlock,
252
- reject: @escaping RCTPromiseRejectBlock
253
- ) {
254
- reject(errorCode, errorMessage, nil)
255
- }
256
-
257
- func showManageSubscriptions(
258
- _ resolve: @escaping RCTPromiseResolveBlock,
259
- reject: @escaping RCTPromiseRejectBlock
260
- ) {
261
- reject(errorCode, errorMessage, nil)
262
- }
263
-
264
- func clearTransaction(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
265
- reject(errorCode, errorMessage, nil)
266
- }
267
-
268
- func beginRefundRequest(
269
- _ sku: String,
270
- resolve: @escaping RCTPromiseResolveBlock,
271
- reject: @escaping RCTPromiseRejectBlock
272
- ) {
273
- reject(errorCode, errorMessage, nil)
274
- }
275
-
276
- func getStorefront(
277
- _ resolve: @escaping RCTPromiseResolveBlock,
278
- reject: @escaping RCTPromiseRejectBlock
279
- ) {
280
- reject(errorCode, errorMessage, nil)
281
- }
282
-
283
- func getAppTransaction(
284
- _ resolve: @escaping RCTPromiseResolveBlock,
285
- reject: @escaping RCTPromiseRejectBlock
286
- ) {
287
- reject(errorCode, errorMessage, nil)
288
- }
289
-
290
- func getReceiptDataIos(
291
- _ resolve: @escaping RCTPromiseResolveBlock,
292
- reject: @escaping RCTPromiseRejectBlock
293
- ) {
294
- reject(errorCode, errorMessage, nil)
295
- }
296
-
297
- func isTransactionVerifiedIos(
298
- _ sku: String,
299
- resolve: @escaping RCTPromiseResolveBlock,
300
- reject: @escaping RCTPromiseRejectBlock
301
- ) {
302
- reject(errorCode, errorMessage, nil)
303
- }
304
-
305
- func getTransactionJwsIos(
306
- _ sku: String,
307
- resolve: @escaping RCTPromiseResolveBlock,
308
- reject: @escaping RCTPromiseRejectBlock
309
- ) {
310
- reject(errorCode, errorMessage, nil)
311
- }
312
-
313
- func validateReceiptIos(
314
- _ sku: String,
315
- resolve: @escaping RCTPromiseResolveBlock,
316
- reject: @escaping RCTPromiseRejectBlock
317
- ) {
318
- reject(errorCode, errorMessage, nil)
319
- }
320
-
321
- func startObserving() {
322
- }
323
-
324
- func stopObserving() {
325
- }
326
- }
327
-
328
- @objc(RNIapIosSk2)
329
- class RNIapIosSk2: RCTEventEmitter, Sk2Delegate {
330
- private var delegate: Sk2Delegate = DummySk2()
331
-
332
- override init() {
333
- super.init()
334
- if #available(iOS 15.0, tvOS 15.0, *) {
335
- delegate = RNIapIosSk2iOS15(sendEvent: self.sendEvent)
336
- }
337
- }
338
-
339
- @objc public func disable(
340
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
341
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
342
- ) {
343
- delegate.disable(resolve, reject: reject)
344
- }
345
-
346
- override class func requiresMainQueueSetup() -> Bool {
347
- return true
348
- }
349
-
350
- override func startObserving() {
351
- delegate.startObserving()
352
- }
353
-
354
- override func stopObserving() {
355
- delegate.stopObserving()
356
- }
357
-
358
- /**
359
- "iap-transaction-updated" is unique to Sk2.
360
- "iap-promoted-product" is only avaiable on Sk1
361
- "purchase-updated", "purchase-error" are for backward compatibility
362
- */
363
- override func supportedEvents() -> [String]? {
364
- return [ "purchase-updated", "purchase-error", "iap-transaction-updated"]
365
- }
366
-
367
- @objc public func initConnection(
368
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
369
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
370
- ) {
371
- delegate.initConnection(resolve, reject: reject)
372
- }
373
- @objc public func endConnection(
374
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
375
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
376
- ) {
377
- delegate.endConnection(resolve, reject: reject)
378
- }
379
-
380
- @objc public func getItems(
381
- _ skus: [String],
382
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
383
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
384
- ) {
385
- delegate.getItems(skus, resolve: resolve, reject: reject)
386
- }
387
-
388
- @objc public func getAvailableItems(
389
- _ alsoPublishToEventListener: Bool,
390
- onlyIncludeActiveItems: Bool,
391
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
392
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
393
- ) {
394
- delegate.getAvailableItems(alsoPublishToEventListener, onlyIncludeActiveItems: onlyIncludeActiveItems, resolve: resolve, reject: reject)
395
- }
396
-
397
- @objc public func buyProduct(
398
- _ sku: String,
399
- andDangerouslyFinishTransactionAutomatically: Bool,
400
- appAccountToken: String?,
401
- quantity: Int,
402
- withOffer: [String: String],
403
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
404
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
405
- ) {
406
- delegate.buyProduct(
407
- sku,
408
- andDangerouslyFinishTransactionAutomatically: andDangerouslyFinishTransactionAutomatically,
409
- appAccountToken: appAccountToken,
410
- quantity: quantity,
411
- withOffer: withOffer,
412
- resolve: resolve,
413
- reject: reject)
414
- }
415
-
416
- @objc public func isEligibleForIntroOffer(
417
- _ groupID: String,
418
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
419
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
420
- ) {
421
- delegate.isEligibleForIntroOffer(groupID, resolve: resolve, reject: reject)
422
- }
423
-
424
- @objc public func subscriptionStatus(
425
- _ sku: String,
426
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
427
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
428
- ) {
429
- delegate.subscriptionStatus(sku, resolve: resolve, reject: reject)
430
- }
431
-
432
- @objc public func currentEntitlement(
433
- _ sku: String,
434
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
435
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
436
- ) {
437
- delegate.currentEntitlement(sku, resolve: resolve, reject: reject)
438
- }
439
-
440
- @objc public func latestTransaction(
441
- _ sku: String,
442
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
443
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
444
- ) {
445
- delegate.latestTransaction(sku, resolve: resolve, reject: reject)
446
- }
447
-
448
- @objc public func finishTransaction(
449
- _ transactionIdentifier: String,
450
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
451
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
452
- ) {
453
- delegate.finishTransaction(transactionIdentifier, resolve: resolve, reject: reject)
454
- }
455
-
456
- @objc public func getPendingTransactions (
457
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
458
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
459
- ) {
460
- delegate.getPendingTransactions(resolve, reject: reject)
461
- }
462
-
463
- @objc public func sync(
464
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in},
465
- reject: @escaping RCTPromiseRejectBlock = {_, _, _ in}
466
- ) {
467
- delegate.sync(resolve, reject: reject)
468
- }
469
-
470
- @objc public func presentCodeRedemptionSheet(
471
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
472
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
473
- ) {
474
- delegate.presentCodeRedemptionSheet(resolve, reject: reject)
475
- }
476
-
477
- @objc public func showManageSubscriptions(
478
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
479
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
480
- ) {
481
- delegate.showManageSubscriptions(resolve, reject: reject)
482
- }
483
-
484
- @objc func clearTransaction(
485
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
486
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }) {
487
- delegate.clearTransaction(resolve, reject: reject)
488
- }
489
-
490
- @objc public func beginRefundRequest(
491
- _ sku: String,
492
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
493
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
494
- ) {
495
- delegate.beginRefundRequest(sku, resolve: resolve, reject: reject)
496
- }
497
-
498
- @objc public func getStorefront(
499
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
500
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
501
- ) {
502
- delegate.getStorefront(resolve, reject: reject)
503
- }
504
-
505
- @objc public func getAppTransaction(
506
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
507
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
508
- ) {
509
- delegate.getAppTransaction(resolve, reject: reject)
510
- }
511
-
512
- @objc public func getReceiptDataIos(
513
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
514
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
515
- ) {
516
- delegate.getReceiptDataIos(resolve, reject: reject)
517
- }
518
-
519
- @objc public func isTransactionVerifiedIos(
520
- _ sku: String,
521
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
522
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
523
- ) {
524
- delegate.isTransactionVerifiedIos(sku, resolve: resolve, reject: reject)
525
- }
526
-
527
- @objc public func getTransactionJwsIos(
528
- _ sku: String,
529
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
530
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
531
- ) {
532
- delegate.getTransactionJwsIos(sku, resolve: resolve, reject: reject)
533
- }
534
-
535
- @objc public func validateReceiptIos(
536
- _ sku: String,
537
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
538
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
539
- ) {
540
- delegate.validateReceiptIos(sku, resolve: resolve, reject: reject)
541
- }
542
- }
543
-
544
- @available(iOS 15.0, tvOS 15.0, *)
545
- class RNIapIosSk2iOS15: Sk2Delegate {
546
- private var _hasListeners = false
547
- private let _hasListenersQueue = DispatchQueue(label: "com.dooboolab.rniap.hasListenersQueue", attributes: .concurrent)
548
- private var transactions: [String: Transaction]
549
- private var updateListenerTask: Task<Void, Error>?
550
- private var subscriptionPollingTask: Task<Void, Never>?
551
- private var pollingSkus: Set<String> = []
552
- fileprivate var sendEvent: ((String?, Any?) -> Void)?
553
- var hasListeners: Bool {
554
- get {
555
- return _hasListenersQueue.sync { _hasListeners }
556
- }
557
- set {
558
- _hasListenersQueue.async(flags: .barrier) { [weak self] in
559
- self?._hasListeners = newValue
560
- }
561
- }
562
- }
563
- init(sendEvent: ((String?, Any?) -> Void)? ) {
564
- self.sendEvent = sendEvent
565
- transactions = [String: Transaction]()
566
- }
567
-
568
- deinit {
569
- removeTransactionObserver()
570
- }
571
-
572
- actor ProductStore {
573
- private(set) var products: [String: Product] = [:]
574
-
575
- func addProduct(_ product: Product) {
576
- self.products[product.id] = product
577
- }
578
-
579
- func getAllProducts() -> [Product] {
580
- return Array(self.products.values)
581
- }
582
-
583
- func getProduct(productID: String) -> Product? {
584
- return self.products[productID]
585
- }
586
-
587
- func removeAll() {
588
- products.removeAll()
589
- }
590
-
591
- func performOnActor(_ action: @escaping (isolated ProductStore) -> Void) async {
592
- action(self)
593
- }
594
- }
595
-
596
- private let productStore = ProductStore()
597
-
598
- @objc public func disable(
599
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
600
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
601
- ) {
602
- removeTransactionObserver()
603
- resolve(nil)
604
- }
605
-
606
- func addTransactionObserver() {
607
- if updateListenerTask == nil {
608
- updateListenerTask = listenForTransactions()
609
- }
610
- }
611
-
612
- func removeTransactionObserver() {
613
- updateListenerTask?.cancel()
614
- updateListenerTask = nil
615
- }
616
-
617
- func addTransaction(_ transaction: Transaction) {
618
- let transactionId = String(transaction.id)
619
- self.transactions[transactionId] = transaction
620
- }
621
-
622
- func listenForTransactions() -> Task<Void, Error> {
623
- return Task.detached {
624
- // Iterate through any transactions that don't come from a direct call to `purchase()`.
625
- for await result in Transaction.updates {
626
- do {
627
- let transaction = try checkVerified(result)
628
- self.addTransaction(transaction)
629
- // Deliver products to the user.
630
- // await self.updateCustomerProductStatus()
631
-
632
- if self.hasListeners {
633
- self.sendEvent?("purchase-updated", serialize(transaction, result))
634
- self.sendEvent?("iap-transaction-updated", ["transaction": serialize(transaction, result)])
635
- }
636
- // Always finish a transaction.
637
- // await transaction.finish()
638
- // The transaction is returned to the user. Once it has fullfilled the order,
639
- // they can call finishTransaction
640
- } catch {
641
- // StoreKit has a transaction that fails verification. Don't deliver content to the user.
642
- debugMessage("Transaction failed verification")
643
- if self.hasListeners {
644
- let err = [
645
- "responseCode": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
646
- "debugMessage": error.localizedDescription,
647
- "code": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
648
- "message": error.localizedDescription
649
- ]
650
-
651
- self.sendEvent?("purchase-error", err)
652
- self.sendEvent?("iap-transaction-updated", ["error": err])
653
- }
654
- }
655
- }
656
- }
657
- }
658
-
659
- func startObserving() {
660
- hasListeners = true
661
- addTransactionObserver()
662
- }
663
-
664
- func stopObserving() {
665
- hasListeners = false
666
- removeTransactionObserver()
667
- }
668
-
669
- public func initConnection(
670
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
671
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
672
- ) {
673
- resolve(AppStore.canMakePayments)
674
- }
675
- public func endConnection(
676
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
677
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
678
- ) {
679
- Task {
680
- await productStore.removeAll()
681
- }
682
- transactions.removeAll()
683
- removeTransactionObserver()
684
- resolve(nil)
685
- }
686
-
687
- public func getItems(
688
- _ skus: [String],
689
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
690
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
691
- ) {
692
- Task {
693
- do {
694
- let fetchedProducts = try await Product.products(for: skus)
695
-
696
- await productStore.performOnActor { isolatedStore in
697
- fetchedProducts.forEach({ product in
698
- isolatedStore.addProduct(product)
699
- })
700
- }
701
-
702
- let products = await productStore.getAllProducts()
703
-
704
- resolve(products.map({ (prod: Product) -> [String: Any?]? in
705
- return serialize(prod)
706
- }).compactMap({$0}))
707
- } catch {
708
- reject(IapErrors.E_UNKNOWN.rawValue, "Error fetching items", error)
709
- }
710
- }
711
- }
712
-
713
- public func getAvailableItems(
714
- _ alsoPublishToEventListener: Bool,
715
- onlyIncludeActiveItems: Bool,
716
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
717
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
718
- ) {
719
- Task {
720
- var purchasedItemsSerialized: [[String: Any?]] = []
721
-
722
- func addTransaction(transaction: Transaction, verification: VerificationResult<Transaction>) {
723
- purchasedItemsSerialized.append(serialize(transaction, verification))
724
- if alsoPublishToEventListener {
725
- self.sendEvent?("purchase-updated", serialize(transaction))
726
- }
727
- }
728
- func addError( error: Error, errorDict: [String: String]) {
729
- if alsoPublishToEventListener {
730
- self.sendEvent?("purchase-error", errorDict)
731
- }
732
- }
733
- // Iterate through all of the user's purchased products.
734
- for await verification in onlyIncludeActiveItems ? Transaction.currentEntitlements : Transaction.all {
735
- do {
736
- // Check whether the transaction is verified. If it isn’t, catch `failedVerification` error.
737
- let transaction = try checkVerified(verification)
738
- // Check the `productType` of the transaction and get the corresponding product from the store.
739
- if !onlyIncludeActiveItems {
740
- addTransaction(transaction: transaction, verification: verification)
741
- continue
742
- }
743
- switch transaction.productType {
744
- case .nonConsumable:
745
- if await productStore.getProduct(productID: transaction.productID) != nil {
746
- addTransaction(transaction: transaction, verification: verification)
747
- }
748
-
749
- case .nonRenewable:
750
- if await productStore.getProduct(productID: transaction.productID) != nil {
751
- // Non-renewing subscriptions have no inherent expiration date, so they're always
752
- // contained in `Transaction.currentEntitlements` after the user purchases them.
753
- // This app defines this non-renewing subscription's expiration date to be one year after purchase.
754
- // If the current date is within one year of the `purchaseDate`, the user is still entitled to this
755
- // product.
756
- let currentDate = Date()
757
- let expirationDate = Calendar(identifier: .gregorian).date(byAdding: DateComponents(year: 1),
758
- to: transaction.purchaseDate)!
759
-
760
- if currentDate < expirationDate {
761
- addTransaction(transaction: transaction, verification: verification)
762
- }
763
- }
764
-
765
- case .autoRenewable:
766
- if await productStore.getProduct(productID: transaction.productID) != nil {
767
- addTransaction(transaction: transaction, verification: verification)
768
- }
769
-
770
- case .consumable:
771
- if await productStore.getProduct(productID: transaction.productID) != nil {
772
- addTransaction(transaction: transaction, verification: verification)
773
- }
774
-
775
- default:
776
- break
777
- }
778
- } catch StoreError.failedVerification {
779
- let err = [ "responseCode": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
780
- "debugMessage": StoreError.failedVerification.localizedDescription,
781
- "code": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
782
- "message": StoreError.failedVerification.localizedDescription,
783
- "productId": "unknown"
784
- ]
785
- addError(error: StoreError.failedVerification, errorDict: err)
786
- } catch {
787
- debugMessage(error)
788
- let err = [ "responseCode": IapErrors.E_UNKNOWN.rawValue,
789
- "debugMessage": error.localizedDescription,
790
- "code": IapErrors.E_UNKNOWN.rawValue,
791
- "message": error.localizedDescription,
792
- "productId": "unknown"
793
- ]
794
- addError(error: StoreError.failedVerification, errorDict: err)
795
- }
796
- }
797
- // Check the `subscriptionGroupStatus` to learn the auto-renewable subscription state to determine whether the customer
798
- // is new (never subscribed), active, or inactive (expired subscription). This app has only one subscription
799
- // group, so products in the subscriptions array all belong to the same group. The statuses that
800
- // `product.subscription.status` returns apply to the entire subscription group.
801
- // subscriptionGroupStatus = try? await subscriptions.first?.subscription?.status.first?.state
802
- resolve(purchasedItemsSerialized)
803
- }
804
- }
805
-
806
- public func buyProduct(
807
- _ sku: String,
808
- andDangerouslyFinishTransactionAutomatically: Bool,
809
- appAccountToken: String?,
810
- quantity: Int,
811
- withOffer: [String: String],
812
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
813
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
814
- ) {
815
- Task {
816
- let product: Product? = await productStore.getProduct(productID: sku)
817
-
818
- if let product = product {
819
- do {
820
- var options: Set<Product.PurchaseOption> = []
821
- if quantity > -1 {
822
- options.insert(.quantity(quantity))
823
- }
824
-
825
- let offerID = withOffer["offerID"]
826
- let keyID = withOffer["keyID"]
827
- let nonce = withOffer["nonce"]
828
- let signature = withOffer["signature"]
829
- let timestamp = withOffer["timestamp"]
830
-
831
- if let offerID = offerID, let keyID = keyID, let nonce = nonce, let nonce = UUID(uuidString: nonce), let signature = signature, let signature = signature.data(using: .utf8), let timestamp = timestamp, let timestamp = Int(timestamp) {
832
- options.insert(.promotionalOffer(offerID: offerID, keyID: keyID, nonce: nonce, signature: signature, timestamp: timestamp ))
833
- }
834
- if let appAccountToken = appAccountToken, let appAccountToken = UUID(uuidString: appAccountToken) {
835
- options.insert(.appAccountToken(appAccountToken))
836
- }
837
- debugMessage("Purchase Started")
838
-
839
- guard let windowScene = await currentWindow()?.windowScene else {
840
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Could not find window scene", nil)
841
- return
842
- }
843
-
844
- var result: Product.PurchaseResult?
845
-
846
- #if swift(>=5.9)
847
- if #available(iOS 17.0, tvOS 17.0, *) {
848
- result = try await product.purchase(confirmIn: windowScene, options: options)
849
- } else {
850
- #if !os(visionOS)
851
- result = try await product.purchase(options: options)
852
- #endif
853
- }
854
- #elseif !os(visionOS)
855
- result = try await product.purchase(options: options)
856
- #endif
857
-
858
- switch result {
859
- case .success(let verification):
860
- debugMessage("Purchase Successful")
861
-
862
- // Check whether the transaction is verified. If it isn't,
863
- // this function rethrows the verification error.
864
- let transaction = try checkVerified(verification)
865
-
866
- // The transaction is verified. Deliver content to the user.
867
- // Do on JS :await updateCustomerProductStatus()
868
-
869
- // Always finish a transaction.
870
- if andDangerouslyFinishTransactionAutomatically {
871
- await transaction.finish()
872
- resolve(nil)
873
- } else {
874
- self.addTransaction(transaction)
875
- self.sendEvent?("purchase-updated", serialize(transaction, verification))
876
- resolve(serialize(transaction, verification))
877
- }
878
- return
879
-
880
- case .userCancelled:
881
- debugMessage("User cancelled the purchase")
882
-
883
- let err = [
884
- "debugMessage": "User cancelled the purchase",
885
- "code": IapErrors.E_USER_CANCELLED.rawValue,
886
- "message": "User cancelled the purchase",
887
- "productId": sku,
888
- "quantity": "\(quantity)"
889
- ]
890
- debugMessage(err)
891
-
892
- reject(
893
- IapErrors.E_USER_CANCELLED.rawValue,
894
- "User cancelled the purchase",
895
- nil)
896
-
897
- return
898
-
899
- case .pending:
900
- debugMessage("Deferred (awaiting approval via parental controls, etc.)")
901
-
902
- let err = [
903
- "debugMessage": "The payment was deferred (awaiting approval via parental controls for instance)",
904
- "code": IapErrors.E_DEFERRED_PAYMENT.rawValue,
905
- "message": "The payment was deferred (awaiting approval via parental controls for instance)",
906
- "productId": sku,
907
- "quantity": "\(quantity)"
908
- ]
909
- debugMessage(err)
910
-
911
- reject(
912
- IapErrors.E_DEFERRED_PAYMENT.rawValue,
913
- "The payment was deferred for \(sku) (awaiting approval via parental controls for instance)",
914
- nil)
915
-
916
- return
917
-
918
- default:
919
- reject(IapErrors.E_UNKNOWN.rawValue, "Unknown response from purchase", nil)
920
- return
921
- }
922
- } catch {
923
- debugMessage("Purchase Failed")
924
-
925
- let err = [
926
- "responseCode": IapErrors.E_PURCHASE_ERROR.rawValue,
927
- "debugMessage": error.localizedDescription,
928
- "message": error.localizedDescription,
929
- "productId": sku
930
- ]
931
- print(err)
932
-
933
- reject(
934
- IapErrors.E_UNKNOWN.rawValue,
935
- "Purchased failed for sku:\(sku): \(error.localizedDescription)",
936
- error)
937
- }
938
- } else {
939
- reject("E_DEVELOPER_ERROR", "Invalid product ID. Did you call getProducts/Subscriptions", nil)
940
- }
941
- }
942
- }
943
-
944
- public func isEligibleForIntroOffer(
945
- _ groupID: String,
946
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
947
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
948
- ) {
949
- Task {
950
- let isEligibleForIntroOffer = await Product.SubscriptionInfo.isEligibleForIntroOffer(for: groupID)
951
- resolve(isEligibleForIntroOffer)
952
- }
953
- }
954
-
955
- public func subscriptionStatus(
956
- _ sku: String,
957
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
958
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
959
- ) {
960
- Task {
961
- do {
962
- let product = await productStore.getProduct(productID: sku)
963
- let status: [Product.SubscriptionInfo.Status]? = try await product?.subscription?.status
964
- guard let status = status else {
965
- resolve(nil)
966
- return
967
- }
968
- resolve(status.map({s in serialize(s)}))
969
- } catch {
970
- reject(IapErrors.E_UNKNOWN.rawValue, "Error getting subscription status", error)
971
- }
972
- }
973
- }
974
-
975
- public func currentEntitlement(
976
- _ sku: String,
977
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
978
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
979
- ) {
980
- Task {
981
- if let product = await productStore.getProduct(productID: sku) {
982
- if let result = await product.currentEntitlement {
983
- do {
984
- // Check whether the transaction is verified. If it isn’t, catch `failedVerification` error.
985
- let transaction = try checkVerified(result)
986
- resolve(serialize(transaction, result))
987
- } catch StoreError.failedVerification {
988
- reject(IapErrors.E_UNKNOWN.rawValue, "Failed to verify transaction for sku \(sku)", StoreError.failedVerification)
989
- } catch {
990
- debugMessage(error)
991
- reject(IapErrors.E_UNKNOWN.rawValue, "Error fetching entitlement for sku \(sku)", error)
992
- }
993
- } else {
994
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find entitlement for sku \(sku)", nil)
995
- }
996
- } else {
997
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find product for sku \(sku)", nil)
998
- }
999
- }
1000
- }
1001
-
1002
- public func latestTransaction(
1003
- _ sku: String,
1004
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
1005
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
1006
- ) {
1007
- Task {
1008
- if let product = await productStore.getProduct(productID: sku) {
1009
- if let result = await product.latestTransaction {
1010
- do {
1011
- // Check whether the transaction is verified. If it isn’t, catch `failedVerification` error.
1012
- let transaction = try checkVerified(result)
1013
- resolve(serialize(transaction, result))
1014
- } catch StoreError.failedVerification {
1015
- reject(IapErrors.E_UNKNOWN.rawValue, "Failed to verify transaction for sku \(sku)", StoreError.failedVerification)
1016
- } catch {
1017
- debugMessage(error)
1018
- reject(IapErrors.E_UNKNOWN.rawValue, "Error fetching latest transaction for sku \(sku)", error)
1019
- }
1020
- } else {
1021
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find latest transaction for sku \(sku)", nil)
1022
- }
1023
- } else {
1024
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find product for sku \(sku)", nil)
1025
- }
1026
- }
1027
- }
1028
-
1029
- public func finishTransaction(
1030
- _ transactionIdentifier: String,
1031
- resolve: @escaping RCTPromiseResolveBlock = { _ in },
1032
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
1033
- ) {
1034
- Task {
1035
- if let transaction = transactions[transactionIdentifier] {
1036
- debugMessage("Finishing transaction")
1037
- await transaction.finish()
1038
- debugMessage("Finished transaction")
1039
- transactions.removeValue(forKey: transactionIdentifier)
1040
- resolve(nil)
1041
- } else {
1042
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Invalid transaction Id", nil)
1043
- }
1044
- }
1045
- }
1046
-
1047
- public func getPendingTransactions (
1048
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
1049
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
1050
- ) {
1051
- resolve(transactions.values.map({(t: Transaction) in serialize(t)}))
1052
- }
1053
-
1054
- public func sync(
1055
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in},
1056
- reject: @escaping RCTPromiseRejectBlock = {_, _, _ in}
1057
- ) {
1058
- Task {
1059
- do {
1060
- try await AppStore.sync()
1061
- resolve(nil)
1062
- } catch {
1063
- if "\(error)" == "userCancelled" {
1064
- reject( IapErrors.E_USER_CANCELLED.rawValue, "User cancelled synchronizing with the AppStore", error)
1065
- } else {
1066
- reject( IapErrors.E_SYNC_ERROR.rawValue, "Error synchronizing with the AppStore", error)
1067
- }
1068
- }
1069
- }
1070
- }
1071
-
1072
- /**
1073
- Should remain the same according to:
1074
- https://stackoverflow.com/a/72789651/570612
1075
- */
1076
- public func presentCodeRedemptionSheet(
1077
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
1078
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
1079
- ) {
1080
- #if !os(tvOS)
1081
- SKPaymentQueue.default().presentCodeRedemptionSheet()
1082
- resolve(nil)
1083
- #else
1084
- reject(IapErrors.E_USER_CANCELLED.rawValue, "This method is not available on tvOS", nil)
1085
- #endif
1086
- }
1087
-
1088
- public func showManageSubscriptions(
1089
- _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
1090
- reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
1091
- ) {
1092
- #if !os(tvOS)
1093
- Task {
1094
- guard let scene = await currentWindow()?.windowScene as? UIWindowScene,
1095
- !ProcessInfo.processInfo.isiOSAppOnMac else {
1096
- return
1097
- }
1098
-
1099
- // Get all subscription SKUs before showing the management UI
1100
- let subscriptionSkus = await getAllSubscriptionProductIds()
1101
- self.pollingSkus = Set(subscriptionSkus)
1102
-
1103
- do {
1104
- try await AppStore.showManageSubscriptions(in: scene)
1105
-
1106
- // Start polling for subscription status changes after UI is shown
1107
- if !self.pollingSkus.isEmpty {
1108
- self.pollForSubscriptionStatusChanges()
1109
- }
1110
- } catch {
1111
- print("Error:(error)")
1112
- }
1113
- }
1114
-
1115
- resolve(nil)
1116
- #else
1117
- reject(IapErrors.E_USER_CANCELLED.rawValue, "This method is not available on tvOS", nil)
1118
- #endif
1119
- }
1120
-
1121
- func clearTransaction(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
1122
- Task {
1123
- for await result in Transaction.unfinished {
1124
- do {
1125
- // Check whether the transaction is verified. If it isn’t, catch `failedVerification` error.
1126
- let transaction = try checkVerified(result)
1127
- debugMessage("Finishing transaction")
1128
- await transaction.finish()
1129
- debugMessage("Finished transaction")
1130
- transactions.removeValue(forKey: String(transaction.id))
1131
- } catch {
1132
- debugMessage("Failed to finish transaction")
1133
- }
1134
- }
1135
- resolve(nil)
1136
- }
1137
- }
1138
-
1139
- // TODO: Duplicated code to get the latest transaction, can be cleaned up.
1140
- func beginRefundRequest(_ sku: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
1141
- #if !os(tvOS)
1142
- @Sendable func serialize(_ rs: Transaction.RefundRequestStatus?) -> String? {
1143
- guard let rs = rs else {return nil}
1144
- switch rs {
1145
- case .success: return "success"
1146
- case .userCancelled: return "userCancelled"
1147
-
1148
- default:
1149
- return nil
1150
- }
1151
- }
1152
-
1153
- Task {
1154
- let window = await currentWindow()
1155
- if let windowScene = await window?.windowScene {
1156
- if let product = await productStore.getProduct(productID: sku) {
1157
- if let result = await product.latestTransaction {
1158
- do {
1159
- // Check whether the transaction is verified. If it isn’t, catch `failedVerification` error.
1160
- let transaction = try checkVerified(result)
1161
- let refund = try await transaction.beginRefundRequest(in: windowScene )
1162
- resolve(serialize(refund))
1163
- } catch StoreError.failedVerification {
1164
- reject(IapErrors.E_UNKNOWN.rawValue, "Failed to verify transaction for sku \(sku)", StoreError.failedVerification)
1165
- } catch {
1166
- debugMessage(error)
1167
- reject(IapErrors.E_UNKNOWN.rawValue, "Failed to refund purchase", error)
1168
- }
1169
- } else {
1170
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find latest transaction for sku \(sku)", nil)
1171
- }
1172
- } else {
1173
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find product for sku \(sku)", nil)
1174
- }
1175
- } else {
1176
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Cannon find window Scene", nil)
1177
- }
1178
- }
1179
- #else
1180
- reject(IapErrors.E_USER_CANCELLED.rawValue, "This method is not available on tvOS", nil)
1181
- #endif
1182
- }
1183
-
1184
- public func getStorefront(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
1185
- Task {
1186
- let storefront = await Storefront.current
1187
- resolve(storefront?.countryCode)
1188
- }
1189
- }
1190
-
1191
- public func getAppTransaction(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
1192
- if #available(iOS 16.0, tvOS 16.0, *) {
1193
- Task {
1194
- do {
1195
- let shared = try await AppTransaction.shared
1196
-
1197
- switch shared {
1198
- case .verified(let appTransaction):
1199
- var result: [String: Any] = [:]
1200
-
1201
- // Add iOS 18.4+ properties
1202
- if #available(iOS 18.4, tvOS 18.4, *) {
1203
- result["appTransactionID"] = appTransaction.appTransactionID
1204
- result["originalPlatform"] = appTransaction.originalPlatform
1205
- }
1206
-
1207
- // Add other AppTransaction properties
1208
- result["originalAppVersion"] = appTransaction.originalAppVersion
1209
- result["originalPurchaseDate"] = appTransaction.originalPurchaseDate.timeIntervalSince1970 * 1000
1210
- result["deviceVerification"] = appTransaction.deviceVerification.base64EncodedString()
1211
- result["deviceVerificationNonce"] = appTransaction.deviceVerificationNonce.uuidString
1212
- result["appVersion"] = appTransaction.appVersion
1213
- result["signedDate"] = appTransaction.signedDate.timeIntervalSince1970 * 1000
1214
- result["environment"] = appTransaction.environment.rawValue
1215
-
1216
- resolve(result)
1217
-
1218
- case .unverified(_, let error):
1219
- reject(IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
1220
- "AppTransaction verification failed: \(error.localizedDescription)",
1221
- error)
1222
- }
1223
- } catch {
1224
- reject(IapErrors.E_UNKNOWN.rawValue,
1225
- "Failed to get AppTransaction: \(error.localizedDescription)",
1226
- error)
1227
- }
1228
- }
1229
- } else {
1230
- reject(IapErrors.E_SERVICE_ERROR.rawValue, "AppTransaction is only available on iOS 16.0+", nil)
1231
- }
1232
- }
1233
-
1234
- // MARK: - New methods from expo-iap
1235
-
1236
- public func getReceiptDataIos(
1237
- _ resolve: @escaping RCTPromiseResolveBlock,
1238
- reject: @escaping RCTPromiseRejectBlock
1239
- ) {
1240
- if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
1241
- FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
1242
- do {
1243
- let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
1244
- let receiptString = receiptData.base64EncodedString(options: [])
1245
- resolve(receiptString)
1246
- } catch {
1247
- reject(IapErrors.E_RECEIPT_FAILED.rawValue, "Error reading receipt data: \(error.localizedDescription)", error)
1248
- }
1249
- } else {
1250
- reject(IapErrors.E_RECEIPT_FAILED.rawValue, "App Store receipt not found", nil)
1251
- }
1252
- }
1253
-
1254
- public func isTransactionVerifiedIos(
1255
- _ sku: String,
1256
- resolve: @escaping RCTPromiseResolveBlock,
1257
- reject: @escaping RCTPromiseRejectBlock
1258
- ) {
1259
- Task {
1260
- if let product = await productStore.getProduct(productID: sku),
1261
- let result = await product.latestTransaction {
1262
- do {
1263
- // If this doesn't throw, the transaction is verified
1264
- _ = try checkVerified(result)
1265
- resolve(true)
1266
- } catch {
1267
- resolve(false)
1268
- }
1269
- } else {
1270
- resolve(false)
1271
- }
1272
- }
1273
- }
1274
-
1275
- public func getTransactionJwsIos(
1276
- _ sku: String,
1277
- resolve: @escaping RCTPromiseResolveBlock,
1278
- reject: @escaping RCTPromiseRejectBlock
1279
- ) {
1280
- Task {
1281
- if let product = await productStore.getProduct(productID: sku),
1282
- let result = await product.latestTransaction {
1283
- resolve(result.jwsRepresentation)
1284
- } else {
1285
- reject(IapErrors.E_DEVELOPER_ERROR.rawValue, "Can't find transaction for sku \(sku)", nil)
1286
- }
1287
- }
1288
- }
1289
-
1290
- public func validateReceiptIos(
1291
- _ sku: String,
1292
- resolve: @escaping RCTPromiseResolveBlock,
1293
- reject: @escaping RCTPromiseRejectBlock
1294
- ) {
1295
- Task {
1296
- // Get receipt data
1297
- var receiptData: String = ""
1298
- if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
1299
- FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
1300
- do {
1301
- let data = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
1302
- receiptData = data.base64EncodedString(options: [])
1303
- } catch {
1304
- // Continue with validation even if receipt retrieval fails
1305
- }
1306
- }
1307
-
1308
- var isValid = false
1309
- var jwsRepresentation: String?
1310
- var latestTransaction: [String: Any?]?
1311
-
1312
- // Get JWS representation and verify transaction
1313
- if let product = await productStore.getProduct(productID: sku),
1314
- let result = await product.latestTransaction {
1315
- jwsRepresentation = result.jwsRepresentation
1316
-
1317
- do {
1318
- // If this doesn't throw, the transaction is verified
1319
- let transaction = try checkVerified(result)
1320
- isValid = true
1321
- latestTransaction = serialize(transaction, result)
1322
- } catch {
1323
- isValid = false
1324
- }
1325
- }
1326
-
1327
- let response: [String: Any] = [
1328
- "isValid": isValid,
1329
- "receiptData": receiptData,
1330
- "jwsRepresentation": jwsRepresentation ?? "",
1331
- "latestTransaction": latestTransaction as Any
1332
- ]
1333
-
1334
- resolve(response)
1335
- }
1336
- }
1337
-
1338
- // MARK: - Subscription polling helpers
1339
-
1340
- private func getAllSubscriptionProductIds() async -> [String] {
1341
- let products = await productStore.getAllProducts()
1342
- return products.compactMap { product in
1343
- if product.subscription != nil {
1344
- return product.id
1345
- }
1346
- return nil
1347
- }
1348
- }
1349
-
1350
- private func pollForSubscriptionStatusChanges() {
1351
- subscriptionPollingTask?.cancel()
1352
- subscriptionPollingTask = Task {
1353
- try? await Task.sleep(nanoseconds: 1_500_000_000) // 1.5 seconds
1354
-
1355
- var previousStatuses: [String: Bool] = [:] // Track auto-renewal state with Bool
1356
-
1357
- for sku in self.pollingSkus {
1358
- guard let product = await self.productStore.getProduct(productID: sku),
1359
- let status = try? await product.subscription?.status.first else { continue }
1360
-
1361
- // Track willAutoRenew as a bool value
1362
- var willAutoRenew = false
1363
- if case .verified(let info) = status.renewalInfo {
1364
- willAutoRenew = info.willAutoRenew
1365
- }
1366
- previousStatuses[sku] = willAutoRenew
1367
- }
1368
-
1369
- for _ in 1...5 {
1370
- try? await Task.sleep(nanoseconds: 2_000_000_000) // 2 seconds
1371
- if Task.isCancelled {
1372
- return
1373
- }
1374
-
1375
- for sku in self.pollingSkus {
1376
- guard let product = await self.productStore.getProduct(productID: sku),
1377
- let status = try? await product.subscription?.status.first,
1378
- let result = await product.latestTransaction else { continue }
1379
- // Try to verify the transaction
1380
- let transaction: Transaction
1381
- do {
1382
- transaction = try checkVerified(result)
1383
- } catch {
1384
- continue // Skip if verification fails
1385
- }
1386
-
1387
- // Track current auto-renewal state
1388
- var currentWillAutoRenew = false
1389
- if case .verified(let info) = status.renewalInfo {
1390
- currentWillAutoRenew = info.willAutoRenew
1391
- }
1392
-
1393
- // Compare with previous state
1394
- if let previousWillAutoRenew = previousStatuses[sku],
1395
- previousWillAutoRenew != currentWillAutoRenew {
1396
- // Use the jwsRepresentation when serializing the transaction
1397
- var purchaseMap = serialize(transaction, result)
1398
-
1399
- if case .verified(let renewalInfo) = status.renewalInfo {
1400
- if let renewalInfoDict = serialize(renewalInfo) {
1401
- purchaseMap["renewalInfo"] = renewalInfoDict
1402
- }
1403
- }
1404
-
1405
- self.sendEvent?("purchase-updated", purchaseMap)
1406
- previousStatuses[sku] = currentWillAutoRenew
1407
- }
1408
- }
1409
- }
1410
- self.pollingSkus.removeAll()
1411
- }
1412
- }
1413
- }