AppStore服务端通知(订阅/退款回调通知) python 解密苹果回调 apple 苹果支付
appStore 设置支付回调,通常支付回调称为notify
Notify一般会加密携带订单的支付数据,成功与否等,相当于给后端一个比较安全的确认,因为前端即时的反馈数据并不能保证绝对的可靠。 早前在做苹果的应用内支付的时候就对苹果没有回调通知感到很苦恼,因为确认只能自己从服务端向苹果发送验证请求,而且通常是要二次确认才能判断充值是否有效。
这次苹果更新了服务端通知功能,当然是用起来了。
这个功能的使用也是非常简单,苹果的要求有3点:
1. 服务器支持ATS访问
这个其实也就是后台的连接可以支持443( https: ) 方式访问
2. 配置一个用于接收POST消息的 URL
实际上就是提供一个POST接口地址专门用来接收苹果的消息通知 譬如说 举个例子: https://api.shezw.com/notify/appstore
3. 在App Store Connect中配置对应的URL
这个比较简单,打开App Store connect,在 应用 > App信息 > 综合信息 > App Store 服务器通知网址 (URL)
中填入上面的URL就可以了
首先看一下,通知类型:
notification_type
/*
CANCEL
表示Apple客户支持取消了订阅或用户升级了订阅。 cancel_date键包含更改的日期和时间。
DID_CHANGE_RENEWAL_PREF
指示客户对其订购计划进行了更改,该更改在下一次续订时生效。当前有效的计划不受影响。
DID_CHANGE_RENEWAL_STATUS
指示订阅续订状态的更改。在JSON响应中,检查auto_renew_status_change_date_ms以了解上一次状态更新的日期和时间。检查auto_renew_status以了解当前的续订状态。
DID_FAIL_TO_RENEW
表示由于计费问题而无法续订的订阅。检查is_in_billing_retry_period以了解订阅的当前重试状态。如果订阅处于计费宽限期内,请检查grace_period_expires_date以了解新服务的到期日期。
DID_RECOVER
表示成功的自动更新已过期的订阅,而该订阅过去无法更新。检查expires_date,以确定下一个续订日期和时间。
DID_RENEW
表示客户的订阅已成功自动续订了新的交易期。
INITIAL_BUY
在用户最初购买订阅时发生。通过在App Store上对其进行身份验证,可以将Latest_receipt作为令牌存储在服务器上,以随时验证用户的订阅状态。
INTERACTIVE_RENEWAL
指示客户使用您的应用程序界面或在该帐户的“订阅”设置中的App Store上以交互方式续订了订阅。立即提供服务。
PRICE_INCREASE_CONSENT
表示App Store已开始要求客户同意您的应用的订阅价格上涨。在Unified_receipt.Pending_renewal_info对象中,price_consent_status值为0,表示App Store正在征求客户的同意,但尚未收到。除非用户同意新价格,否则订阅不会自动续订。当客户同意提价时,系统将price_consent_status设置为1。使用verifyReceipt检查收货以查看更新的价格同意状态。
REFUND
表示App Store成功退还了一笔交易。 cancel_date_ms包含已退款交易的时间戳。 original_transaction_id和product_id标识原始交易和产品。 cancel_reason包含原因。
RENEWAL (在沙盒中弃用)
表示成功的自动更新已过期的订阅,而该订阅过去无法更新。检查expires_date,以确定下一个续订日期和时间。此通知在沙箱环境中已弃用,计划于2021年3月在生产中弃用。更新现有代码以改为依赖DID_RECOVER通知类型。
REVOKE 撤销
表示用户不再可以通过“家庭共享”获得应用内购买。当购买者禁用产品的家庭共享,购买者(或家庭成员)离开家庭组或购买者要求并收到退款时,StoreKit会发送此通知。您的应用程序还将收到PaymentQueue(_:didRevokeEntitlementsForProductIdentifiers :)调用。有关家庭共享的更多信息,请参阅在应用程序中支持家庭共享。
*/
Python 实现解密apple pay 回调
https://pypi.org/project/app-store-notifications-v2-validator/
AppleRootCA-G3.cer 下载地址 https://www.apple.com/certificateauthority/
是的你没有看错,苹果的解密密钥是公共的。和国内的微信支付宝不同
安装包 pip install app-store-notifications-v2-validator
import app_store_notifications_v2_validator as asn2 request_body = b'{"signedPayload":"eyJh .... "}' apple_root_cert_path = "/tmp/AppleRootCA-G3.cer" try: data = asn2.parse(request_body,apple_root_cert_path) except InvalidTokenError: pass
解密数据
{ "notificationType": "SUBSCRIBED", "subtype": "RESUBSCRIBE", "notificationUUID": "00000000-0000-0000-0000-000000000000", "data": { "bundleId": "com.example.App", "bundleVersion": "1", "environment": "Sandbox", "signedTransactionInfo": { "transactionId": "0000000000000000", "originalTransactionId": "0000000000000000", "webOrderLineItemId": "0000000000000000", "bundleId": "com.example.App", "productId": "com.example.App.pro", "subscriptionGroupIdentifier": "00000000", "purchaseDate": 0000000000000, "originalPurchaseDate": 0000000000000, "expiresDate": 0000000000000, "quantity": 1, "type": "Auto-Renewable Subscription", "inAppOwnershipType": "PURCHASED", "signedDate": 000000000000 }, "signedRenewalInfo": { "originalTransactionId": "0000000000000000", "autoRenewProductId": "com.example.App.pro", "productId": "com.example.App.pro", "autoRenewStatus": 1, "signedDate": 0000000000000 } }, "version": "2.0" }