如何获取消耗型SKProduct重复购买的AppStore响应并提示用户
解决消耗型内购重复购买无响应问题
针对你遇到的重复点击购买按钮后无StoreKit响应、无法提示用户的问题,可按以下步骤处理:
1. 发起购买前拦截重复请求
用户重复点击按钮时,可能同一商品的未完成交易仍在支付队列中,此时重复添加支付请求会被StoreKit静默忽略。所以要在发起购买前先做本地校验:
func purchaseProduct(product: SKProduct) { // 过滤队列中未完成的同商品交易 let pendingTransactions = SKPaymentQueue.default().transactions.filter { guard let pid = $0.payment.productIdentifier else { return false } return pid == product.productIdentifier && ![$0.transactionState == .purchased, $0.transactionState == .failed, $0.transactionState == .restored].contains(true) } if !pendingTransactions.isEmpty { showAlert(message: "购买请求正在处理中,请稍候") return } // 正常发起购买 let payment = SKPayment(product: product) SKPaymentQueue.default().add(payment) }
2. 修复交易处理逻辑的核心问题
你的代码中未调用finishTransaction,这会导致已完成的交易一直滞留在队列中,后续购买请求可能被静默拦截。同时要修正.purchasing状态的打印错误,并完善错误处理:
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch transaction.transactionState { case .purchased: print("购买成功") // 这里添加你的业务逻辑:标记商品消耗、同步服务器等 completePurchase(transaction: transaction) // 必须调用finish,否则交易永远留在队列 queue.finishTransaction(transaction) case .restored: print("已恢复购买") queue.finishTransaction(transaction) case .failed: print("购买失败") if let skError = transaction.error as? SKError { handlePurchaseError(error: skError) } queue.finishTransaction(transaction) case .deferred: print("购买等待家长审批") case .purchasing: print("正在处理购买请求") // 修正你之前的打印错误 @unknown default: fatalError() } } } // 处理SK错误,给出对应提示 func handlePurchaseError(error: SKError) { var message = "购买失败" switch error.code { case .paymentCancelled: message = "你已取消购买" case .paymentInvalid: message = "支付请求无效" case .paymentNotAllowed: message = "你的账户不允许进行支付" default: message += ": \(error.localizedDescription)" } showAlert(message: message) }
3. 关于Firebase的提示说明
Firebase Analytics的Purchase is a duplicate and will not be reported是其自身的去重逻辑——当短时间内检测到同一用户重复上报同一商品的购买事件时,会自动跳过重复上报,这和StoreKit的响应无关,无需额外处理。
4. 沙盒环境注意事项
消耗型内购在沙盒环境下允许重复购买,但如果交易未被正确finish,或者你的业务逻辑未标记商品已消耗(比如服务器未同步状态),可能导致后续购买无响应,务必确保交易完成后及时清理队列和更新业务状态。
内容的提问来源于stack exchange,提问作者incelemeTRe
相关产品推荐
相关产品推荐

