I'm simulating purchases of an Auto-renewing subscription in my app on an iPhone. My issue is that the purchase is considered to be done by the App store while it is not.
Here is what is going on:
- The user presses a button to purchase the renewing subscription
- The user gives his iTunes password and confirms the purchase
- The app submits the receipt received from the app store to my server to check validity
- The server returns a "ok" or "not ok" string. The app calls finishTransaction only on "ok"
I have an issue when there is a network failure on step 3. I can't validate the receipt. But if the user tries to purchase a second time, the app store tells him that he has already subscribed, even though I didn't call the finishTransaction
method to complete the purchase!
Is this an expected behavior? Shouldn't the app-store treat non-finished transactions as non-finished, or am I missing something? I would welcome any suggestion to solve this issue.
-(void) userPurchase:(SKProduct*) product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
NSLog(@"paymentQueue updatedTransaction");
for (SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStatePurchased:
[self recordSubscription:transaction];
break;
case SKPaymentTransactionStateFailed:
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self recordSubscription:transaction];
break;
default: NSLog(@"Default");
break;
}
};
}
-(void) recordSubscription:(SKPaymentTransaction*)transaction{
NSString *jsonObjectString = [self encode:(uint8_t *)transaction.transactionReceipt.bytes length:transaction.transactionReceipt.length];
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:jsonObjectString,@"receiptdata", nil];
[[AFNetworkSubClass sharedClient] postPath:@"myserver" params:params
success:^(AFHTTPRequestOperation *operation, id output) {
/* some code */
if([valstring isEqualToString:@"ok"]){
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"validation failed");
}