虽然通过苹果的StoreKit2框架客户端可以直接处理整个支付流程,不再需要验证票据了,但是绝大多数业务场景都需要再服务器端再次验证支付逻辑,这时我们就需要解析苹果服务器到服务器到支付通知了,这里只说明通知数据结构的解析,具体可以分为如下三步来实现:
第1步:苹果服务器POST过来的JSON数据:
{
"signedPayload": "eyJhbGciOiJF这里是被加密的内容eyJhbGciOiJF"
}
第2步:按照苹果官方提供的方法提取出signedPayload的内容如下:
{
"notificationType" : "DID_RENEW",
"subtype" : "子类型",
"notificationUUID" : "f2d65c0c-4980-4211-9d02-d104959a468e",
"data" {
"appAppleId" : 706*****38,
"bundleId" : "App的Bundle Id标志符",
"bundleVersion" : "20230506165910",
"environment" : "Sandbox",
"signedTransactionInfo" : "eyJhbGc加密的交易信息zV1Q",
"signedRenewalInfo":"eyJhbGciO加密的续费信息giG29hdGA",
"status" : 1
},
"version" : "2.0",
"signedDate" : 1717485836523
}
其中notificationType字段表示通知的具体类型,共有18种可能的情况 :
1、CONSUMPTION_REQUEST - 消费者发起了一个【退款/自动续期订阅】请求
2、DID_CHANGE_RENEWAL_PREF - 结合subtype字段【UPGRADE/DOWNGRADE】决定消费者修改了订阅计划,如果subtype字段为空表示该回至当前状态
3、DID_CHANGE_RENEWAL_STATUS - 结合subtype字段【AUTO_RENEW_ENABLED/AUTO_RENEW_DISABLED】一起决定订阅续期状态变化,如果用户发起了退款请求则App Store也会禁用自动续期
4、DID_FAIL_TO_RENEW - 结合subtype字段【GRACE_PERIOD/空】一起决定服务端是否可以停服务了,如还处在GRACE_PERIOD宽限期内不要停服务,否则可以收回服务了
5、DID_RENEW - 结合subtype字段【BILLING_RECOVERY/空】一起决定服务端是否可以提供服务了,subtype值为BILLING_RECOVERY表示上次过期的订阅自动续期成了,为空表示一个新的自动续期订阅成功了
6、EXPIRED - 结合subtype字段【VOLUNTARY/BILLING_RETRY/PRICE_INCREASE/PRODUCT_NOT_FOR_SALE/空】一起决定订阅过期原因,分别表示用户自主取消/上一个账单自动续期失败/用户不同意涨价/商品不再处于销售状态/其它原因
7、EXTERNAL_PURCHASE_TOKEN - 结合subtype字段【EXTERNAL_PURCHASE_TOKEN】仅启用了外部支付才有此值
8、GRACE_PERIOD_EXPIRED - 宽限期已结束还是无法扣款成功,服务端可以取消服务了
9、OFFER_REDEEMED - 结合subtype字段【INITIAL_BUY/RESUBSCRIBE/UPGRADE/DOWNGRADE/空】一起决定消费者使用了促销优惠或优惠码,分别表示第一次使用优惠码/非首次使用优惠码/用优惠码升级/用优惠码降级/用优惠码再次购买当前已买且有效的服务
10、PRICE_INCREASE - 结合subtype字段【PENDING/ACCEPTED】一起决定消费者是否同意服务涨价,分别表示待处理/接受涨价
11、REFUND - 表明App Store已经成功处理了一笔退款
12、REFUND_DECLINED - 表明App Store拒绝了开发发起的退款请求
13、REFUND_REVERSED - 表明App Store撤销了之前因消费者争议而产生的退款请求,需要继续提供服务
14、RENEWAL_EXTENDED - 表明App Store扩展了某个订阅的续订日期
15、RENEWAL_EXTENSION - 结合subtype字段【SUMMARY/FAILURE】一起决定App Store正尝试调用为所有活动订阅者延长订阅日期
16、REVOKE - 表明家庭共享服务关闭,不可再共享了
17、SUBSCRIBED - 结合subtype字段【INITIAL_BUY/RESUBSCRIBE】一起决定消费者订阅了一个产品,分别表示第一次订阅或通过家庭共享访问/非第一次
18、TEST - 表明App Store发送了一个测试通知,你请求了Test Notification API
第3步:同样按官方提示提取出signedTransactionInfo字段里的交易信息:
{
"transactionId" : "2000000618051216",
"originalTransactionId" : "2000000528520218",
"webOrderLineItemId" : "2000000063257619",
"bundleId" : "App的Bundle Id标志符",
"productId" : "PD11021501",
"subscriptionGroupIdentifier" : "10509057",
"purchaseDate" : 1717485886000,
"originalPurchaseDate" : 1708488949000,
"expiresDate" : 1717486186000,
"quantity" : 1,
"type" : "Auto-Renewable Subscription",
"appAccountToken" : "18fc0cf2-0379-5204-y70e-30ctdey20577", # 自定义UUID格式的数据
"inAppOwnershipType" : "PURCHASED",
"signedDate" : 1717485836502,
"environment" : "Sandbox",
"transactionReason" : "RENEWAL",
"storefront" : "CHN",
"storefrontId" : "143465",
"price" : 68000,
"currency" : "CNY"
}
至此便可以根据signedTransactionInfo里的交易信息进行相关服务的下发了。