在做Apple pay的时候,遇到了串单的问题,究其原因就是无论支付成功还是失败,苹果都不会返回任何与订单相关的直接参数,我无法与我们服务器的订单号唯一对应,导致,处理订单的时候会乱,通过几天的摸索,找到了以下解决方法,我认为应该可以完美解决iOS7以及以上的串单问题,但是iOS7以下,我没有什么好的方法!
1. 当我们向苹果服务器发起支付请求后,苹果会回调如下方法:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
LGLog(@"Transaction is being added to the server queue.");
break;
default:
break;
}
}
}
2. 当苹果回调后,我们需要在
- (void)completeTransaction:(SKPaymentTransaction *)transaction 或者
- (void)restoreTransaction:(SKPaymentTransaction *)transaction 或者
- (void)failedTransaction:(SKPaymentTransaction *)transaction 中调用
[[SKPaymentQueue defaultQueue] finishTransaction:transaction],告诉苹果我们已经接到通知,如果此方法通知苹果失败,那么苹果会一直调用 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions,直到我们通知苹果成功,这样一来,就会出现串单问题。 因为苹果在 transaction 中没有返给我们任何跟订单相关的参数,我们无法跟我们服务器的订单唯一对应
3. 解决办法:
对于成功的回调,transaction中会包含一个交易号transaction.transactionIdentifier ,它是唯一的,我们可以将它保存到本地,用于区别不同的订单;
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
// 如果苹果已经有过成功回调,则作废此次回调
if (![ZCTool saveTransactionIdentifier:transaction.transactionIdentifier]) {
return;
}
}对于失败的回调,iOS7以及以上(iOS7以下,我没有好方法),我们可以使用 transaction.payment.applicationUsername 保存订单号,具体做法如下
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
if (SYSTEM_VERSION >= 7.0) {
payment.applicationUsername = ourOrderId;
}
[[SKPaymentQueue defaultQueue] addPayment:payment];
这样,在失败回调方法中,我们可以如下处理,跟成功回调保存交易号的处理逻辑一致
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if (SYSTEM_VERSION >= 7.0) {
// 处理iOS7以及以上,如果苹果已经有过失败回调,则作废此次回调
if (![ZCTool saveAppleFailureOrderId:transaction.payment.applicationUsername]) {
return;
}
}
}
如果大家有什么更好的方法,请指教!