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.
- package/NitroIap.podspec +33 -0
- package/README.md +163 -51
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +107 -138
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -13
- package/android/src/main/AndroidManifest.xml +1 -4
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +843 -0
- package/android/src/main/java/com/margelo/nitro/iap/NitroIapPackage.java +33 -0
- package/android/src/main/java/com/margelo/nitro/iap/Types.kt +173 -0
- package/ios/Bridge.h +8 -0
- package/ios/ErrorUtils.swift +153 -0
- package/ios/HybridRnIap.swift +1326 -0
- package/ios/ProductStore.swift +33 -0
- package/ios/reactnativeiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/reactnativeiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/lib/module/helpers/subscription.js +56 -0
- package/lib/module/helpers/subscription.js.map +1 -0
- package/lib/module/hooks/useIAP.js +175 -123
- package/lib/module/hooks/useIAP.js.map +1 -1
- package/lib/module/index.js +1015 -9
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/module/specs/RnIap.nitro.js +4 -0
- package/lib/{commonjs/modules/common.js.map → module/specs/RnIap.nitro.js.map} +1 -1
- package/lib/module/types.js +187 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/error.js +80 -0
- package/lib/module/utils/error.js.map +1 -0
- package/lib/module/utils/type-bridge.js +202 -0
- package/lib/module/utils/type-bridge.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/plugin/src/withIAP.d.ts +2 -7
- package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
- package/lib/typescript/scripts/check-nitro-versions.d.ts +3 -0
- package/lib/typescript/scripts/check-nitro-versions.d.ts.map +1 -0
- package/lib/typescript/src/helpers/subscription.d.ts +14 -0
- package/lib/typescript/src/helpers/subscription.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useIAP.d.ts +42 -26
- package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +356 -8
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/RnIap.nitro.d.ts +404 -0
- package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +544 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/error.d.ts +30 -0
- package/lib/typescript/src/utils/error.d.ts.map +1 -0
- package/lib/typescript/src/utils/type-bridge.d.ts +40 -0
- package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -0
- package/nitro.json +17 -0
- package/nitrogen/generated/android/NitroIap+autolinking.cmake +80 -0
- package/nitrogen/generated/android/NitroIap+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroIapOnLoad.cpp +50 -0
- package/nitrogen/generated/android/NitroIapOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JFunc_void_NitroProduct.hpp +78 -0
- package/nitrogen/generated/android/c++/JFunc_void_NitroPurchase.hpp +78 -0
- package/nitrogen/generated/android/c++/JFunc_void_NitroPurchaseResult.hpp +78 -0
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +577 -0
- package/nitrogen/generated/android/c++/JHybridRnIapSpec.hpp +93 -0
- package/nitrogen/generated/android/c++/JNitroAndroidReceiptValidationOptions.hpp +66 -0
- package/nitrogen/generated/android/c++/JNitroAvailablePurchasesAndroidOptions.hpp +54 -0
- package/nitrogen/generated/android/c++/JNitroAvailablePurchasesIosOptions.hpp +65 -0
- package/nitrogen/generated/android/c++/JNitroAvailablePurchasesOptions.hpp +62 -0
- package/nitrogen/generated/android/c++/JNitroFinishTransactionAndroidParams.hpp +58 -0
- package/nitrogen/generated/android/c++/JNitroFinishTransactionIosParams.hpp +53 -0
- package/nitrogen/generated/android/c++/JNitroFinishTransactionParams.hpp +62 -0
- package/nitrogen/generated/android/c++/JNitroProduct.hpp +154 -0
- package/nitrogen/generated/android/c++/JNitroPurchase.hpp +122 -0
- package/nitrogen/generated/android/c++/JNitroPurchaseRequest.hpp +66 -0
- package/nitrogen/generated/android/c++/JNitroPurchaseResult.hpp +70 -0
- package/nitrogen/generated/android/c++/JNitroReceiptValidationParams.hpp +60 -0
- package/nitrogen/generated/android/c++/JNitroReceiptValidationResultAndroid.hpp +122 -0
- package/nitrogen/generated/android/c++/JNitroReceiptValidationResultIOS.hpp +68 -0
- package/nitrogen/generated/android/c++/JNitroRequestPurchaseAndroid.hpp +115 -0
- package/nitrogen/generated/android/c++/JNitroRequestPurchaseIos.hpp +84 -0
- package/nitrogen/generated/android/c++/JNitroSubscriptionOffer.hpp +57 -0
- package/nitrogen/generated/android/c++/JNitroSubscriptionRenewalInfo.hpp +74 -0
- package/nitrogen/generated/android/c++/JNitroSubscriptionStatus.hpp +64 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_NitroPurchaseResult.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Boolean_NitroPurchaseResult.hpp +71 -0
- package/nitrogen/generated/android/c++/JVariant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.hpp +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroProduct.kt +81 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroPurchase.kt +81 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Func_void_NitroPurchaseResult.kt +81 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/HybridRnIapSpec.kt +198 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAndroidReceiptValidationOptions.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAvailablePurchasesAndroidOptions.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAvailablePurchasesIosOptions.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroAvailablePurchasesOptions.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroFinishTransactionAndroidParams.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroFinishTransactionIosParams.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroFinishTransactionParams.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroIapOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroProduct.kt +104 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchase.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchaseRequest.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroPurchaseResult.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationParams.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationResultAndroid.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroReceiptValidationResultIOS.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroRequestPurchaseAndroid.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroRequestPurchaseIos.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroSubscriptionOffer.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroSubscriptionRenewalInfo.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroSubscriptionStatus.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_Boolean_NitroPurchaseResult.kt +42 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.kt +42 -0
- package/nitrogen/generated/ios/NitroIap+autolinking.rb +60 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.cpp +152 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +1061 -0
- package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +107 -0
- package/nitrogen/generated/ios/NitroIapAutolinking.mm +33 -0
- package/nitrogen/generated/ios/NitroIapAutolinking.swift +25 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +355 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NitroProduct.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NitroPurchase.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_NitroPurchaseResult.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_NitroProduct_.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_NitroPurchase_.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__vector_NitroSubscriptionStatus__.swift +54 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_NitroReceiptValidationResultIOS__NitroReceiptValidationResultAndroid_.swift +59 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_bool__NitroPurchaseResult_.swift +59 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_NitroProduct_.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_NitroPurchase_.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridRnIapSpec.swift +78 -0
- package/nitrogen/generated/ios/swift/HybridRnIapSpec_cxx.swift +750 -0
- package/nitrogen/generated/ios/swift/NitroAndroidReceiptValidationOptions.swift +80 -0
- package/nitrogen/generated/ios/swift/NitroAvailablePurchasesAndroidOptions.swift +54 -0
- package/nitrogen/generated/ios/swift/NitroAvailablePurchasesIosOptions.swift +116 -0
- package/nitrogen/generated/ios/swift/NitroAvailablePurchasesOptions.swift +84 -0
- package/nitrogen/generated/ios/swift/NitroFinishTransactionAndroidParams.swift +58 -0
- package/nitrogen/generated/ios/swift/NitroFinishTransactionIosParams.swift +35 -0
- package/nitrogen/generated/ios/swift/NitroFinishTransactionParams.swift +84 -0
- package/nitrogen/generated/ios/swift/NitroProduct.swift +653 -0
- package/nitrogen/generated/ios/swift/NitroPurchase.swift +453 -0
- package/nitrogen/generated/ios/swift/NitroPurchaseRequest.swift +84 -0
- package/nitrogen/generated/ios/swift/NitroPurchaseResult.swift +117 -0
- package/nitrogen/generated/ios/swift/NitroReceiptValidationParams.swift +65 -0
- package/nitrogen/generated/ios/swift/NitroReceiptValidationResultAndroid.swift +258 -0
- package/nitrogen/generated/ios/swift/NitroReceiptValidationResultIOS.swift +87 -0
- package/nitrogen/generated/ios/swift/NitroRequestPurchaseAndroid.swift +225 -0
- package/nitrogen/generated/ios/swift/NitroRequestPurchaseIos.swift +161 -0
- package/nitrogen/generated/ios/swift/NitroSubscriptionOffer.swift +46 -0
- package/nitrogen/generated/ios/swift/NitroSubscriptionRenewalInfo.swift +152 -0
- package/nitrogen/generated/ios/swift/NitroSubscriptionStatus.swift +76 -0
- package/nitrogen/generated/ios/swift/Variant_Bool_NitroPurchaseResult.swift +18 -0
- package/nitrogen/generated/ios/swift/Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.swift +18 -0
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.cpp +50 -0
- package/nitrogen/generated/shared/c++/HybridRnIapSpec.hpp +125 -0
- package/nitrogen/generated/shared/c++/NitroAndroidReceiptValidationOptions.hpp +80 -0
- package/nitrogen/generated/shared/c++/NitroAvailablePurchasesAndroidOptions.hpp +68 -0
- package/nitrogen/generated/shared/c++/NitroAvailablePurchasesIosOptions.hpp +79 -0
- package/nitrogen/generated/shared/c++/NitroAvailablePurchasesOptions.hpp +76 -0
- package/nitrogen/generated/shared/c++/NitroFinishTransactionAndroidParams.hpp +72 -0
- package/nitrogen/generated/shared/c++/NitroFinishTransactionIosParams.hpp +67 -0
- package/nitrogen/generated/shared/c++/NitroFinishTransactionParams.hpp +76 -0
- package/nitrogen/generated/shared/c++/NitroProduct.hpp +168 -0
- package/nitrogen/generated/shared/c++/NitroPurchase.hpp +136 -0
- package/nitrogen/generated/shared/c++/NitroPurchaseRequest.hpp +76 -0
- package/nitrogen/generated/shared/c++/NitroPurchaseResult.hpp +84 -0
- package/nitrogen/generated/shared/c++/NitroReceiptValidationParams.hpp +74 -0
- package/nitrogen/generated/shared/c++/NitroReceiptValidationResultAndroid.hpp +136 -0
- package/nitrogen/generated/shared/c++/NitroReceiptValidationResultIOS.hpp +82 -0
- package/nitrogen/generated/shared/c++/NitroRequestPurchaseAndroid.hpp +95 -0
- package/nitrogen/generated/shared/c++/NitroRequestPurchaseIos.hpp +85 -0
- package/nitrogen/generated/shared/c++/NitroSubscriptionOffer.hpp +71 -0
- package/nitrogen/generated/shared/c++/NitroSubscriptionRenewalInfo.hpp +88 -0
- package/nitrogen/generated/shared/c++/NitroSubscriptionStatus.hpp +78 -0
- package/package.json +145 -104
- package/plugin/build/src/withIAP.d.ts +3 -0
- package/plugin/build/src/withIAP.js +81 -0
- package/plugin/build/tsconfig.tsbuildinfo +1 -0
- package/plugin/build/withIAP.d.ts +2 -7
- package/plugin/build/withIAP.js +62 -51
- package/plugin/src/withIAP.ts +119 -0
- package/plugin/tsconfig.json +18 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/src/helpers/subscription.ts +65 -0
- package/src/hooks/useIAP.ts +361 -222
- package/src/index.ts +1194 -9
- package/src/specs/RnIap.nitro.ts +501 -0
- package/src/types.ts +680 -0
- package/src/utils/error.ts +97 -0
- package/src/utils/type-bridge.ts +209 -0
- package/LICENSE +0 -21
- package/RNIap.podspec +0 -36
- package/android/src/amazon/AndroidManifest.xml +0 -14
- package/android/src/amazon/java/com/dooboolab/rniap/EventSender.kt +0 -10
- package/android/src/amazon/java/com/dooboolab/rniap/PurchasingServiceProxy.kt +0 -29
- package/android/src/amazon/java/com/dooboolab/rniap/PurchasingServiceProxyAmazonImpl.kt +0 -31
- package/android/src/amazon/java/com/dooboolab/rniap/RNIapActivityListener.kt +0 -55
- package/android/src/amazon/java/com/dooboolab/rniap/RNIapAmazonListener.kt +0 -325
- package/android/src/amazon/java/com/dooboolab/rniap/RNIapAmazonModule.kt +0 -244
- package/android/src/amazon/java/com/dooboolab/rniap/RNIapPackage.kt +0 -17
- package/android/src/amazon/java/com/dooboolab/rniap/modifysubscription/RNIapAmazonModifySubscriptionListener.kt +0 -88
- package/android/src/amazon/java/com/dooboolab/rniap/utils/Extensions.kt +0 -22
- package/android/src/main/java/com/dooboolab/rniap/PromiseUtils.kt +0 -62
- package/android/src/main/java/com/dooboolab/rniap/PromiseUtlis.kt +0 -43
- package/android/src/play/java/com/dooboolab/rniap/PlayUtils.kt +0 -114
- package/android/src/play/java/com/dooboolab/rniap/RNIapActivityListener.kt +0 -15
- package/android/src/play/java/com/dooboolab/rniap/RNIapModule.kt +0 -911
- package/android/src/play/java/com/dooboolab/rniap/RNIapPackage.kt +0 -17
- package/android/src/testAmazon/java/com/dooboolab/rniap/RNIapAmazonModuleTest.kt +0 -170
- package/app.plugin.js +0 -1
- package/ios/IapSerializationUtils.swift +0 -290
- package/ios/IapTypes.swift +0 -56
- package/ios/IapUtils.swift +0 -40
- package/ios/LatestPromiseKeeper.swift +0 -52
- package/ios/RNIapIos-Bridging-Header.h +0 -2
- package/ios/RNIapIos.m +0 -69
- package/ios/RNIapIos.swift +0 -868
- package/ios/RNIapIos.xcodeproj/project.pbxproj +0 -289
- package/ios/RNIapIosSk2.m +0 -126
- package/ios/RNIapIosSk2.swift +0 -1413
- package/ios/ThreadSafe.swift +0 -18
- package/lib/commonjs/eventEmitter.js +0 -195
- package/lib/commonjs/eventEmitter.js.map +0 -1
- package/lib/commonjs/hooks/index.js +0 -17
- package/lib/commonjs/hooks/index.js.map +0 -1
- package/lib/commonjs/hooks/useIAP.js +0 -203
- package/lib/commonjs/hooks/useIAP.js.map +0 -1
- package/lib/commonjs/hooks/withIAPContext.js +0 -95
- package/lib/commonjs/hooks/withIAPContext.js.map +0 -1
- package/lib/commonjs/iap.js +0 -836
- package/lib/commonjs/iap.js.map +0 -1
- package/lib/commonjs/index.js +0 -105
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/internal/enhancedFetch.js +0 -26
- package/lib/commonjs/internal/enhancedFetch.js.map +0 -1
- package/lib/commonjs/internal/fillProductsWithAdditionalData.js +0 -50
- package/lib/commonjs/internal/fillProductsWithAdditionalData.js.map +0 -1
- package/lib/commonjs/internal/index.js +0 -39
- package/lib/commonjs/internal/index.js.map +0 -1
- package/lib/commonjs/internal/platform.js +0 -119
- package/lib/commonjs/internal/platform.js.map +0 -1
- package/lib/commonjs/modules/amazon.js +0 -50
- package/lib/commonjs/modules/amazon.js.map +0 -1
- package/lib/commonjs/modules/android.js +0 -92
- package/lib/commonjs/modules/android.js.map +0 -1
- package/lib/commonjs/modules/common.js +0 -2
- package/lib/commonjs/modules/index.js +0 -50
- package/lib/commonjs/modules/index.js.map +0 -1
- package/lib/commonjs/modules/ios.js +0 -160
- package/lib/commonjs/modules/ios.js.map +0 -1
- package/lib/commonjs/modules/iosSk2.js +0 -113
- package/lib/commonjs/modules/iosSk2.js.map +0 -1
- package/lib/commonjs/purchaseError.js +0 -170
- package/lib/commonjs/purchaseError.js.map +0 -1
- package/lib/commonjs/types/amazon.js +0 -2
- package/lib/commonjs/types/amazon.js.map +0 -1
- package/lib/commonjs/types/android.js +0 -67
- package/lib/commonjs/types/android.js.map +0 -1
- package/lib/commonjs/types/apple.js +0 -24
- package/lib/commonjs/types/apple.js.map +0 -1
- package/lib/commonjs/types/appleSk2.js +0 -137
- package/lib/commonjs/types/appleSk2.js.map +0 -1
- package/lib/commonjs/types/index.js +0 -67
- package/lib/commonjs/types/index.js.map +0 -1
- package/lib/commonjs/utils/errorMapping.js +0 -83
- package/lib/commonjs/utils/errorMapping.js.map +0 -1
- package/lib/commonjs/utils/typeGuards.js +0 -74
- package/lib/commonjs/utils/typeGuards.js.map +0 -1
- package/lib/module/eventEmitter.js +0 -185
- package/lib/module/eventEmitter.js.map +0 -1
- package/lib/module/hooks/index.js +0 -2
- package/lib/module/hooks/index.js.map +0 -1
- package/lib/module/hooks/withIAPContext.js +0 -86
- package/lib/module/hooks/withIAPContext.js.map +0 -1
- package/lib/module/iap.js +0 -805
- package/lib/module/iap.js.map +0 -1
- package/lib/module/internal/enhancedFetch.js +0 -19
- package/lib/module/internal/enhancedFetch.js.map +0 -1
- package/lib/module/internal/fillProductsWithAdditionalData.js +0 -43
- package/lib/module/internal/fillProductsWithAdditionalData.js.map +0 -1
- package/lib/module/internal/index.js +0 -4
- package/lib/module/internal/index.js.map +0 -1
- package/lib/module/internal/platform.js +0 -102
- package/lib/module/internal/platform.js.map +0 -1
- package/lib/module/modules/amazon.js +0 -42
- package/lib/module/modules/amazon.js.map +0 -1
- package/lib/module/modules/android.js +0 -81
- package/lib/module/modules/android.js.map +0 -1
- package/lib/module/modules/common.js +0 -2
- package/lib/module/modules/common.js.map +0 -1
- package/lib/module/modules/index.js +0 -5
- package/lib/module/modules/index.js.map +0 -1
- package/lib/module/modules/ios.js +0 -145
- package/lib/module/modules/ios.js.map +0 -1
- package/lib/module/modules/iosSk2.js +0 -96
- package/lib/module/modules/iosSk2.js.map +0 -1
- package/lib/module/purchaseError.js +0 -164
- package/lib/module/purchaseError.js.map +0 -1
- package/lib/module/types/amazon.js +0 -2
- package/lib/module/types/amazon.js.map +0 -1
- package/lib/module/types/android.js +0 -63
- package/lib/module/types/android.js.map +0 -1
- package/lib/module/types/apple.js +0 -17
- package/lib/module/types/apple.js.map +0 -1
- package/lib/module/types/appleSk2.js +0 -129
- package/lib/module/types/appleSk2.js.map +0 -1
- package/lib/module/types/index.js +0 -75
- package/lib/module/types/index.js.map +0 -1
- package/lib/module/utils/errorMapping.js +0 -75
- package/lib/module/utils/errorMapping.js.map +0 -1
- package/lib/module/utils/typeGuards.js +0 -61
- package/lib/module/utils/typeGuards.js.map +0 -1
- package/lib/typescript/src/eventEmitter.d.ts +0 -151
- package/lib/typescript/src/eventEmitter.d.ts.map +0 -1
- package/lib/typescript/src/hooks/index.d.ts +0 -2
- package/lib/typescript/src/hooks/index.d.ts.map +0 -1
- package/lib/typescript/src/hooks/withIAPContext.d.ts +0 -27
- package/lib/typescript/src/hooks/withIAPContext.d.ts.map +0 -1
- package/lib/typescript/src/iap.d.ts +0 -503
- package/lib/typescript/src/iap.d.ts.map +0 -1
- package/lib/typescript/src/internal/enhancedFetch.d.ts +0 -6
- package/lib/typescript/src/internal/enhancedFetch.d.ts.map +0 -1
- package/lib/typescript/src/internal/fillProductsWithAdditionalData.d.ts +0 -7
- package/lib/typescript/src/internal/fillProductsWithAdditionalData.d.ts.map +0 -1
- package/lib/typescript/src/internal/index.d.ts +0 -4
- package/lib/typescript/src/internal/index.d.ts.map +0 -1
- package/lib/typescript/src/internal/platform.d.ts +0 -27
- package/lib/typescript/src/internal/platform.d.ts.map +0 -1
- package/lib/typescript/src/modules/amazon.d.ts +0 -55
- package/lib/typescript/src/modules/amazon.d.ts.map +0 -1
- package/lib/typescript/src/modules/android.d.ts +0 -74
- package/lib/typescript/src/modules/android.d.ts.map +0 -1
- package/lib/typescript/src/modules/common.d.ts +0 -14
- package/lib/typescript/src/modules/common.d.ts.map +0 -1
- package/lib/typescript/src/modules/index.d.ts +0 -5
- package/lib/typescript/src/modules/index.d.ts.map +0 -1
- package/lib/typescript/src/modules/ios.d.ts +0 -117
- package/lib/typescript/src/modules/ios.d.ts.map +0 -1
- package/lib/typescript/src/modules/iosSk2.d.ts +0 -140
- package/lib/typescript/src/modules/iosSk2.d.ts.map +0 -1
- package/lib/typescript/src/purchaseError.d.ts +0 -133
- package/lib/typescript/src/purchaseError.d.ts.map +0 -1
- package/lib/typescript/src/types/amazon.d.ts +0 -33
- package/lib/typescript/src/types/amazon.d.ts.map +0 -1
- package/lib/typescript/src/types/android.d.ts +0 -66
- package/lib/typescript/src/types/android.d.ts.map +0 -1
- package/lib/typescript/src/types/apple.d.ts +0 -27
- package/lib/typescript/src/types/apple.d.ts.map +0 -1
- package/lib/typescript/src/types/appleSk2.d.ts +0 -129
- package/lib/typescript/src/types/appleSk2.d.ts.map +0 -1
- package/lib/typescript/src/types/index.d.ts +0 -302
- package/lib/typescript/src/types/index.d.ts.map +0 -1
- package/lib/typescript/src/utils/errorMapping.d.ts +0 -29
- package/lib/typescript/src/utils/errorMapping.d.ts.map +0 -1
- package/lib/typescript/src/utils/typeGuards.d.ts +0 -53
- package/lib/typescript/src/utils/typeGuards.d.ts.map +0 -1
- package/src/eventEmitter.ts +0 -212
- package/src/hooks/index.ts +0 -1
- package/src/hooks/withIAPContext.tsx +0 -179
- package/src/iap.ts +0 -1046
- package/src/internal/enhancedFetch.ts +0 -25
- package/src/internal/fillProductsWithAdditionalData.ts +0 -47
- package/src/internal/index.ts +0 -3
- package/src/internal/platform.ts +0 -135
- package/src/modules/amazon.ts +0 -94
- package/src/modules/android.ts +0 -179
- package/src/modules/common.ts +0 -16
- package/src/modules/index.ts +0 -4
- package/src/modules/ios.ts +0 -229
- package/src/modules/iosSk2.ts +0 -194
- package/src/purchaseError.ts +0 -196
- package/src/types/amazon.ts +0 -40
- package/src/types/android.ts +0 -89
- package/src/types/apple.ts +0 -44
- package/src/types/appleSk2.ts +0 -275
- package/src/types/index.ts +0 -379
- package/src/utils/errorMapping.ts +0 -88
- package/src/utils/typeGuards.ts +0 -90
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
package com.margelo.nitro.iap
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.android.billingclient.api.*
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import com.google.android.gms.common.ConnectionResult
|
|
9
|
+
import com.google.android.gms.common.GoogleApiAvailability
|
|
10
|
+
import com.margelo.nitro.NitroModules
|
|
11
|
+
import com.margelo.nitro.core.Promise
|
|
12
|
+
import org.json.JSONArray
|
|
13
|
+
import org.json.JSONObject
|
|
14
|
+
import kotlinx.coroutines.Dispatchers
|
|
15
|
+
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
16
|
+
import kotlinx.coroutines.withContext
|
|
17
|
+
import kotlin.coroutines.resume
|
|
18
|
+
import kotlin.coroutines.resumeWithException
|
|
19
|
+
|
|
20
|
+
class HybridRnIap : HybridRnIapSpec(), PurchasesUpdatedListener, BillingClientStateListener {
|
|
21
|
+
companion object {
|
|
22
|
+
const val TAG = "RnIap"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Get ReactApplicationContext lazily from NitroModules
|
|
26
|
+
private val context: ReactApplicationContext by lazy {
|
|
27
|
+
NitroModules.applicationContext as ReactApplicationContext
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private var billingClient: BillingClient? = null
|
|
31
|
+
private val skuDetailsCache = mutableMapOf<String, ProductDetails>()
|
|
32
|
+
|
|
33
|
+
// Event listeners
|
|
34
|
+
private val purchaseUpdatedListeners = mutableListOf<(NitroPurchase) -> Unit>()
|
|
35
|
+
private val purchaseErrorListeners = mutableListOf<(NitroPurchaseResult) -> Unit>()
|
|
36
|
+
private val promotedProductListenersIOS = mutableListOf<(NitroProduct) -> Unit>()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// Connection methods
|
|
40
|
+
override fun initConnection(): Promise<Boolean> {
|
|
41
|
+
return Promise.async {
|
|
42
|
+
if (billingClient?.isReady == true) {
|
|
43
|
+
return@async true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check if Google Play Services is available
|
|
47
|
+
val googleApiAvailability = GoogleApiAvailability.getInstance()
|
|
48
|
+
val resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context)
|
|
49
|
+
if (resultCode != ConnectionResult.SUCCESS) {
|
|
50
|
+
val errorMsg = BillingUtils.getPlayServicesErrorMessage(resultCode)
|
|
51
|
+
val errorJson = BillingUtils.createErrorJson(
|
|
52
|
+
IapErrorCode.E_NOT_PREPARED,
|
|
53
|
+
errorMsg,
|
|
54
|
+
resultCode
|
|
55
|
+
)
|
|
56
|
+
throw Exception(errorJson)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
withContext(Dispatchers.Main) {
|
|
60
|
+
initBillingClient()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
override fun endConnection(): Promise<Boolean> {
|
|
66
|
+
return Promise.async {
|
|
67
|
+
billingClient?.endConnection()
|
|
68
|
+
billingClient = null
|
|
69
|
+
true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Product methods
|
|
74
|
+
override fun fetchProducts(skus: Array<String>, type: String): Promise<Array<NitroProduct>> {
|
|
75
|
+
return Promise.async {
|
|
76
|
+
Log.d(TAG, "fetchProducts called with SKUs: ${skus.joinToString()}, type: $type")
|
|
77
|
+
|
|
78
|
+
// Validate SKU list
|
|
79
|
+
if (skus.isEmpty()) {
|
|
80
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
81
|
+
IapErrorCode.E_EMPTY_SKU_LIST,
|
|
82
|
+
"SKU list is empty"
|
|
83
|
+
))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Initialize billing client if not already done
|
|
87
|
+
// Auto-reconnection will handle service disconnections automatically
|
|
88
|
+
if (billingClient == null) {
|
|
89
|
+
initConnection().await()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
val productType = if (type == "subs") {
|
|
93
|
+
BillingClient.ProductType.SUBS
|
|
94
|
+
} else {
|
|
95
|
+
BillingClient.ProductType.INAPP
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
val productList = skus.map { sku ->
|
|
99
|
+
QueryProductDetailsParams.Product.newBuilder()
|
|
100
|
+
.setProductId(sku)
|
|
101
|
+
.setProductType(productType)
|
|
102
|
+
.build()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
val params = QueryProductDetailsParams.newBuilder()
|
|
106
|
+
.setProductList(productList)
|
|
107
|
+
.build()
|
|
108
|
+
|
|
109
|
+
val result = suspendCancellableCoroutine<List<ProductDetails>> { continuation ->
|
|
110
|
+
billingClient?.queryProductDetailsAsync(params) { billingResult, productDetailsResult ->
|
|
111
|
+
Log.d(TAG, "queryProductDetailsAsync response: code=${billingResult.responseCode}")
|
|
112
|
+
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
|
113
|
+
val productDetailsList = productDetailsResult.productDetailsList ?: emptyList()
|
|
114
|
+
Log.d(TAG, "Retrieved ${productDetailsList.size} products")
|
|
115
|
+
// Cache the product details
|
|
116
|
+
if (productDetailsList.isNotEmpty()) {
|
|
117
|
+
for (details in productDetailsList) {
|
|
118
|
+
Log.d(TAG, "Product: ${details.productId}, has offers: ${details.subscriptionOfferDetails?.size ?: 0}")
|
|
119
|
+
skuDetailsCache[details.productId] = details
|
|
120
|
+
}
|
|
121
|
+
continuation.resume(productDetailsList)
|
|
122
|
+
} else {
|
|
123
|
+
continuation.resume(emptyList())
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
continuation.resumeWithException(
|
|
127
|
+
Exception(getBillingErrorMessage(billingResult.responseCode))
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
Log.d(TAG, "Converting ${result.size} products to NitroProducts")
|
|
134
|
+
|
|
135
|
+
val nitroProducts = result.map { productDetails ->
|
|
136
|
+
convertToNitroProduct(productDetails, type)
|
|
137
|
+
}.toTypedArray()
|
|
138
|
+
|
|
139
|
+
Log.d(TAG, "Returning ${nitroProducts.size} NitroProducts to JS")
|
|
140
|
+
nitroProducts
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Purchase methods
|
|
145
|
+
// Purchase methods (Unified)
|
|
146
|
+
override fun requestPurchase(request: NitroPurchaseRequest): Promise<Unit> {
|
|
147
|
+
return Promise.async {
|
|
148
|
+
// Android implementation
|
|
149
|
+
val androidRequest = request.android ?: run {
|
|
150
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
151
|
+
IapErrorCode.E_USER_ERROR,
|
|
152
|
+
"No Android request provided"
|
|
153
|
+
))
|
|
154
|
+
return@async
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Validate SKU list
|
|
158
|
+
if (androidRequest.skus.isEmpty()) {
|
|
159
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
160
|
+
IapErrorCode.E_EMPTY_SKU_LIST,
|
|
161
|
+
"SKU list is empty"
|
|
162
|
+
))
|
|
163
|
+
return@async
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
// Initialize billing client if not already done
|
|
168
|
+
if (billingClient == null) {
|
|
169
|
+
initConnection().await()
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Get current activity - this should be done on Main thread
|
|
173
|
+
val activity = withContext(Dispatchers.Main) {
|
|
174
|
+
context.currentActivity
|
|
175
|
+
} ?: run {
|
|
176
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
177
|
+
IapErrorCode.E_ACTIVITY_UNAVAILABLE,
|
|
178
|
+
"Current activity is null. Please ensure the app is in foreground."
|
|
179
|
+
))
|
|
180
|
+
return@async
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
withContext(Dispatchers.Main) {
|
|
184
|
+
val productDetailsList = mutableListOf<BillingFlowParams.ProductDetailsParams>()
|
|
185
|
+
|
|
186
|
+
// Build product details list
|
|
187
|
+
for (sku in androidRequest.skus) {
|
|
188
|
+
val productDetails = skuDetailsCache[sku] ?: run {
|
|
189
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
190
|
+
IapErrorCode.E_SKU_NOT_FOUND,
|
|
191
|
+
"Product not found: $sku. Call requestProducts first.",
|
|
192
|
+
sku
|
|
193
|
+
))
|
|
194
|
+
return@withContext
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
val productDetailsParams = BillingFlowParams.ProductDetailsParams.newBuilder()
|
|
198
|
+
.setProductDetails(productDetails)
|
|
199
|
+
|
|
200
|
+
// Add offer token for subscriptions
|
|
201
|
+
val subscriptionOffers = androidRequest.subscriptionOffers
|
|
202
|
+
if (!subscriptionOffers.isNullOrEmpty()) {
|
|
203
|
+
val offer = subscriptionOffers.find { it.sku == sku }
|
|
204
|
+
offer?.offerToken?.let { productDetailsParams.setOfferToken(it) }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
productDetailsList.add(productDetailsParams.build())
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
val billingFlowParams = BillingFlowParams.newBuilder()
|
|
211
|
+
.setProductDetailsParamsList(productDetailsList)
|
|
212
|
+
.setIsOfferPersonalized(androidRequest.isOfferPersonalized ?: false)
|
|
213
|
+
|
|
214
|
+
// Set subscription update params if replacing
|
|
215
|
+
val purchaseToken = androidRequest.purchaseTokenAndroid
|
|
216
|
+
val replacementMode = androidRequest.replacementModeAndroid
|
|
217
|
+
if (!purchaseToken.isNullOrEmpty() && replacementMode != null) {
|
|
218
|
+
val updateParams = BillingFlowParams.SubscriptionUpdateParams.newBuilder()
|
|
219
|
+
.setOldPurchaseToken(purchaseToken)
|
|
220
|
+
.setSubscriptionReplacementMode(replacementMode.toInt())
|
|
221
|
+
.build()
|
|
222
|
+
billingFlowParams.setSubscriptionUpdateParams(updateParams)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Set obfuscated identifiers
|
|
226
|
+
androidRequest.obfuscatedAccountIdAndroid?.let { billingFlowParams.setObfuscatedAccountId(it) }
|
|
227
|
+
androidRequest.obfuscatedProfileIdAndroid?.let { billingFlowParams.setObfuscatedProfileId(it) }
|
|
228
|
+
|
|
229
|
+
// Launch billing flow - results will be handled by onPurchasesUpdated
|
|
230
|
+
val billingResult = billingClient?.launchBillingFlow(activity, billingFlowParams.build())
|
|
231
|
+
if (billingResult?.responseCode != BillingClient.BillingResponseCode.OK) {
|
|
232
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
233
|
+
getBillingErrorCode(billingResult?.responseCode ?: -1),
|
|
234
|
+
getBillingErrorMessage(billingResult?.responseCode ?: -1)
|
|
235
|
+
))
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Purchase results will be handled by onPurchasesUpdated callback
|
|
239
|
+
}
|
|
240
|
+
} catch (e: Exception) {
|
|
241
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
242
|
+
IapErrorCode.E_UNKNOWN,
|
|
243
|
+
e.message ?: "Unknown error occurred"
|
|
244
|
+
))
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Purchase history methods (Unified)
|
|
250
|
+
override fun getAvailablePurchases(options: NitroAvailablePurchasesOptions?): Promise<Array<NitroPurchase>> {
|
|
251
|
+
return Promise.async {
|
|
252
|
+
// Android implementation
|
|
253
|
+
val androidOptions = options?.android
|
|
254
|
+
val type = androidOptions?.type ?: "inapp"
|
|
255
|
+
|
|
256
|
+
// Initialize billing client if not already done
|
|
257
|
+
// Auto-reconnection will handle service disconnections automatically
|
|
258
|
+
if (billingClient == null) {
|
|
259
|
+
initConnection().await()
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
val productType = if (type == "subs") {
|
|
263
|
+
BillingClient.ProductType.SUBS
|
|
264
|
+
} else {
|
|
265
|
+
BillingClient.ProductType.INAPP
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
val params = QueryPurchasesParams.newBuilder()
|
|
269
|
+
.setProductType(productType)
|
|
270
|
+
.build()
|
|
271
|
+
|
|
272
|
+
val result = suspendCancellableCoroutine<List<Purchase>> { continuation ->
|
|
273
|
+
billingClient?.queryPurchasesAsync(params) { billingResult, purchases ->
|
|
274
|
+
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
|
275
|
+
continuation.resume(purchases)
|
|
276
|
+
} else {
|
|
277
|
+
continuation.resumeWithException(
|
|
278
|
+
Exception(getBillingErrorMessage(billingResult.responseCode))
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
result.map { purchase ->
|
|
285
|
+
convertToNitroPurchase(purchase)
|
|
286
|
+
}.toTypedArray()
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Transaction management methods (Unified)
|
|
291
|
+
override fun finishTransaction(params: NitroFinishTransactionParams): Promise<Variant_Boolean_NitroPurchaseResult> {
|
|
292
|
+
return Promise.async {
|
|
293
|
+
// Android implementation
|
|
294
|
+
val androidParams = params.android ?: return@async Variant_Boolean_NitroPurchaseResult.First(true)
|
|
295
|
+
val purchaseToken = androidParams.purchaseToken
|
|
296
|
+
val isConsumable = androidParams.isConsumable ?: false
|
|
297
|
+
|
|
298
|
+
// Initialize billing client if not already done
|
|
299
|
+
// Auto-reconnection will handle service disconnections automatically
|
|
300
|
+
if (billingClient == null) {
|
|
301
|
+
initConnection().await()
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (isConsumable) {
|
|
305
|
+
// Consume the purchase
|
|
306
|
+
val consumeParams = ConsumeParams.newBuilder()
|
|
307
|
+
.setPurchaseToken(purchaseToken)
|
|
308
|
+
.build()
|
|
309
|
+
|
|
310
|
+
val result = suspendCancellableCoroutine<Pair<BillingResult, String>> { continuation ->
|
|
311
|
+
billingClient?.consumeAsync(consumeParams) { billingResult, token ->
|
|
312
|
+
continuation.resume(Pair(billingResult, token))
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
Variant_Boolean_NitroPurchaseResult.Second(
|
|
317
|
+
NitroPurchaseResult(
|
|
318
|
+
responseCode = result.first.responseCode.toDouble(),
|
|
319
|
+
debugMessage = result.first.debugMessage,
|
|
320
|
+
code = result.first.responseCode.toString(),
|
|
321
|
+
message = getBillingErrorMessage(result.first.responseCode),
|
|
322
|
+
purchaseToken = result.second
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
} else {
|
|
326
|
+
// Acknowledge the purchase
|
|
327
|
+
val acknowledgeParams = AcknowledgePurchaseParams.newBuilder()
|
|
328
|
+
.setPurchaseToken(purchaseToken)
|
|
329
|
+
.build()
|
|
330
|
+
|
|
331
|
+
val result = suspendCancellableCoroutine<BillingResult> { continuation ->
|
|
332
|
+
billingClient?.acknowledgePurchase(acknowledgeParams) { billingResult ->
|
|
333
|
+
continuation.resume(billingResult)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
Variant_Boolean_NitroPurchaseResult.Second(
|
|
338
|
+
NitroPurchaseResult(
|
|
339
|
+
responseCode = result.responseCode.toDouble(),
|
|
340
|
+
debugMessage = result.debugMessage,
|
|
341
|
+
code = result.responseCode.toString(),
|
|
342
|
+
message = getBillingErrorMessage(result.responseCode),
|
|
343
|
+
purchaseToken = purchaseToken
|
|
344
|
+
)
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
override val memorySize: Long
|
|
351
|
+
get() = 0L
|
|
352
|
+
|
|
353
|
+
// Event listener methods
|
|
354
|
+
override fun addPurchaseUpdatedListener(listener: (purchase: NitroPurchase) -> Unit) {
|
|
355
|
+
purchaseUpdatedListeners.add(listener)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
override fun addPurchaseErrorListener(listener: (error: NitroPurchaseResult) -> Unit) {
|
|
359
|
+
purchaseErrorListeners.add(listener)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
override fun removePurchaseUpdatedListener(listener: (purchase: NitroPurchase) -> Unit) {
|
|
363
|
+
// Note: Kotlin doesn't have easy closure comparison, so we'll clear all listeners
|
|
364
|
+
purchaseUpdatedListeners.clear()
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
override fun removePurchaseErrorListener(listener: (error: NitroPurchaseResult) -> Unit) {
|
|
368
|
+
// Note: Kotlin doesn't have easy closure comparison, so we'll clear all listeners
|
|
369
|
+
purchaseErrorListeners.clear()
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
override fun addPromotedProductListenerIOS(listener: (product: NitroProduct) -> Unit) {
|
|
373
|
+
// Promoted products are iOS-only, but we implement the interface for consistency
|
|
374
|
+
promotedProductListenersIOS.add(listener)
|
|
375
|
+
Log.w(TAG, "addPromotedProductListenerIOS called on Android - promoted products are iOS-only")
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
override fun removePromotedProductListenerIOS(listener: (product: NitroProduct) -> Unit) {
|
|
379
|
+
// Promoted products are iOS-only, but we implement the interface for consistency
|
|
380
|
+
promotedProductListenersIOS.clear()
|
|
381
|
+
Log.w(TAG, "removePromotedProductListenerIOS called on Android - promoted products are iOS-only")
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// BillingClientStateListener implementation
|
|
385
|
+
override fun onBillingSetupFinished(billingResult: BillingResult) {
|
|
386
|
+
// Handled inline in initConnection
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
override fun onBillingServiceDisconnected() {
|
|
390
|
+
// Try to restart the connection on the next request
|
|
391
|
+
// For now, just log the disconnection
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// PurchasesUpdatedListener implementation
|
|
395
|
+
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
|
|
396
|
+
Log.d(TAG, "onPurchasesUpdated: responseCode=${billingResult.responseCode}")
|
|
397
|
+
|
|
398
|
+
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
|
|
399
|
+
// Send successful purchases via events
|
|
400
|
+
for (purchase in purchases) {
|
|
401
|
+
sendPurchaseUpdate(convertToNitroPurchase(purchase))
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
// Send error via events
|
|
405
|
+
val errorCode = getBillingErrorCode(billingResult.responseCode)
|
|
406
|
+
val errorMessage = getBillingErrorMessage(billingResult.responseCode)
|
|
407
|
+
sendPurchaseError(createPurchaseErrorResult(
|
|
408
|
+
errorCode,
|
|
409
|
+
errorMessage,
|
|
410
|
+
null,
|
|
411
|
+
billingResult.responseCode,
|
|
412
|
+
billingResult.debugMessage
|
|
413
|
+
))
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Helper methods
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Send purchase update event to listeners
|
|
421
|
+
*/
|
|
422
|
+
private fun sendPurchaseUpdate(purchase: NitroPurchase) {
|
|
423
|
+
for (listener in purchaseUpdatedListeners) {
|
|
424
|
+
listener(purchase)
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Send purchase error event to listeners
|
|
430
|
+
*/
|
|
431
|
+
private fun sendPurchaseError(error: NitroPurchaseResult) {
|
|
432
|
+
for (listener in purchaseErrorListeners) {
|
|
433
|
+
listener(error)
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Create purchase error result with proper format
|
|
439
|
+
*/
|
|
440
|
+
private fun createPurchaseErrorResult(
|
|
441
|
+
errorCode: String,
|
|
442
|
+
message: String,
|
|
443
|
+
sku: String? = null,
|
|
444
|
+
responseCode: Int? = null,
|
|
445
|
+
debugMessage: String? = null
|
|
446
|
+
): NitroPurchaseResult {
|
|
447
|
+
return NitroPurchaseResult(
|
|
448
|
+
responseCode = responseCode?.toDouble() ?: -1.0,
|
|
449
|
+
debugMessage = debugMessage,
|
|
450
|
+
code = errorCode,
|
|
451
|
+
message = message,
|
|
452
|
+
purchaseToken = null
|
|
453
|
+
)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Convert billing response code to IAP error code
|
|
458
|
+
*/
|
|
459
|
+
private fun getBillingErrorCode(responseCode: Int): String {
|
|
460
|
+
return when (responseCode) {
|
|
461
|
+
BillingClient.BillingResponseCode.USER_CANCELED -> IapErrorCode.E_USER_CANCELLED
|
|
462
|
+
BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> IapErrorCode.E_SERVICE_ERROR
|
|
463
|
+
BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> IapErrorCode.E_NOT_PREPARED
|
|
464
|
+
BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> IapErrorCode.E_SKU_NOT_FOUND
|
|
465
|
+
BillingClient.BillingResponseCode.DEVELOPER_ERROR -> IapErrorCode.E_DEVELOPER_ERROR
|
|
466
|
+
BillingClient.BillingResponseCode.ERROR -> IapErrorCode.E_UNKNOWN
|
|
467
|
+
BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> IapErrorCode.E_ALREADY_OWNED
|
|
468
|
+
BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> IapErrorCode.E_ITEM_NOT_OWNED
|
|
469
|
+
BillingClient.BillingResponseCode.NETWORK_ERROR -> IapErrorCode.E_NETWORK_ERROR
|
|
470
|
+
else -> IapErrorCode.E_UNKNOWN
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
private suspend fun initBillingClient(): Boolean {
|
|
475
|
+
return suspendCancellableCoroutine { continuation ->
|
|
476
|
+
// For Google Play Billing v8.0.0+, use PendingPurchasesParams
|
|
477
|
+
val pendingPurchasesParams = PendingPurchasesParams.newBuilder()
|
|
478
|
+
.enableOneTimeProducts()
|
|
479
|
+
.build()
|
|
480
|
+
|
|
481
|
+
billingClient = BillingClient.newBuilder(context)
|
|
482
|
+
.setListener(this@HybridRnIap)
|
|
483
|
+
.enablePendingPurchases(pendingPurchasesParams)
|
|
484
|
+
.enableAutoServiceReconnection() // Automatically handle service disconnections
|
|
485
|
+
.build()
|
|
486
|
+
|
|
487
|
+
billingClient?.startConnection(object : BillingClientStateListener {
|
|
488
|
+
override fun onBillingSetupFinished(billingResult: BillingResult) {
|
|
489
|
+
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
|
490
|
+
continuation.resume(true)
|
|
491
|
+
} else {
|
|
492
|
+
val errorData = BillingUtils.getBillingErrorData(billingResult.responseCode)
|
|
493
|
+
val errorJson = BillingUtils.createErrorJson(
|
|
494
|
+
errorData.code,
|
|
495
|
+
errorData.message,
|
|
496
|
+
billingResult.responseCode,
|
|
497
|
+
billingResult.debugMessage
|
|
498
|
+
)
|
|
499
|
+
continuation.resumeWithException(Exception(errorJson))
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
override fun onBillingServiceDisconnected() {
|
|
504
|
+
Log.i(TAG, "Billing service disconnected")
|
|
505
|
+
// Will try to reconnect on next operation
|
|
506
|
+
}
|
|
507
|
+
})
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
private fun convertToNitroProduct(productDetails: ProductDetails, type: String): NitroProduct {
|
|
512
|
+
// Get price info from either one-time purchase or subscription
|
|
513
|
+
val (currency, displayPrice, priceAmountMicros) = when {
|
|
514
|
+
productDetails.oneTimePurchaseOfferDetails != null -> {
|
|
515
|
+
val offer = productDetails.oneTimePurchaseOfferDetails!!
|
|
516
|
+
Triple(
|
|
517
|
+
offer.priceCurrencyCode,
|
|
518
|
+
offer.formattedPrice,
|
|
519
|
+
offer.priceAmountMicros
|
|
520
|
+
)
|
|
521
|
+
}
|
|
522
|
+
productDetails.subscriptionOfferDetails?.isNotEmpty() == true -> {
|
|
523
|
+
val firstOffer = productDetails.subscriptionOfferDetails!![0]
|
|
524
|
+
val firstPhase = firstOffer.pricingPhases.pricingPhaseList[0]
|
|
525
|
+
Triple(
|
|
526
|
+
firstPhase.priceCurrencyCode,
|
|
527
|
+
firstPhase.formattedPrice,
|
|
528
|
+
firstPhase.priceAmountMicros
|
|
529
|
+
)
|
|
530
|
+
}
|
|
531
|
+
else -> Triple("", "N/A", 0L)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Convert subscription offer details to JSON string if available
|
|
535
|
+
val subscriptionOfferDetailsJson = productDetails.subscriptionOfferDetails?.let { offers ->
|
|
536
|
+
Log.d(TAG, "Product ${productDetails.productId} has ${offers.size} subscription offers")
|
|
537
|
+
|
|
538
|
+
val jsonArray = JSONArray().apply {
|
|
539
|
+
offers.forEach { offer ->
|
|
540
|
+
Log.d(TAG, "Offer: basePlanId=${offer.basePlanId}, offerId=${offer.offerId}, offerToken=${offer.offerToken}")
|
|
541
|
+
|
|
542
|
+
val offerJson = JSONObject().apply {
|
|
543
|
+
put("offerToken", offer.offerToken)
|
|
544
|
+
put("basePlanId", offer.basePlanId)
|
|
545
|
+
offer.offerId?.let { put("offerId", it) }
|
|
546
|
+
|
|
547
|
+
val pricingPhasesArray = JSONArray().apply {
|
|
548
|
+
offer.pricingPhases.pricingPhaseList.forEach { phase ->
|
|
549
|
+
put(JSONObject().apply {
|
|
550
|
+
put("formattedPrice", phase.formattedPrice)
|
|
551
|
+
put("priceCurrencyCode", phase.priceCurrencyCode)
|
|
552
|
+
put("priceAmountMicros", phase.priceAmountMicros)
|
|
553
|
+
put("billingCycleCount", phase.billingCycleCount)
|
|
554
|
+
put("billingPeriod", phase.billingPeriod)
|
|
555
|
+
put("recurrenceMode", phase.recurrenceMode)
|
|
556
|
+
})
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
put("pricingPhases", pricingPhasesArray)
|
|
560
|
+
}
|
|
561
|
+
put(offerJson)
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
val jsonString = jsonArray.toString()
|
|
566
|
+
Log.d(TAG, "Subscription offer details JSON: $jsonString")
|
|
567
|
+
jsonString
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
val nitroProduct = NitroProduct(
|
|
571
|
+
id = productDetails.productId,
|
|
572
|
+
title = productDetails.title,
|
|
573
|
+
description = productDetails.description,
|
|
574
|
+
type = type,
|
|
575
|
+
displayName = productDetails.name,
|
|
576
|
+
displayPrice = displayPrice,
|
|
577
|
+
currency = currency,
|
|
578
|
+
price = priceAmountMicros / 1000000.0,
|
|
579
|
+
platform = "android",
|
|
580
|
+
// iOS fields (null on Android)
|
|
581
|
+
isFamilyShareable = null,
|
|
582
|
+
jsonRepresentation = null,
|
|
583
|
+
subscriptionPeriodUnitIOS = null,
|
|
584
|
+
subscriptionPeriodNumberIOS = null,
|
|
585
|
+
introductoryPriceIOS = null,
|
|
586
|
+
introductoryPriceAsAmountIOS = null,
|
|
587
|
+
introductoryPricePaymentModeIOS = null,
|
|
588
|
+
introductoryPriceNumberOfPeriodsIOS = null,
|
|
589
|
+
introductoryPriceSubscriptionPeriodIOS = null,
|
|
590
|
+
// Android fields
|
|
591
|
+
originalPrice = productDetails.oneTimePurchaseOfferDetails?.formattedPrice,
|
|
592
|
+
originalPriceAmountMicros = productDetails.oneTimePurchaseOfferDetails?.priceAmountMicros?.toDouble(),
|
|
593
|
+
introductoryPriceValue = null, // TODO: Extract from subscription offers
|
|
594
|
+
introductoryPriceCycles = null,
|
|
595
|
+
introductoryPricePeriod = null,
|
|
596
|
+
subscriptionPeriod = null, // TODO: Extract from subscription offers
|
|
597
|
+
freeTrialPeriod = null,
|
|
598
|
+
subscriptionOfferDetailsAndroid = subscriptionOfferDetailsJson
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
Log.d(TAG, "Created NitroProduct for ${productDetails.productId}: has subscriptionOfferDetailsAndroid=${nitroProduct.subscriptionOfferDetailsAndroid != null}")
|
|
602
|
+
|
|
603
|
+
return nitroProduct
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
private fun convertToNitroPurchase(purchase: Purchase): NitroPurchase {
|
|
607
|
+
return NitroPurchase(
|
|
608
|
+
id = purchase.orderId ?: "",
|
|
609
|
+
productId = purchase.products.firstOrNull() ?: "",
|
|
610
|
+
transactionDate = purchase.purchaseTime.toDouble(),
|
|
611
|
+
purchaseToken = purchase.purchaseToken,
|
|
612
|
+
platform = "android",
|
|
613
|
+
// iOS fields
|
|
614
|
+
quantityIOS = null,
|
|
615
|
+
originalTransactionDateIOS = null,
|
|
616
|
+
originalTransactionIdentifierIOS = null,
|
|
617
|
+
appAccountToken = null,
|
|
618
|
+
// Android fields
|
|
619
|
+
purchaseTokenAndroid = purchase.purchaseToken,
|
|
620
|
+
dataAndroid = purchase.originalJson,
|
|
621
|
+
signatureAndroid = purchase.signature,
|
|
622
|
+
autoRenewingAndroid = purchase.isAutoRenewing,
|
|
623
|
+
purchaseStateAndroid = purchase.purchaseState.toDouble(),
|
|
624
|
+
isAcknowledgedAndroid = purchase.isAcknowledged,
|
|
625
|
+
packageNameAndroid = purchase.packageName,
|
|
626
|
+
obfuscatedAccountIdAndroid = purchase.accountIdentifiers?.obfuscatedAccountId,
|
|
627
|
+
obfuscatedProfileIdAndroid = purchase.accountIdentifiers?.obfuscatedProfileId
|
|
628
|
+
)
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// Helper function for billing error messages
|
|
632
|
+
private fun getBillingErrorMessage(responseCode: Int): String {
|
|
633
|
+
val errorData = BillingUtils.getBillingErrorData(responseCode)
|
|
634
|
+
return errorData.message
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// iOS-specific method - not supported on Android
|
|
638
|
+
override fun getStorefrontIOS(): Promise<String> {
|
|
639
|
+
return Promise.async {
|
|
640
|
+
val errorJson = BillingUtils.createErrorJson(
|
|
641
|
+
IapErrorCode.E_UNKNOWN,
|
|
642
|
+
"getStorefrontIOS is only available on iOS"
|
|
643
|
+
)
|
|
644
|
+
throw Exception(errorJson)
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// iOS-specific method - not supported on Android
|
|
649
|
+
override fun getAppTransactionIOS(): Promise<String?> {
|
|
650
|
+
return Promise.async {
|
|
651
|
+
val errorJson = BillingUtils.createErrorJson(
|
|
652
|
+
IapErrorCode.E_UNKNOWN,
|
|
653
|
+
"getAppTransactionIOS is only available on iOS"
|
|
654
|
+
)
|
|
655
|
+
throw Exception(errorJson)
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// iOS-specific method - not supported on Android
|
|
660
|
+
override fun requestPromotedProductIOS(): Promise<NitroProduct?> {
|
|
661
|
+
return Promise.async {
|
|
662
|
+
// Android doesn't have promoted products like iOS App Store
|
|
663
|
+
// Return null as this feature is iOS-only
|
|
664
|
+
null
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
override fun buyPromotedProductIOS(): Promise<Unit> {
|
|
669
|
+
return Promise.async {
|
|
670
|
+
// Android doesn't have promoted products like iOS App Store
|
|
671
|
+
// This is an iOS-only feature, so we do nothing on Android
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
override fun presentCodeRedemptionSheetIOS(): Promise<Boolean> {
|
|
676
|
+
return Promise.async {
|
|
677
|
+
// Android doesn't have a code redemption sheet like iOS App Store
|
|
678
|
+
// This is an iOS-only feature, so we return false on Android
|
|
679
|
+
false
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
override fun clearTransactionIOS(): Promise<Unit> {
|
|
684
|
+
return Promise.async {
|
|
685
|
+
// This is an iOS-only feature for clearing unfinished transactions
|
|
686
|
+
// On Android, we don't need to do anything
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
override fun beginRefundRequestIOS(sku: String): Promise<String?> {
|
|
691
|
+
return Promise.async {
|
|
692
|
+
// Android doesn't have in-app refund requests like iOS
|
|
693
|
+
// Refunds on Android are handled through Google Play Console
|
|
694
|
+
null
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Receipt validation
|
|
699
|
+
override fun validateReceipt(params: NitroReceiptValidationParams): Promise<Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid> {
|
|
700
|
+
return Promise.async {
|
|
701
|
+
try {
|
|
702
|
+
// For Android, we need the androidOptions to be provided
|
|
703
|
+
val androidOptions = params.androidOptions
|
|
704
|
+
?: throw Exception(BillingUtils.createErrorJson(
|
|
705
|
+
IapErrorCode.E_DEVELOPER_ERROR,
|
|
706
|
+
"Android receipt validation requires androidOptions parameter"
|
|
707
|
+
))
|
|
708
|
+
|
|
709
|
+
// Android receipt validation would typically involve server-side validation
|
|
710
|
+
// using Google Play Developer API. Here we provide a simplified implementation
|
|
711
|
+
// that demonstrates the expected structure.
|
|
712
|
+
|
|
713
|
+
// In a real implementation, you would make an HTTP request to Google Play API
|
|
714
|
+
// using the androidOptions.accessToken, androidOptions.packageName, etc.
|
|
715
|
+
|
|
716
|
+
// For now, we'll return a mock successful validation result
|
|
717
|
+
// This should be replaced with actual Google Play Developer API calls
|
|
718
|
+
val currentTime = System.currentTimeMillis()
|
|
719
|
+
|
|
720
|
+
val result = NitroReceiptValidationResultAndroid(
|
|
721
|
+
autoRenewing = androidOptions.isSub ?: false,
|
|
722
|
+
betaProduct = false,
|
|
723
|
+
cancelDate = null,
|
|
724
|
+
cancelReason = "",
|
|
725
|
+
deferredDate = null,
|
|
726
|
+
deferredSku = null,
|
|
727
|
+
freeTrialEndDate = 0.0,
|
|
728
|
+
gracePeriodEndDate = 0.0,
|
|
729
|
+
parentProductId = params.sku,
|
|
730
|
+
productId = params.sku,
|
|
731
|
+
productType = if (androidOptions.isSub == true) "subs" else "inapp",
|
|
732
|
+
purchaseDate = currentTime.toDouble(),
|
|
733
|
+
quantity = 1.0,
|
|
734
|
+
receiptId = androidOptions.productToken,
|
|
735
|
+
renewalDate = if (androidOptions.isSub == true) (currentTime + (30L * 24 * 60 * 60 * 1000)).toDouble() else 0.0, // 30 days from now if subscription
|
|
736
|
+
term = if (androidOptions.isSub == true) "P1M" else "", // P1M = 1 month
|
|
737
|
+
termSku = params.sku,
|
|
738
|
+
testTransaction = false
|
|
739
|
+
)
|
|
740
|
+
|
|
741
|
+
Variant_NitroReceiptValidationResultIOS_NitroReceiptValidationResultAndroid.Second(result)
|
|
742
|
+
|
|
743
|
+
} catch (e: Exception) {
|
|
744
|
+
val errorJson = BillingUtils.createErrorJson(
|
|
745
|
+
IapErrorCode.E_RECEIPT_FAILED,
|
|
746
|
+
"Receipt validation failed: ${e.message}"
|
|
747
|
+
)
|
|
748
|
+
throw Exception(errorJson)
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// iOS-specific methods - Not applicable on Android, return appropriate defaults
|
|
754
|
+
override fun subscriptionStatusIOS(sku: String): Promise<Array<NitroSubscriptionStatus>?> {
|
|
755
|
+
return Promise.async {
|
|
756
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
757
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
758
|
+
"subscriptionStatusIOS is only available on iOS platform"
|
|
759
|
+
))
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
override fun currentEntitlementIOS(sku: String): Promise<NitroPurchase?> {
|
|
764
|
+
return Promise.async {
|
|
765
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
766
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
767
|
+
"currentEntitlementIOS is only available on iOS platform"
|
|
768
|
+
))
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
override fun latestTransactionIOS(sku: String): Promise<NitroPurchase?> {
|
|
773
|
+
return Promise.async {
|
|
774
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
775
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
776
|
+
"latestTransactionIOS is only available on iOS platform"
|
|
777
|
+
))
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
override fun getPendingTransactionsIOS(): Promise<Array<NitroPurchase>> {
|
|
782
|
+
return Promise.async {
|
|
783
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
784
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
785
|
+
"getPendingTransactionsIOS is only available on iOS platform"
|
|
786
|
+
))
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
override fun syncIOS(): Promise<Boolean> {
|
|
791
|
+
return Promise.async {
|
|
792
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
793
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
794
|
+
"syncIOS is only available on iOS platform"
|
|
795
|
+
))
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
override fun showManageSubscriptionsIOS(): Promise<Boolean> {
|
|
800
|
+
return Promise.async {
|
|
801
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
802
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
803
|
+
"showManageSubscriptionsIOS is only available on iOS platform"
|
|
804
|
+
))
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
override fun isEligibleForIntroOfferIOS(groupID: String): Promise<Boolean> {
|
|
809
|
+
return Promise.async {
|
|
810
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
811
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
812
|
+
"isEligibleForIntroOfferIOS is only available on iOS platform"
|
|
813
|
+
))
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
override fun getReceiptDataIOS(): Promise<String> {
|
|
818
|
+
return Promise.async {
|
|
819
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
820
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
821
|
+
"getReceiptDataIOS is only available on iOS platform"
|
|
822
|
+
))
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
override fun isTransactionVerifiedIOS(sku: String): Promise<Boolean> {
|
|
827
|
+
return Promise.async {
|
|
828
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
829
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
830
|
+
"isTransactionVerifiedIOS is only available on iOS platform"
|
|
831
|
+
))
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
override fun getTransactionJwsIOS(sku: String): Promise<String?> {
|
|
836
|
+
return Promise.async {
|
|
837
|
+
throw Exception(BillingUtils.createErrorJson(
|
|
838
|
+
IapErrorCode.E_FEATURE_NOT_SUPPORTED,
|
|
839
|
+
"getTransactionJwsIOS is only available on iOS platform"
|
|
840
|
+
))
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|