在做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;
}
}
}
如果大家有什麼更好的方法,請指教!