Ionic iOS端In App Purchase取消及退款回调未触发问题咨询
核心问题排查结果
你现在收不到回调主要是两个核心问题导致的:
- 产品类型注册错误
你把月度自动续期订阅注册成了NON_CONSUMABLE(非消耗型商品),这类商品是一次购买永久生效的,插件本身就不会为这类商品处理订阅到期、取消、退款相关的状态流转,自然不会触发对应回调,商品状态会一直停留在owned,和你现在遇到的现象完全吻合。 - 回调触发场景理解偏差
cancelled回调仅在用户主动中断当前购买流程时触发,比如弹出支付确认框(输密码/刷Face ID环节)用户点了取消,才会走这个回调。用户在系统设置里关闭订阅自动续费,不属于这个回调的触发范围——关闭自动续费只是代表下个周期不再扣费,当前已经付费的订阅周期内用户依然享有完整权益,不会立刻触发状态变更。refunded回调不会由系统主动推送到你的客户端,必须主动刷新收据、结合服务端校验才能拿到退款状态,不存在用户申请退款后客户端立刻收到回调的逻辑。
具体修复方案
- 修正商品注册类型
自动续期订阅在插件里对应的类型是PAID_SUBSCRIPTIONS,替换掉原来注册逻辑里的错误类型即可:// 注册产品 this.store.register({ id: this.PRODUCT_IOS_MONTHLY_RECURRING_ID, type: this.store.PAID_SUBSCRIPTIONS // 替换原来的NON_CONSUMABLE }); - 补全正确的事件监听
原来的监听逻辑里缺了订阅过期的回调,用户关闭自动续费后,等当前订阅周期结束,商品状态会变为过期,这时候你可以回收用户权益:this.store.when(this.PRODUCT_IOS_MONTHLY_RECURRING_ID) .cancelled(this.purchaseCancelled) // 仅处理购买流程中途取消 .updated(this.purchaseMonthlyUpdated) .approved(this.purchaseApproved) .verified(this.purchaseVerified) .refunded(this.purchaseRefunded) .owned(this.purchaseOwned) .expired(this.purchaseExpired); // 新增:订阅到期未续费触发,在这里处理权益回收 - 补全状态主动刷新逻辑
不要只在初始化的时候调用一次refresh方法,在以下场景必须主动调用this.store.refresh()拉取最新的商店订单状态:- App每次冷启动完成后
- App从后台切回前台时
- 用户进入会员中心、订阅相关页面时
- 不要纯依赖客户端状态做权益判断
客户端的插件状态只能做参考,所有权益判定必须走服务端校验:- 客户端拿到交易收据后上传到你的服务端,由服务端对接苹果的收据校验接口,解析真实的订阅过期时间、退款标记
- 在App Store Connect配置服务端订阅通知地址,苹果会把退款、订阅取消、计费失败、续费成功这类事件实时推送到你的服务端,服务端更新用户权益状态后,客户端再拉取最新权益即可,这是唯一能实时感知退款事件的方式。
- 沙箱测试注意点
沙箱环境的订阅时间是加速的,同时状态同步存在1-5分钟的延迟,操作取消订阅、申请退款后不要立刻判断结果,多触发几次refresh、等待几分钟再验证状态。
内容的提问来源于stack exchange,提问作者Shraddha Shravagi
相关产品推荐
相关产品推荐

