1. 为什么调用了finishTransaction、clearTransactionIOS之后,
requestPurchase请求得到的还是之前交易的签证
这是 iOS 的 StoreKit 行为机制 导致的:即使你调用了 finishTransaction 和 clearTransactionIOS,仍可能返回之前的交易凭证(receipt),原因通常如下:
⸻
🔍 主要原因分析
1. 交易未在 Apple 服务器真正确认(未消费完成)
• finishTransaction() 虽然告诉客户端“我处理完了”,
• 但 如果未将凭证提交到你的服务器/Apple 做验证,Apple 可能仍认为这是个“未完成的订阅”。
👉 特别是在 自动续订订阅 (auto-renewable subscriptions) 场景下:
• Apple 会持续把旧的 receipt 作为最新状态返回。
• 这不是 SDK 缓存,而是来自 Apple 的行为。
⸻
2. clearTransactionIOS() 只能清除本地挂起交易,但不能清除服务器端状态。
await clearTransactionIOS();
这个方法只是清理 本地临时状态(如重复消费的提醒),不会影响 Apple 返回的交易凭证。
⸻
✅ 正确做法建议
✅ 1. 永远在服务端验证 receipt
调用 requestPurchase 后获得的 transactionReceipt(或 purchase.transactionReceipt)必须发送到服务器去 Apple 校验,确保是否为新订阅、续订、试用等。
✅ 2. 使用 getAvailablePurchases() 处理旧交易
这用于处理“未完成消费”的场景,而不应每次都直接调用 requestPurchase。
const purchases = await RNIap.getAvailablePurchases();
purchases.forEach(p => {
await finishTransaction(p);
});
✅ 3. 避免短时间内重复请求相同商品
Apple 会限制短时间内对同一个订阅项的重复请求,并返回旧的交易凭证。
⸻
🧪 调试建议
1. 确保沙盒账号是新的,且清除旧交易记录
2. 可尝试创建新的商品 ID(避免复用测试订阅)
3. 观察 purchase.transactionId 和 originalTransactionId 是否一致:
• 若一致,则是重复的挂起交易。
⸻
📌 总结
如果你每次调用 requestPurchase 都获取的是“旧交易”的凭证,很可能是因为:
• Apple 认为该交易还未消费(需要服务端验证并记录)
• 或当前账号/商品状态已自动续订,返回的是当前订阅状态(不是新交易)
⸻
是否需要我帮你写一段完整的处理逻辑,包括验证、消费、监听的订阅处理流程?