这种现象可能有很多情况,最常见的原因就是 已有的Apple订单没有正确关闭! 经过老狗的测试,老狗遇到的是下面这种情况:
沙箱测试环境下,订阅会员成功后,后续每5分钟自动续费一次(沙箱设置),自动续费后,下次再支付,就不会有已订阅的提示了,直接自动提示支付成功了!但此时会员其实并没有增加有效期!(正常情况下,订阅有效期间订阅相同内容,apple支付会直接提示已订阅,无需重复订阅)
经过学习和排查发现我的错误原因,是因为app前端没有正确处理自动续费的通知!出现问题的逻辑步骤大概如下:
这就是Apple侧的前端支付通知设计,不仅是当下的支付会有通知,以前的自动续费但未完结的订单也会通知!
在apple自动续费后,下次初始化iap支付时,会立即通知之前没有处理完成的订单,一般自动续费都是支付成功的订单,所以现象就是:当你初始化支付时,apple还没开始处理新的支付,你的程序就(误以为)接收到了支付成功的通知,从而自动完成了。。。
(网络搜集到的)解决方案 也“很简单”:在进入商品页面,或启动app时,就初始化一次iap支付,此时可能接收到一些自动续费的成功的通知,接收到通知时,正确处理这些通知,调用“complate”保证把这些通知相关的交易正确关闭,这样就不会再收到这些通知了!
当然这种解决方案也有问题:如果自动续费的通知没有和服务端订单匹配上,怎么处理?是不是会影响用户权益?这就要你自己取舍了! 普遍的做法是:如果接收到支付成功通知,象征性地与服务端校验,无论服务端是否处理成功,前端都要调用“complate”,来确保这个通知完结!不要影响后续的支付!!!
上面是基于网上搜集资料和自己实际问题总结的文字,仅供参考!
再往下是 Gemini 的回答,请自行阅读分析
如果发起支付后,没有弹出 Apple 的购买认证界面(要求输入密码/Face ID/Touch ID),而直接收到了 SKPaymentTransactionState.purchased 的回调,这几乎可以确定是因为:
这是最常见且最重要的原因。当您尝试购买一个商品时,StoreKit 会检查这个商品在购买队列中的状态。
如果用户之前在相同设备上发起过对同一个 Product Identifier 的购买,但由于某种原因(比如网络中断、App 闪退)导致交易未能完成(finishTransaction 未被调用),那么这笔交易可能还留在 SKPaymentQueue 中。
当您再次调用 add(payment) 时,App Store 不会重新发起认证,而是直接将队列中已存在的、状态为 purchased 的旧交易返回给您。
解决方案: 任何时候收到
purchased状态后,您的代码中必须调用SKPaymentQueue.default().finishTransaction(transaction)来完成交易。如果不调用,下次启动 App 或下次购买时,这笔交易会再次被返回。
如果您尝试购买一个已经被用户成功购买过的 非消耗品(例如“永久高级会员”、“解锁所有关卡”),Apple 会识别到用户已经拥有该商品。
在这种情况下,StoreKit 不会要求用户再次付费,也不会弹出认证界面,而是直接将这笔交易以 SKPaymentTransactionState.restored 的状态回调给您。
注意: 尽管您收到的是
restored状态,但有些开发者在处理逻辑上可能会将restored误认为purchased(或处理方式相同),造成“直接成功”的错觉。请检查您的回调代码。
如果您在 Sandbox (沙盒) 环境下测试,Apple 的行为有时会简化:
在某些情况下,特别是使用 Touch ID/Face ID 认证购买,如果用户刚刚完成了一笔购买,App Store 可能会在极短的时间内缓存认证信息。但这种情况比较少见,且持续时间很短。
本文作者:DingDangDog
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!