首页 > 解决方案 > SKPaymentQueue finishTransactions 未从队列中删除交易

问题描述

updatedTransactions:委托回调正在触发几天前的旧交易。我试着打电话finishTransactions给他们,但是当我启动应用程序时,同样的交易仍然存在(检查transactionIdentifier)一遍又一遍。

我无法进行任何新的购买。进行新购买时,这些旧交易之一将在SKPaymentTransactionStatePurchased状态下返回,但由于之前已经成功,我收到来自 Apple 的错误:“此应用内购买已被购买。它将免费恢复. [环境:沙盒]”

错误信息

如何正确地从事务队列中删除事务?

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {

    // Getting called with old, already finished transactions

    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                break;
            case SKPaymentTransactionStateDeferred:
                // ...
                break;
            case SKPaymentTransactionStateFailed:
                // ...
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                // validate receipt first
                // then finish transaction
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                // ...
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            default:
                break;
        }
    }
}

编辑:

我确认finishTransactions没有将它们从队列中删除。

NSArray<SKPaymentTransaction *> *transactions = [[SKPaymentQueue defaultQueue] transactions];
NSLog(@"BEFORE transactions = %@", transactions);
for (SKPaymentTransaction *txn in transactions) {
    [[SKPaymentQueue defaultQueue] finishTransaction:txn];
}
transactions = [[SKPaymentQueue defaultQueue] transactions];
NSLog(@"AFTER transactions = %@", transactions);

输出:

BEFORE transactions = (
    "<SKPaymentTransaction: 0x2802c8b10>",
    "<SKPaymentTransaction: 0x2802c8c60>",
    "<SKPaymentTransaction: 0x2802c8c40>",
    "<SKPaymentTransaction: 0x2802c8c20>",
    "<SKPaymentTransaction: 0x2802c8b00>"
)
AFTER transactions = (
    "<SKPaymentTransaction: 0x2802c8b10>",
    "<SKPaymentTransaction: 0x2802c8c60>",
    "<SKPaymentTransaction: 0x2802c8c40>",
    "<SKPaymentTransaction: 0x2802c8c20>",
    "<SKPaymentTransaction: 0x2802c8b00>"
)

编辑#2:

我在 Apple 开发者论坛上发现,这在过去 48 小时内影响了其他一些人。我相信这是 Apple 方面的一个问题。

编辑#3:

我们通过我们的合作伙伴团队联系了 Apple,并确认 Apple 的服务在此期间确实出现了故障,但问题已得到解决。

标签: iosin-app-purchasestorekit

解决方案


首先,您需要将所有purchasedrestoredfailedtransactions 标记为finished,而不仅仅是purchased那些。

要从一个空的交易队列重新开始,我建议您将以下行添加到您的商店组件或您处理购买的任何地方的初始化代码中:

SKPaymentQueue.default().transactions.forEach({ SKPaymentQueue.default().finishTransaction($0) })

这会将所有当前打开的事务标记为已完成,并允许您从空事务队列重新开始。


推荐阅读