前言
促销优惠是 iOS12.2新增的针对 IAP 自动续期订阅类型产品更加灵活的促销方式, 整体流程如下图, 官方文档见 https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_subscription_offers_in_your_app?language=objc
那我们的server需要做什么呢?
1.判断用户是否可以使用优惠
2.对参数进行签名
3.解析收据中促销优惠相关字段
使用场景
我们的场景是一个连包会员业务, ios端使用iap的自动续期订阅类型
接入流程
1. 后台配置
配置主要分为两步
1.登陆app store connect, 找到「用户和访问」->「密钥」->「订阅」, 点击+号, 创建完成后, 点击下载密钥文件(是一个采用ECC算法的私钥文件), 这个文件只能下载一次, 一定要保存好, 并且不要随意泄漏给其他人. 这里的 密钥ID 后面流程会用到
2.登陆app store connect, 找到 「我的app」 -> 「功能」-> 「你们的订阅商品」-> 「订阅价格」, 点击 + 号, 选择 创建促销优惠, 这时需要设置我们的优惠名称, 优惠代码(该字段在后续流程会用到), 点击下一步后, 创建优惠价格
2. 判断用户是否可以使用促销优惠
这个就是具体的业务逻辑了, 苹果支持 当前正在订阅中 以及 已经过期的订阅 使用促销优惠, 但是要注意一点, 第一次购买app下的订阅商品时不能使用促销优惠, 客户端调用促销优惠相关逻辑时会报错, 这种case 我们的处理方案是, 客户端解析到该异常, 传递一个重试标记, 服务端记录重试标记, 当标记存在时不返回优惠, 任意一笔订阅交易成功后删除标记.
3. 生成签名
签名的生成规则 https://developer.apple.com/documentation/storekit/in-app_purchase/generating_a_signature_for_subscription_offers?language=objc
签名字段如下
字段名 | 来源 |
---|---|
appBundleID | 值为 app store connect中「我的APP」-> 「APP信息」->「综合信息」->「套装ID」 |
keyIdentifier | 后台配置第一步中的密钥ID |
productIdentifier | 后台配置的商品code |
offerIdentifier | 后台配置第二步中的优惠产品code(需要根据业务场景具体选择一个优惠产品code) |
applicationUsername | 依赖客户端具体的使用, 需要跟客户端确认 |
nonce | UUID, 一定要满足UUID的标准格式, 不然会报错, 服务端是java的话可以使用java.util.UUID.randomUUID().toString() |
timestamp | 时间戳 |
注意!
苹果使用的加密算法为ECC, 服务端是java的话, 签名时使用
KeyFactory.getInstance(“ec”);
Signature.getInstance(“SHA256WithECDSA”);
其余签名代码省略, 请读者自行查找
4. 解析优惠字段
当用户使用促销优惠支付后, 收据in_app和latest_receipt_info 中会出现 promotional_offer_id 字段, 值为使用当优惠的code