From e1725190be64a4f7dff99241be37ba8f033049f3 Mon Sep 17 00:00:00 2001 From: N3TC4T Date: Fri, 1 Nov 2024 19:25:40 +0100 Subject: [PATCH] fix: better IAP error messages --- .../java/libs/common/InAppPurchaseModule.java | 25 +++++----- .../InAppPurchase+TransactionObserver.m | 47 +++++++++++++++---- src/common/libs/iap.ts | 1 + src/locale/en.json | 3 +- src/locale/translations/af.json | 3 +- src/locale/translations/ar.json | 3 +- src/locale/translations/bg.json | 3 +- src/locale/translations/bn-BD.json | 3 +- src/locale/translations/ca.json | 3 +- src/locale/translations/cs.json | 3 +- src/locale/translations/da.json | 3 +- src/locale/translations/de.json | 3 +- src/locale/translations/el.json | 3 +- src/locale/translations/en-AU.json | 3 +- src/locale/translations/es-419.json | 3 +- src/locale/translations/es.json | 3 +- src/locale/translations/et.json | 3 +- src/locale/translations/eu.json | 3 +- src/locale/translations/fi.json | 3 +- src/locale/translations/fil.json | 3 +- src/locale/translations/fr.json | 3 +- src/locale/translations/gl-ES.json | 3 +- src/locale/translations/gu.json | 3 +- src/locale/translations/he.json | 3 +- src/locale/translations/hi-IN.json | 3 +- src/locale/translations/hr.json | 3 +- src/locale/translations/ht.json | 3 +- src/locale/translations/hu.json | 3 +- src/locale/translations/id.json | 3 +- src/locale/translations/it.json | 3 +- src/locale/translations/ja.json | 3 +- src/locale/translations/ka.json | 3 +- src/locale/translations/kk.json | 3 +- src/locale/translations/kn.json | 3 +- src/locale/translations/ko.json | 3 +- src/locale/translations/lt.json | 3 +- src/locale/translations/lv.json | 3 +- src/locale/translations/ml.json | 3 +- src/locale/translations/mr.json | 3 +- src/locale/translations/nl.json | 3 +- src/locale/translations/no-NO.json | 3 +- src/locale/translations/pa.json | 3 +- src/locale/translations/pl.json | 3 +- src/locale/translations/pt-BR.json | 3 +- src/locale/translations/pt.json | 3 +- src/locale/translations/ro.json | 3 +- src/locale/translations/ru.json | 3 +- src/locale/translations/sd.json | 3 +- src/locale/translations/sk.json | 3 +- src/locale/translations/sl.json | 3 +- src/locale/translations/sr.json | 3 +- src/locale/translations/sv.json | 3 +- src/locale/translations/sw.json | 3 +- src/locale/translations/ta-IN.json | 3 +- src/locale/translations/te-IN.json | 3 +- src/locale/translations/tr.json | 3 +- src/locale/translations/uk.json | 3 +- src/locale/translations/ur.json | 3 +- src/locale/translations/uz.json | 3 +- src/locale/translations/vi.json | 3 +- src/locale/translations/zh-TW.json | 3 +- src/locale/translations/zh.json | 3 +- .../PurchaseProductOverlay.tsx | 17 +++++-- 63 files changed, 184 insertions(+), 83 deletions(-) diff --git a/android/app/src/main/java/libs/common/InAppPurchaseModule.java b/android/app/src/main/java/libs/common/InAppPurchaseModule.java index c244d9a60..7d9f657ad 100644 --- a/android/app/src/main/java/libs/common/InAppPurchaseModule.java +++ b/android/app/src/main/java/libs/common/InAppPurchaseModule.java @@ -128,7 +128,7 @@ public void onBillingSetupFinished(@NonNull BillingResult billingResult) { @Override public void onBillingServiceDisconnected() { - promise.reject(E_CLIENT_IS_NOT_READY, "billing client service disconnected"); + promise.reject(E_CLIENT_IS_NOT_READY, "Billing client service disconnected!"); } }); } @@ -136,7 +136,7 @@ public void onBillingServiceDisconnected() { @ReactMethod public void getProductDetails(String productId, Promise promise) { if (!isReady()) { - promise.reject(E_CLIENT_IS_NOT_READY, "billing client is not ready, forgot to initialize?"); + promise.reject(E_CLIENT_IS_NOT_READY, "Billing client is not ready, forgot to initialize?"); return; } @@ -176,7 +176,7 @@ public void getProductDetails(String productId, Promise promise) { @ReactMethod public void restorePurchases(Promise promise) { if (!isReady()) { - promise.reject(E_CLIENT_IS_NOT_READY, "billing client is not ready, forgot to initialize?"); + promise.reject(E_CLIENT_IS_NOT_READY, "Billing client is not ready, forgot to initialize?"); return; } @@ -203,7 +203,7 @@ public void restorePurchases(Promise promise) { @ReactMethod public void purchase(String productId, Promise promise) { if (!isReady()) { - promise.reject(E_CLIENT_IS_NOT_READY, "billingClient is not ready, forgot to initialize?"); + promise.reject(E_CLIENT_IS_NOT_READY, "Billing client is not ready, forgot to initialize?"); return; } @@ -213,7 +213,7 @@ public void purchase(String productId, Promise promise) { return; } - promise.reject(E_PRODUCT_DETAILS_NOT_FOUND, "product details with id " + productId + " not found, make sure to run the getProductDetails method before purchase!"); + promise.reject(E_PRODUCT_DETAILS_NOT_FOUND, "Product is unavailable!"); } @@ -230,7 +230,7 @@ public void finalizePurchase(String purchaseToken, Promise promise) { if (billing.getResponseCode() == BillingClient.BillingResponseCode.OK) { promise.resolve(purchaseToken); } else { - promise.reject(E_FINISH_TRANSACTION_FAILED, "billing response code " + billing.getResponseCode()); + promise.reject(E_FINISH_TRANSACTION_FAILED, "Finalize purchase failed: code " + billing.getResponseCode()); } }); } @@ -252,12 +252,13 @@ public void onPurchasesUpdated(@NonNull BillingResult billing, @Nullable List *)transactions { + updatedTransactions: (nonnull NSArray *)transactions { NSMutableArray *result=[self transactionsToResult:transactions]; if([result count] > 0){ [self callCompletionHandlerWithResult:result]; @@ -42,20 +42,20 @@ - (void)callCompletionHandlerWithResult: (NSMutableArray *)result { - (NSMutableArray *)transactionsToResult: (nonnull NSArray *)transactions { NSMutableArray *result = [NSMutableArray arrayWithCapacity: [transactions count]]; - + [transactions enumerateObjectsUsingBlock: ^(SKPaymentTransaction *obj, NSUInteger idx, BOOL *stop) { NSMutableDictionary *paymentDictionary = [[NSMutableDictionary alloc] init]; - + NSString *productIdentifier = obj.payment.productIdentifier; NSString *transactionIdentifier = obj.transactionIdentifier; NSString *applicationUsername = obj.payment.applicationUsername; NSNumber *quantity = [NSNumber numberWithInteger:obj.payment.quantity]; - + [paymentDictionary setValue:productIdentifier forKey:@"productIdentifier"]; [paymentDictionary setValue:transactionIdentifier forKey:@"transactionIdentifier"]; [paymentDictionary setValue:applicationUsername forKey:@"applicationUsername"]; [paymentDictionary setValue:quantity forKey:@"quantity"]; - + switch(obj.transactionState){ // SUCCESS case SKPaymentTransactionStatePurchased: @@ -67,20 +67,49 @@ - (NSMutableArray *)transactionsToResult: (nonnull NSArray { const receipts = await InAppPurchase.purchase(productId); if (Array.isArray(receipts) && receipts.length > 0) { - // start the verifying process - await this.verifyPurchase(receipts[0]); + const receipt = receipts[0]; + + if ('error' in receipt) { + // something happened :\ + throw new Error(receipt.error); + } else { + // start the verifying process if transaction was successful + await this.verifyPurchase(receipt); + } } - } catch (error) { + } catch (error: any) { LoggerService.recordError('lunchPurchaseFlow: ', error); + Alert.alert( + Localize.t('monetization.purchaseFailed'), + error.message || Localize.t('global.somethingWentWrong'), + ); } finally { this.setState({ isPurchasing: false,