Skip to content

Commit 4ccd776

Browse files
authored
Merge pull request #1 from squaretwo/feature/manual_purchase_finish
Add manual purchase finish
2 parents 08e18ea + b55a62d commit 4ccd776

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

InAppUtils/InAppUtils.m

+53-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ - (void)paymentQueue:(SKPaymentQueue *)queue
5858
} else {
5959
RCTLogWarn(@"No callback registered for transaction with state purchased.");
6060
}
61-
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
6261
break;
6362
}
6463
case SKPaymentTransactionStateRestored:
@@ -76,6 +75,28 @@ - (void)paymentQueue:(SKPaymentQueue *)queue
7675
}
7776
}
7877

78+
RCT_EXPORT_METHOD(getPendingPurchases:(RCTResponseSenderBlock)callback)
79+
{
80+
NSMutableArray *transactionsArrayForJS = [NSMutableArray array];
81+
for (SKPaymentTransaction *transaction in [SKPaymentQueue defaultQueue].transactions) {
82+
NSMutableDictionary *purchase = [NSMutableDictionary dictionaryWithDictionary: @{
83+
@"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000),
84+
@"transactionIdentifier": transaction.transactionIdentifier,
85+
@"productIdentifier": transaction.payment.productIdentifier,
86+
@"transactionReceipt": [[transaction transactionReceipt] base64EncodedStringWithOptions:0],
87+
@"transactionState": StringForTransactionState(transaction.transactionState)
88+
}];
89+
SKPaymentTransaction *originalTransaction = transaction.originalTransaction;
90+
if (originalTransaction) {
91+
purchase[@"originalTransactionDate"] = @(originalTransaction.transactionDate.timeIntervalSince1970 * 1000);
92+
purchase[@"originalTransactionIdentifier"] = originalTransaction.transactionIdentifier;
93+
}
94+
95+
[transactionsArrayForJS addObject:purchase];
96+
}
97+
callback(@[[NSNull null], transactionsArrayForJS]);
98+
}
99+
79100
RCT_EXPORT_METHOD(purchaseProductForUser:(NSString *)productIdentifier
80101
username:(NSString *)username
81102
callback:(RCTResponseSenderBlock)callback)
@@ -114,6 +135,24 @@ - (void) doPurchaseProduct:(NSString *)productIdentifier
114135
}
115136
}
116137

138+
RCT_EXPORT_METHOD(finishPurchase:(NSString *)transactionIdentifier
139+
callback:(RCTResponseSenderBlock)callback)
140+
{
141+
for (SKPaymentTransaction *transaction in [SKPaymentQueue defaultQueue].transactions) {
142+
if ([transaction.transactionIdentifier isEqualToString:transactionIdentifier]) {
143+
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
144+
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
145+
callback(@[[NSNull null]]);
146+
} else {
147+
callback(@[@"invalid_purchase"]);
148+
}
149+
return;
150+
}
151+
}
152+
callback(@[@"invalid_purchase"]);
153+
}
154+
155+
117156
- (void)paymentQueue:(SKPaymentQueue *)queue
118157
restoreCompletedTransactionsFailedWithError:(NSError *)error
119158
{
@@ -270,5 +309,18 @@ - (void)dealloc
270309
{
271310
return [NSString stringWithFormat:@"%p", instance];
272311
}
312+
313+
static NSString *StringForTransactionState(SKPaymentTransactionState state)
314+
{
315+
switch(state) {
316+
case SKPaymentTransactionStatePurchasing: return @"purchasing";
317+
case SKPaymentTransactionStatePurchased: return @"purchased";
318+
case SKPaymentTransactionStateFailed: return @"failed";
319+
case SKPaymentTransactionStateRestored: return @"restored";
320+
case SKPaymentTransactionStateDeferred: return @"deferred";
321+
}
322+
323+
[NSException raise:NSGenericException format:@"Unexpected SKPaymentTransactionState."];
324+
}
273325

274326
@end

Readme.md

+8
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,15 @@ InAppUtils.purchaseProduct(productIdentifier, (error, response) => {
6969
// NOTE for v3.0: User can cancel the payment which will be available as error object here.
7070
if(response && response.productIdentifier) {
7171
Alert.alert('Purchase Successful', 'Your Transaction ID is ' + response.transactionIdentifier);
72+
7273
//unlock store here.
74+
75+
// After providing the item, we call finishPurchase to finalize the transaction.
76+
InAppUtils.finishPurchase(response.transactionIdentifier, (error) => {
77+
if (!error) {
78+
// Transaction Complete
79+
}
80+
});
7381
}
7482
});
7583
```

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-in-app-utils",
3-
"version": "5.6.0",
3+
"version": "6.0.0",
44
"description": "A react-native wrapper for handling in-app payments.",
55
"author": {
66
"name": "Chirag Jain",

0 commit comments

Comments
 (0)