From 6bf387bb2a831f8e097547ca0fe025702d86bfa9 Mon Sep 17 00:00:00 2001 From: Akshet Pandey Date: Wed, 27 Sep 2017 09:12:07 -0700 Subject: [PATCH 01/16] Allow products to be fetched even if purchases are restricted (#123) Restricting IAPs doesn't prevent us from fetching product information. A better way to handle this is to check canMakePayments method and show appropriate message on the payment screen. Update README to include canMakePayments Also add note about calling canMakePayments before purchaseProduct to show a better error message to users. --- InAppUtils/InAppUtils.m | 14 +++++--------- Readme.md | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/InAppUtils/InAppUtils.m b/InAppUtils/InAppUtils.m index d726603..f382e75 100644 --- a/InAppUtils/InAppUtils.m +++ b/InAppUtils/InAppUtils.m @@ -191,15 +191,11 @@ - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue RCT_EXPORT_METHOD(loadProducts:(NSArray *)productIdentifiers callback:(RCTResponseSenderBlock)callback) { - if([SKPaymentQueue canMakePayments]){ - SKProductsRequest *productsRequest = [[SKProductsRequest alloc] - initWithProductIdentifiers:[NSSet setWithArray:productIdentifiers]]; - productsRequest.delegate = self; - _callbacks[RCTKeyForInstance(productsRequest)] = callback; - [productsRequest start]; - } else { - callback(@[@"not_available"]); - } + SKProductsRequest *productsRequest = [[SKProductsRequest alloc] + initWithProductIdentifiers:[NSSet setWithArray:productIdentifiers]]; + productsRequest.delegate = self; + _callbacks[RCTKeyForInstance(productsRequest)] = callback; + [productsRequest start]; } RCT_EXPORT_METHOD(canMakePayments: (RCTResponseSenderBlock)callback) diff --git a/Readme.md b/Readme.md index 359cba3..46b5757 100644 --- a/Readme.md +++ b/Readme.md @@ -61,6 +61,18 @@ InAppUtils.loadProducts(products, (error, products) => { **Troubleshooting:** If you do not get back your product(s) then there's a good chance that something in your iTunes Connect or Xcode is not properly configured. Take a look at this [StackOverflow Answer](http://stackoverflow.com/a/11707704/293280) to determine what might be the issue(s). +### Checking if payments are allowed + +```javascript +InAppUtils.canMakePayments((canMakePayments) => { + if(!canMakePayments) { + Alert.alert('Not Allowed', 'This device is not allowed to make purchases. Please check restrictions on device'); + } +}) +``` + +**NOTE:** canMakePayments may return false because of country limitation or parental contol/restriction setup on the device. + ### Buy product ```javascript @@ -76,6 +88,8 @@ InAppUtils.purchaseProduct(productIdentifier, (error, response) => { **NOTE:** Call `loadProducts` prior to calling `purchaseProduct`, otherwise this will return `invalid_product`. If you're calling them right after each other, you will need to call `purchaseProduct` inside of the `loadProducts` callback to ensure it has had a chance to complete its call. +**NOTE:** Call `canMakePurchases` prior to calling `purchaseProduct` to ensure that the user is allowed to make a purchase. It is generally a good idea to inform the user that they are not allowed to make purchases from their account and what they can do about it instead of a cryptic error message from iTunes. + **NOTE:** `purchaseProductForUser(productIdentifier, username, callback)` is also available. https://stackoverflow.com/questions/29255568/is-there-any-way-to-know-purchase-made-by-which-itunes-account-ios/29280858#29280858 From 8cf764dbd9670f39fed383fddb6fa45ff5576df5 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Wed, 27 Sep 2017 12:12:38 -0400 Subject: [PATCH 02/16] 6.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9e0f046..d128aed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-in-app-utils", - "version": "5.6.0", + "version": "6.0.0", "description": "A react-native wrapper for handling in-app payments.", "author": { "name": "Chirag Jain", From 2845d194f906d4c60dd8393e941141c45689aa72 Mon Sep 17 00:00:00 2001 From: Andrew Shini Date: Thu, 30 Nov 2017 10:35:52 +1000 Subject: [PATCH 03/16] Include original transaction data if available (#142) --- InAppUtils/InAppUtils.m | 37 +++++++++++++++++++------------------ Readme.md | 3 +++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/InAppUtils/InAppUtils.m b/InAppUtils/InAppUtils.m index f382e75..cb55fda 100644 --- a/InAppUtils/InAppUtils.m +++ b/InAppUtils/InAppUtils.m @@ -47,12 +47,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue NSString *key = RCTKeyForInstance(transaction.payment.productIdentifier); RCTResponseSenderBlock callback = _callbacks[key]; if (callback) { - NSDictionary *purchase = @{ - @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), - @"transactionIdentifier": transaction.transactionIdentifier, - @"productIdentifier": transaction.payment.productIdentifier, - @"transactionReceipt": [[transaction transactionReceipt] base64EncodedStringWithOptions:0] - }; + NSDictionary *purchase = [self getPurchaseData:transaction]; callback(@[[NSNull null], purchase]); [_callbacks removeObjectForKey:key]; } else { @@ -145,18 +140,7 @@ - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue for(SKPaymentTransaction *transaction in queue.transactions){ if(transaction.transactionState == SKPaymentTransactionStateRestored) { - NSMutableDictionary *purchase = [NSMutableDictionary dictionaryWithDictionary: @{ - @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), - @"transactionIdentifier": transaction.transactionIdentifier, - @"productIdentifier": transaction.payment.productIdentifier, - @"transactionReceipt": [[transaction transactionReceipt] base64EncodedStringWithOptions:0] - }]; - - SKPaymentTransaction *originalTransaction = transaction.originalTransaction; - if (originalTransaction) { - purchase[@"originalTransactionDate"] = @(originalTransaction.transactionDate.timeIntervalSince1970 * 1000); - purchase[@"originalTransactionIdentifier"] = originalTransaction.transactionIdentifier; - } + NSDictionary *purchase = [self getPurchaseData:transaction]; [productsArrayForJS addObject:purchase]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; @@ -255,6 +239,23 @@ - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ } } +- (NSDictionary *)getPurchaseData:(SKPaymentTransaction *)transaction { + NSMutableDictionary *purchase = [NSMutableDictionary dictionaryWithDictionary: @{ + @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), + @"transactionIdentifier": transaction.transactionIdentifier, + @"productIdentifier": transaction.payment.productIdentifier, + @"transactionReceipt": [[transaction transactionReceipt] base64EncodedStringWithOptions:0] + }]; + // originalTransaction is available for restore purchase and purchase of cancelled/expired subscriptions + SKPaymentTransaction *originalTransaction = transaction.originalTransaction; + if (originalTransaction) { + purchase[@"originalTransactionDate"] = @(originalTransaction.transactionDate.timeIntervalSince1970 * 1000); + purchase[@"originalTransactionIdentifier"] = originalTransaction.transactionIdentifier; + } + + return purchase; +} + - (void)dealloc { [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; diff --git a/Readme.md b/Readme.md index 46b5757..fe8d042 100644 --- a/Readme.md +++ b/Readme.md @@ -97,11 +97,14 @@ https://stackoverflow.com/questions/29255568/is-there-any-way-to-know-purchase-m | Field | Type | Description | | --------------------- | ------ | -------------------------------------------------- | +| originalTransactionDate | number | The original transaction date (ms since epoch) | +| originalTransactionIdentifier | string | The original transaction identifier | | transactionDate | number | The transaction date (ms since epoch) | | transactionIdentifier | string | The transaction identifier | | productIdentifier | string | The product identifier | | transactionReceipt | string | The transaction receipt as a base64 encoded string | +**NOTE:** `originalTransactionDate` and `originalTransactionIdentifier` are only available for subscriptions that were previously cancelled or expired. ### Restore payments From 8ed80248ac905fb3949dbb94c2a18e874d86838d Mon Sep 17 00:00:00 2001 From: Cai Leao Date: Wed, 10 Jan 2018 13:02:19 +0000 Subject: [PATCH 04/16] Update Readme.md (#154) Changed the installation steps to use `react-native install` rather than the old `rnpm` --- Readme.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index fe8d042..61c53ec 100644 --- a/Readme.md +++ b/Readme.md @@ -17,11 +17,9 @@ A react-native wrapper for handling in-app purchases. ### Add it to your project -1. Make sure you have `rnpm` installed: `npm install rnpm -g` +1.Install with react-native cli `react-native install react-native-in-app-utils` -2. Install with rnpm: `rnpm install react-native-in-app-utils` - -3. Whenever you want to use it within React code now you just have to do: `var InAppUtils = require('NativeModules').InAppUtils;` +2. Whenever you want to use it within React code now you just have to do: `var InAppUtils = require('NativeModules').InAppUtils;` or for ES6: ``` From 0d0a0f1aadcb514fd4a8e74b4b26642b2cf6a290 Mon Sep 17 00:00:00 2001 From: Steve Hanson Date: Mon, 12 Mar 2018 11:18:23 -0500 Subject: [PATCH 05/16] Update breaking change message in readme (#163) Fixes #162 --- Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 61c53ec..43d6499 100644 --- a/Readme.md +++ b/Readme.md @@ -4,8 +4,7 @@ A react-native wrapper for handling in-app purchases. # Breaking Change -- Due to a major breaking change in RN 0.40+, Use v5.x of this lib when installing from npm. - +- Due to a major breaking change in RN 0.40+, use version 5 or higher of this lib when installing from npm. # Notes From d64ab45c4f45b22d01bd6169ea068c5843acb5f2 Mon Sep 17 00:00:00 2001 From: Phil Wilks Date: Tue, 10 Jul 2018 17:36:12 +0100 Subject: [PATCH 06/16] Improved variable naming in Readme.md (#184) * Improved variable naming in Readme.md Also added a console.log line just to help people know what should be happening * Might as well make it const not var --- Readme.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 43d6499..6f2b98d 100644 --- a/Readme.md +++ b/Readme.md @@ -34,10 +34,11 @@ const { InAppUtils } = NativeModules You have to load the products first to get the correctly internationalized name and price in the correct currency. ```javascript -var products = [ +const identifiers = [ 'com.xyz.abc', ]; -InAppUtils.loadProducts(products, (error, products) => { +InAppUtils.loadProducts(identifiers, (error, products) => { + console.log(products); //update store here. }); ``` From dba6b218f62fad3dab7c4e081d1a3f3c7245e1e8 Mon Sep 17 00:00:00 2001 From: Phil Wilks Date: Wed, 11 Jul 2018 09:44:34 +0100 Subject: [PATCH 07/16] Readme formatting tweaks --- Readme.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Readme.md b/Readme.md index 6f2b98d..79ba175 100644 --- a/Readme.md +++ b/Readme.md @@ -1,12 +1,12 @@ # `react-native-in-app-utils` -A react-native wrapper for handling in-app purchases. +A react-native wrapper for handling in-app purchases in iOS. -# Breaking Change +## Breaking Change - Due to a major breaking change in RN 0.40+, use version 5 or higher of this lib when installing from npm. -# Notes +## Notes - You need an Apple Developer account to use in-app purchases. @@ -14,9 +14,9 @@ A react-native wrapper for handling in-app purchases. - You have to test your in-app purchases on a real device, in-app purchases will always fail on the Simulator. -### Add it to your project +## Installation -1.Install with react-native cli `react-native install react-native-in-app-utils` +1. Install with react-native cli `react-native install react-native-in-app-utils` 2. Whenever you want to use it within React code now you just have to do: `var InAppUtils = require('NativeModules').InAppUtils;` or for ES6: From 166499ef85a22dcbfcb95dadef1a9d4a87d7f8b0 Mon Sep 17 00:00:00 2001 From: Kesha Antonov Date: Sun, 29 Jul 2018 15:35:02 +0300 Subject: [PATCH 08/16] RN 0.50+ compat: main queue (#175) * main queue * requiresMainQueueSetup: set to NO --- InAppUtils/InAppUtils.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/InAppUtils/InAppUtils.m b/InAppUtils/InAppUtils.m index cb55fda..d5737d4 100644 --- a/InAppUtils/InAppUtils.m +++ b/InAppUtils/InAppUtils.m @@ -19,6 +19,10 @@ - (instancetype)init return self; } ++ (BOOL)requiresMainQueueSetup { + return NO; +} + - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); @@ -124,7 +128,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue callback(@[@"restore_failed"]); break; } - + [_callbacks removeObjectForKey:key]; } else { RCTLogWarn(@"No callback registered for restore product request."); @@ -252,7 +256,7 @@ - (NSDictionary *)getPurchaseData:(SKPaymentTransaction *)transaction { purchase[@"originalTransactionDate"] = @(originalTransaction.transactionDate.timeIntervalSince1970 * 1000); purchase[@"originalTransactionIdentifier"] = originalTransaction.transactionIdentifier; } - + return purchase; } From 3bc09c03c4a9d05277f74f3442bc0001f46a55b7 Mon Sep 17 00:00:00 2001 From: chirag04 Date: Wed, 26 Sep 2018 10:25:34 -0400 Subject: [PATCH 09/16] 6.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d128aed..6ce33a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-in-app-utils", - "version": "6.0.0", + "version": "6.0.1", "description": "A react-native wrapper for handling in-app payments.", "author": { "name": "Chirag Jain", From ad34d0ffbd7cc39c446906aa466afed1715e9d16 Mon Sep 17 00:00:00 2001 From: Dmitry Alekseev <44493574+quarrant@users.noreply.github.com> Date: Sun, 10 Feb 2019 17:59:46 +0300 Subject: [PATCH 10/16] Update react-native-in-app-utils.podspec (#204) Fix a pod install error --- react-native-in-app-utils.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-native-in-app-utils.podspec b/react-native-in-app-utils.podspec index ce26c4a..8ade00c 100644 --- a/react-native-in-app-utils.podspec +++ b/react-native-in-app-utils.podspec @@ -10,7 +10,7 @@ Pod::Spec.new do |s| s.license = pjson["license"] s.author = { "Chirag Jain" => "jain_chirag04@yahoo.com" } s.platform = :ios, "7.0" - s.source = { :git => "https://github.com/chirag04/react-native-in-app-utils", :tag => "#{s.version}" } + s.source = { :git => "https://github.com/chirag04/react-native-in-app-utils.git", :tag => "v#{s.version}" } s.source_files = 'InAppUtils/*.{h,m}' s.dependency 'React' From 3573999ab9fc406b982c56452687955b3e21ec9f Mon Sep 17 00:00:00 2001 From: fabio cerdeiral <38343+fcerdeiral@users.noreply.github.com> Date: Mon, 26 Aug 2019 04:52:10 -0700 Subject: [PATCH 11/16] Start using Grand Unified Receipt format and remove usage of deprecated methods (#210) --- InAppUtils/InAppUtils.m | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/InAppUtils/InAppUtils.m b/InAppUtils/InAppUtils.m index d5737d4..3b545cb 100644 --- a/InAppUtils/InAppUtils.m +++ b/InAppUtils/InAppUtils.m @@ -193,13 +193,24 @@ - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue } RCT_EXPORT_METHOD(receiptData:(RCTResponseSenderBlock)callback) +{ + NSString *receipt = [self grandUnifiedReceipt]; + if (receipt == nil) { + callback(@[@"not_available"]); + } else { + callback(@[[NSNull null], receipt]); + } +} + +// Fetch Grand Unified Receipt +- (NSString *)grandUnifiedReceipt { NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL]; NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl]; if (!receiptData) { - callback(@[@"not_available"]); + return nil; } else { - callback(@[[NSNull null], [receiptData base64EncodedStringWithOptions:0]]); + return [receiptData base64EncodedStringWithOptions:0]; } } @@ -220,7 +231,7 @@ - (void)productsRequest:(SKProductsRequest *)request @"currencyCode": [item.priceLocale objectForKey:NSLocaleCurrencyCode], @"priceString": item.priceString, @"countryCode": [item.priceLocale objectForKey: NSLocaleCountryCode], - @"downloadable": item.downloadable ? @"true" : @"false" , + @"downloadable": item.isDownloadable ? @"true" : @"false" , @"description": item.localizedDescription ? item.localizedDescription : @"", @"title": item.localizedTitle ? item.localizedTitle : @"", }; @@ -248,7 +259,7 @@ - (NSDictionary *)getPurchaseData:(SKPaymentTransaction *)transaction { @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), @"transactionIdentifier": transaction.transactionIdentifier, @"productIdentifier": transaction.payment.productIdentifier, - @"transactionReceipt": [[transaction transactionReceipt] base64EncodedStringWithOptions:0] + @"transactionReceipt": [self grandUnifiedReceipt] }]; // originalTransaction is available for restore purchase and purchase of cancelled/expired subscriptions SKPaymentTransaction *originalTransaction = transaction.originalTransaction; From da0de5c9cb7d9bdf37a5dfb0bad9b142d0a8b21e Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Tue, 24 Sep 2019 14:46:18 -0400 Subject: [PATCH 12/16] 6.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ce33a3..b05b292 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-in-app-utils", - "version": "6.0.1", + "version": "6.0.2", "description": "A react-native wrapper for handling in-app payments.", "author": { "name": "Chirag Jain", From f9e5571e91ef107fbe1e57daffb0ae3c1f56c545 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Wed, 23 Sep 2020 11:37:33 -0400 Subject: [PATCH 13/16] fix iap promise issue on ios 14 (#225) update Co-authored-by: Chirag Jain --- InAppUtils/InAppUtils.m | 58 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/InAppUtils/InAppUtils.m b/InAppUtils/InAppUtils.m index 3b545cb..cf860da 100644 --- a/InAppUtils/InAppUtils.m +++ b/InAppUtils/InAppUtils.m @@ -28,15 +28,15 @@ - (dispatch_queue_t)methodQueue return dispatch_get_main_queue(); } -RCT_EXPORT_MODULE() +RCT_EXPORT_MODULE(); -- (void)paymentQueue:(SKPaymentQueue *)queue - updatedTransactions:(NSArray *)transactions +- (void) paymentQueue:(SKPaymentQueue *)queue + updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStateFailed: { - NSString *key = RCTKeyForInstance(transaction.payment.productIdentifier); + NSString *key = transaction.payment.productIdentifier; RCTResponseSenderBlock callback = _callbacks[key]; if (callback) { callback(@[RCTJSErrorFromNSError(transaction.error)]); @@ -48,7 +48,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue break; } case SKPaymentTransactionStatePurchased: { - NSString *key = RCTKeyForInstance(transaction.payment.productIdentifier); + NSString *key = transaction.payment.productIdentifier; RCTResponseSenderBlock callback = _callbacks[key]; if (callback) { NSDictionary *purchase = [self getPurchaseData:transaction]; @@ -75,9 +75,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue } } -RCT_EXPORT_METHOD(purchaseProductForUser:(NSString *)productIdentifier - username:(NSString *)username - callback:(RCTResponseSenderBlock)callback) +RCT_EXPORT_METHOD(purchaseProductForUser:(NSString *)productIdentifier username:(NSString *)username callback:(RCTResponseSenderBlock)callback) { [self doPurchaseProduct:productIdentifier username:username callback:callback]; } @@ -107,7 +105,7 @@ - (void) doPurchaseProduct:(NSString *)productIdentifier payment.applicationUsername = username; } [[SKPaymentQueue defaultQueue] addPayment:payment]; - _callbacks[RCTKeyForInstance(payment.productIdentifier)] = callback; + _callbacks[payment.productIdentifier] = callback; } else { callback(@[@"invalid_product"]); } @@ -116,7 +114,7 @@ - (void) doPurchaseProduct:(NSString *)productIdentifier - (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error { - NSString *key = RCTKeyForInstance(@"restoreRequest"); + NSString *key = @"restoreRequest"; RCTResponseSenderBlock callback = _callbacks[key]; if (callback) { switch (error.code) @@ -137,7 +135,7 @@ - (void)paymentQueue:(SKPaymentQueue *)queue - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue { - NSString *key = RCTKeyForInstance(@"restoreRequest"); + NSString *key = @"restoreRequest"; RCTResponseSenderBlock callback = _callbacks[key]; if (callback) { NSMutableArray *productsArrayForJS = [NSMutableArray array]; @@ -160,15 +158,15 @@ - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue RCT_EXPORT_METHOD(restorePurchases:(RCTResponseSenderBlock)callback) { NSString *restoreRequest = @"restoreRequest"; - _callbacks[RCTKeyForInstance(restoreRequest)] = callback; + _callbacks[restoreRequest] = callback; [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; } RCT_EXPORT_METHOD(restorePurchasesForUser:(NSString *)username - callback:(RCTResponseSenderBlock)callback) + callback:(RCTResponseSenderBlock)callback) { NSString *restoreRequest = @"restoreRequest"; - _callbacks[RCTKeyForInstance(restoreRequest)] = callback; + _callbacks[restoreRequest] = callback; if(!username) { callback(@[@"username_required"]); return; @@ -186,7 +184,7 @@ - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue [productsRequest start]; } -RCT_EXPORT_METHOD(canMakePayments: (RCTResponseSenderBlock)callback) +RCT_EXPORT_METHOD(canMakePayments:(RCTResponseSenderBlock)callback) { BOOL canMakePayments = [SKPaymentQueue canMakePayments]; callback(@[@(canMakePayments)]); @@ -225,16 +223,16 @@ - (void)productsRequest:(SKProductsRequest *)request NSMutableArray *productsArrayForJS = [NSMutableArray array]; for(SKProduct *item in response.products) { NSDictionary *product = @{ - @"identifier": item.productIdentifier, - @"price": item.price, - @"currencySymbol": [item.priceLocale objectForKey:NSLocaleCurrencySymbol], - @"currencyCode": [item.priceLocale objectForKey:NSLocaleCurrencyCode], - @"priceString": item.priceString, - @"countryCode": [item.priceLocale objectForKey: NSLocaleCountryCode], - @"downloadable": item.isDownloadable ? @"true" : @"false" , - @"description": item.localizedDescription ? item.localizedDescription : @"", - @"title": item.localizedTitle ? item.localizedTitle : @"", - }; + @"identifier": item.productIdentifier, + @"price": item.price, + @"currencySymbol": [item.priceLocale objectForKey:NSLocaleCurrencySymbol], + @"currencyCode": [item.priceLocale objectForKey:NSLocaleCurrencyCode], + @"priceString": item.priceString, + @"countryCode": [item.priceLocale objectForKey: NSLocaleCountryCode], + @"downloadable": item.isDownloadable ? @"true" : @"false" , + @"description": item.localizedDescription ? item.localizedDescription : @"", + @"title": item.localizedTitle ? item.localizedTitle : @"", + }; [productsArrayForJS addObject:product]; } callback(@[[NSNull null], productsArrayForJS]); @@ -256,11 +254,11 @@ - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ - (NSDictionary *)getPurchaseData:(SKPaymentTransaction *)transaction { NSMutableDictionary *purchase = [NSMutableDictionary dictionaryWithDictionary: @{ - @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), - @"transactionIdentifier": transaction.transactionIdentifier, - @"productIdentifier": transaction.payment.productIdentifier, - @"transactionReceipt": [self grandUnifiedReceipt] - }]; + @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), + @"transactionIdentifier": transaction.transactionIdentifier, + @"productIdentifier": transaction.payment.productIdentifier, + @"transactionReceipt": [self grandUnifiedReceipt] + }]; // originalTransaction is available for restore purchase and purchase of cancelled/expired subscriptions SKPaymentTransaction *originalTransaction = transaction.originalTransaction; if (originalTransaction) { From ed357696a81fc2a0c210f72291e4803ddec99dbe Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Wed, 23 Sep 2020 11:38:53 -0400 Subject: [PATCH 14/16] 6.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b05b292..e10c615 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-in-app-utils", - "version": "6.0.2", + "version": "6.1.0", "description": "A react-native wrapper for handling in-app payments.", "author": { "name": "Chirag Jain", From 598093ef424280c6f0342ab939436e7a76af9fdd Mon Sep 17 00:00:00 2001 From: Seth Archambault Date: Tue, 19 Jan 2021 17:13:22 -0500 Subject: [PATCH 15/16] Update ios deployment target from 7 to 8 (#227) Closes #199 --- react-native-in-app-utils.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-native-in-app-utils.podspec b/react-native-in-app-utils.podspec index 8ade00c..035d531 100644 --- a/react-native-in-app-utils.podspec +++ b/react-native-in-app-utils.podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.summary = pjson["description"] s.license = pjson["license"] s.author = { "Chirag Jain" => "jain_chirag04@yahoo.com" } - s.platform = :ios, "7.0" + s.platform = :ios, "8.0" s.source = { :git => "https://github.com/chirag04/react-native-in-app-utils.git", :tag => "v#{s.version}" } s.source_files = 'InAppUtils/*.{h,m}' From 6ebc17a35a5a833e7435d8be179c458ef1993adb Mon Sep 17 00:00:00 2001 From: Ben Styles Date: Wed, 9 Jun 2021 18:30:45 +0200 Subject: [PATCH 16/16] Fix simulator crash (#231) Co-authored-by: Ben Styles --- InAppUtils/InAppUtils.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InAppUtils/InAppUtils.m b/InAppUtils/InAppUtils.m index cf860da..f35fff3 100644 --- a/InAppUtils/InAppUtils.m +++ b/InAppUtils/InAppUtils.m @@ -253,11 +253,12 @@ - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ } - (NSDictionary *)getPurchaseData:(SKPaymentTransaction *)transaction { + NSString *receipt = [self grandUnifiedReceipt]; NSMutableDictionary *purchase = [NSMutableDictionary dictionaryWithDictionary: @{ @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), @"transactionIdentifier": transaction.transactionIdentifier, @"productIdentifier": transaction.payment.productIdentifier, - @"transactionReceipt": [self grandUnifiedReceipt] + @"transactionReceipt": receipt ? receipt : [NSNull null] }]; // originalTransaction is available for restore purchase and purchase of cancelled/expired subscriptions SKPaymentTransaction *originalTransaction = transaction.originalTransaction;