Skip to content

Commit

Permalink
fix: better IAP error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
N3TC4T committed Nov 1, 2024
1 parent eeb4fa3 commit e172519
Show file tree
Hide file tree
Showing 63 changed files with 184 additions and 83 deletions.
25 changes: 13 additions & 12 deletions android/app/src/main/java/libs/common/InAppPurchaseModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,15 @@ 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!");
}
});
}

@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;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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!");
}


Expand All @@ -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());
}
});
}
Expand All @@ -252,12 +252,13 @@ public void onPurchasesUpdated(@NonNull BillingResult billing, @Nullable List<Pu
if (billing.getResponseCode() != BillingClient.BillingResponseCode.OK) {
switch (billing.getResponseCode()) {
case BillingClient.BillingResponseCode.USER_CANCELED:
rejectBillingFlowPromise(E_PURCHASE_CANCELED, "purchase canceled by users");
rejectBillingFlowPromise(E_PURCHASE_CANCELED, "The purchase was canceled by the user.");
break;
case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
rejectBillingFlowPromise(E_ALREADY_PURCHASED, "item already owned by users");
rejectBillingFlowPromise(E_ALREADY_PURCHASED, "The item is already owned.");
break;
default:
rejectBillingFlowPromise(E_PURCHASE_FAILED, "billing response code " + billing.getResponseCode());
rejectBillingFlowPromise(E_PURCHASE_FAILED, "An unexpected error occurred, code: " + billing.getResponseCode());
break;
}
return;
Expand All @@ -266,7 +267,7 @@ public void onPurchasesUpdated(@NonNull BillingResult billing, @Nullable List<Pu

// something is not right?
if (list == null || list.isEmpty()) {
rejectBillingFlowPromise(E_PURCHASE_FAILED, "the purchase list is empty!");
rejectBillingFlowPromise(E_PURCHASE_FAILED, "The purchase list is empty!");
return;
}

Expand Down Expand Up @@ -294,14 +295,14 @@ public boolean isReady() {
private void launchBillingFlow(ProductDetails productDetails, Promise promise) {
// set flag
if (isUserPurchasing.getAndSet(true)) {
promise.reject(E_PURCHASE_FAILED, "There is a Billing flow going on at the moment, can't start the new one!");
promise.reject(E_PURCHASE_FAILED, "There is a Billing flow going on at the moment, can't start a new one!");
return;
}

// if we already have an promise going on for billing flow, reject it as we don't want to start
// the new flow without closing the old one
if (billingFlowPromise != null) {
promise.reject(E_PURCHASE_FAILED, "There is a Billing flow going on at the moment, can't start the new one!");
promise.reject(E_PURCHASE_FAILED, "There is a Billing flow going on at the moment, can't start a new one!");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedW
}

- (void)paymentQueue: (nonnull SKPaymentQueue *)queue
updatedTransactions: (nonnull NSArray<SKPaymentTransaction *> *)transactions {
updatedTransactions: (nonnull NSArray<SKPaymentTransaction *> *)transactions {
NSMutableArray *result=[self transactionsToResult:transactions];
if([result count] > 0){
[self callCompletionHandlerWithResult:result];
Expand All @@ -42,20 +42,20 @@ - (void)callCompletionHandlerWithResult: (NSMutableArray *)result {

- (NSMutableArray *)transactionsToResult: (nonnull NSArray<SKPaymentTransaction *> *)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:
Expand All @@ -67,20 +67,49 @@ - (NSMutableArray *)transactionsToResult: (nonnull NSArray<SKPaymentTransaction
}
// FAILED
case SKPaymentTransactionStateFailed:
[paymentDictionary setValue:[NSNumber numberWithInteger:obj.error.code] forKey:@"error"];
{
NSString *humanErrorMessage = [self normalizeStoreKitError:obj.error];
[paymentDictionary setValue:humanErrorMessage forKey:@"error"];
// just finish the transaction, otherwise it will not being cleared.
[[SKPaymentQueue defaultQueue] finishTransaction:obj];
break;
}
// NO ACTION IS NEEDED
case SKPaymentTransactionStatePurchasing:
case SKPaymentTransactionStateDeferred:
return;
}

[result addObject: paymentDictionary];
}];


return result;
}


-(NSString*)normalizeStoreKitError:(NSError *)error {
switch (error.code) {
case SKErrorUnknown:
return @"Unknown error occurred. Please try again.";
case SKErrorClientInvalid:
return @"In-app purchases are not allowed on this device.";
case SKErrorPaymentCancelled:
return @"You have cancelled the transaction.";
case SKErrorPaymentInvalid:
return @"The purchase identifier is invalid.";
case SKErrorPaymentNotAllowed:
return @"You are not authorized to make purchases.";
case SKErrorStoreProductNotAvailable:
return @"The requested product is not available in the store.";
case SKErrorCloudServicePermissionDenied:
return @"Access to cloud service information is not allowed.";
case SKErrorCloudServiceNetworkConnectionFailed:
return @"Could not connect to the network.";
case SKErrorCloudServiceRevoked:
return @"Cloud service revoked.";
default:
return error.localizedDescription;
}
}
@end
1 change: 1 addition & 0 deletions src/common/libs/iap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface GooglePlayPurchase {
}

interface AppStorePayment {
error?: string;
transactionIdentifier: string;
productIdentifier: string;
quantity: number;
Expand Down
3 changes: 2 additions & 1 deletion src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService":"Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/af.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/bn-BD.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/en-AU.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/es-419.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
3 changes: 2 additions & 1 deletion src/locale/translations/et.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@
"noPurchaseFound": "No Purchases Found",
"noPreviousPurchases": "We couldn't find any previous purchases to restore. If you believe this is an error, please contact our support team.",
"errorRestorePurchase": "An unexpected error occurred while checking your purchase history.\n\nPlease try again later or contact our support team if the issue persists.",
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists."
"couldNotFetchProductDetails": "Error fetching product details. Please try again later or contact support if the issue persists.",
"purchaseFailed": "Purchase failed!"
},
"errors": {
"unableToLoadTermOfService": "Oops! Unable to Retrieve Terms of Service",
Expand Down
Loading

0 comments on commit e172519

Please sign in to comment.