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;

        }

    }

}

如果大家有什么更好的方法,请指教!

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