Some checks failed
Build docker and publish / build (20.15.1) (push) Has been cancelled
实现Apple应用内购支付功能,包括: 1. 新增AppleIAP和ApplePay支付平台枚举 2. 添加IAP验证接口/v1/public/iap/verify处理初购验证 3. 实现Apple服务器通知处理逻辑/v1/iap/notifications 4. 新增JWS验签和JWKS公钥缓存功能 5. 复用现有订单系统处理IAP支付订单 相关文档已更新,包含接入方案和实现细节
2.7 KiB
2.7 KiB
实施目标
- 复用现有订单与队列赋权,接入 Apple 自动续期(IAP),保持报表/审计/通知一致。
方案选择
- 采用“平台化复用 + 合成订单”的方式:Apple 由客户端结算 + 服务器通知驱动,服务端生成“已支付订单”进入现有赋权与续费流程。
具体改动(按文件)
- 平台标识
- 更新
pkg/payment/platform.go:新增AppleIAP枚举与名称(仅标识,不参与PurchaseCheckout)。
- 路由与 Handler
- 新增公共接口:
POST /v1/public/iap/verify- 位置:
internal/handler/public/iap/verifyHandler.go - 逻辑:调用
internal/logic/public/iap/verifyLogic.go,以originalTransactionId验证 Apple 购买,生成“已支付订阅订单”,入队激活。
- 位置:
- 新增通知接口:
POST /v1/iap/notifications- 位置:
internal/handler/notify/appleIAPNotifyHandler.go - 逻辑:调用
internal/logic/notify/appleIAPNotifyLogic.go,JWS 验签后按事件(初购/续期/退款)生成或更新订单,触发续费或撤销权益。
- 位置:
- 路由注册:
internal/handler/routes.go增加/v1/public/iap/verify路由。internal/handler/notify.go增加独立/v1/iap/notifications路由(Apple 不带:token)。
- 数据与模型
- 在用户订阅(或新建
iap_binding表)绑定:originalTransactionId、environment、latestExpiresDate。 - 订单字段复用:
Method=AppleIAP、TradeNo=originalTransactionId、Type=1/2(订阅/续费),Status=2(已支付),金额可取通知中的价格;取不到则置Amount=0保证流程。
- 逻辑复用与改造点
- 赋权:复用
queue/logic/order/activateOrderLogic.go:165 NewPurchase。 - 续费:复用
queue/logic/order/activateOrderLogic.go:529 updateSubscriptionForRenewal。 - 不改动
internal/logic/public/portal/purchaseCheckoutLogic.go的渠道路由(Apple 不走此流程)。
- 安全与幂等
- Apple JWS 验签:拉取并缓存 JWKS 公钥,校验通知;拒绝无效签名。
- 幂等:以
notificationId/transactionId与originalTransactionId去重处理。
- 客户端协作
- iOS:完成 StoreKit 购买后携带
originalTransactionId调用/v1/public/iap/verify。 - 续费:依赖 Server Notifications v2 自动驱动,无需客户端调用。
- 测试与监控
- 沙盒验证初购、续期、重试与宽限期、退款撤销;注意元数据延迟(~1小时)。
- 指标:通知验签失败、API 调用失败、幂等冲突、状态不一致报警。
交付节奏
- 第一步:平台枚举与路由骨架;
- 第二步:
verify验证与“合成订单”生成; - 第三步:通知验签与事件映射;
- 第四步:沙盒联调,确认队列赋权与续费延长。