iOS---蘋果支付串單完美解決方案

在做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;

        }

    }

}

如果大家有什麼更好的方法,請指教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章