iOS-内购退款通知处理
1、前言
Apple退款请求,请求退款会有CONSUMPTION_REQUEST通知(notificationType | Apple Developer Documentation),服务端处理:Send Consumption Information | Apple Developer Documentation
Apple要求在收到CONSUMPTION_REQUEST通知后12小时内回复,不处理12小时后默认表示同意退款
退款通知:只支持消耗品和自动续期
A notification type that indicates that the customer initiated a refund request for a consumable in-app purchase or auto-renewable subscription, and the App Store is requesting that you provide consumption data. For more information, see Send Consumption Information
2、通知样式
CONSUMPTION_REQUEST
{ "notificationType": "CONSUMPTION_REQUEST", "notificationUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "version": "2.0", "signedDate": 1.743495457425E12, "data": { "appAppleId": 6.743115016E4, "bundleId": "xxxxx", "bundleVersion": "1", "environment": "Sandbox", "consumptionRequestReason": "UNINTENDED_PURCHASE", "signedTransactionInfo": { "transactionId": "xxxxxx", "originalTransactionId": "xxxxx", "bundleId": "xxxxxxx", "productId": "com.xxxx.xiaohao", "purchaseDate": 1.743495343E12, "originalPurchaseDate": 1.743495343E12, "quantity": 1.0, "type": "Consumable", "inAppOwnershipType": "PURCHASED", "signedDate": 1.743495457407E12, "environment": "Sandbox", "transactionReason": "PURCHASE", "storefront": "CHN", "storefrontId": "143465", "price": 168000.0, "currency": "CNY" }, "signedRenewalInfo": {} } }
REFUND
{ "notificationType": "REFUND", "notificationUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "version": "2.0", "signedDate": 1.743495644753E12, "data": { "appAppleId": 6.743115016E4, "bundleId": "xxxxx", "bundleVersion": "1", "environment": "Sandbox", "signedTransactionInfo": { "transactionId": "xxxx", "originalTransactionId": "xxxx", "bundleId": "xxxxxx", "productId": "com.xxxx.xiaohao", "purchaseDate": 1.743495343E12, "originalPurchaseDate": 1.743495343E12, "quantity": 1.0, "type": "Consumable", "inAppOwnershipType": "PURCHASED", "signedDate": 1.743495644732E12, "revocationReason": 0.0, "revocationDate": 1.743495513E12, "environment": "Sandbox", "transactionReason": "PURCHASE", "storefront": "CHN", "storefrontId": "143465", "price": 168000.0, "currency": "CNY" }, "signedRenewalInfo": {} } }
REFUND_DECLINED
{ "notificationType": "REFUND_DECLINED", "notificationUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "version": "2.0", "signedDate": 1.743496526676E12, "data": { "appAppleId": 6.743115016E4, "bundleId": "xxxxx", "bundleVersion": "1", "environment": "Sandbox", "signedTransactionInfo": { "transactionId": "xxxx", "originalTransactionId": "xxxx", "bundleId": "xxxxx", "productId": "com.xxxx.noxiaohao", "purchaseDate": 1.743496357E12, "originalPurchaseDate": 1.743496357E12, "quantity": 1.0, "type": "Non-Consumable", "inAppOwnershipType": "PURCHASED", "signedDate": 1.743496526664E12, "environment": "Sandbox", "transactionReason": "PURCHASE", "storefront": "CHN", "storefrontId": "143465", "price": 88000.0, "currency": "CNY" }, "signedRenewalInfo": {} } }
3、发送消费信息
URL
PUT https://api.storekit.itunes.apple.com/inApps/v1/transactions/consumption/{transactionId}
沙盒URL
PUT https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/consumption/{transactionId}
Body
ConsumptionRequest
响应代码
Accepted----------------------202
App Store服务器收到了消费信息。
Bad Request------------------400
无效请求。有关更多信息,请参阅错误代码。如果没有错误代码,则请求格式错误
Unauthorized-----------------401
授权标头中的JSON Web令牌(JWT)无效。有关更多信息,请参阅为API请求生成JSON Web令牌。
Not Found---------------------404
未找到交易标识符。
The request exceeded the rate limit.-------------429
内容类型:应用程序/json
Internal Server Error-----500
服务器错误。稍后再试。
4、隐私协议
在Send Consumption InformationAPI中与苹果共享其个人数据之前,您必须获得用户的有效同意。您,开发人员,全权负责获得有效同意,因为您正在与苹果共享您从用户那里收集的数据。
根据适用法律,获得有效同意的要求各不相同,苹果无法就获得有效同意的具体方法为您提供建议。开发人员负责确定具体是否遵守适用法律。如果您的应用程序违反了苹果的指导方针,App Review将与您联系并与您合作,解决任何问题。
5、退款结果通知
退款成功:REFUND
退款失败:REFUND_DECLINED
6、测试
利用Apple StoreKit V2版本-只支持Swift,编写退款客户端API接口相关逻辑申请退款
App Store在测试环境中自动批准或拒绝退款请求。请注意,App Store在测试环境中不会发送退款请求的电子邮件。
测试批准的退款
要设置已批准的退款测试,请在退款申请表上选择任何退款原因,然后提交该表。App Store在测试环境中自动批准退款请求。
如果您在沙盒环境中进行测试,并且您的服务器收到沙盒的App Store Server Notifications V2,它将收到带有REFUND的通知。
测试拒绝退款
要设置退款被拒绝的测试,请按照退款申请表上的以下步骤操作,您的应用程序在沙盒环境中运行:
- 在“问题”下,选择“其他”。
- 在文本框中,输入REJECT。
- 点击请求退款。
App Store在测试环境中自动拒绝退款请求。
7、自测结果
非消耗品、非续期订阅:没有CONSUMPTION_REQUEST,通知:ONE_TIME_CHARGE、REFUND/REFUND_DECLINED
消耗品:有CONSUMPTION_REQUEST,,通知:ONE_TIME_CHARGE、CONSUMPTION_REQUEST、REFUND/REFUND_DECLINED
自动续期:有CONSUMPTION_REQUEST,通知:SUBSCRIBED、CONSUMPTION_REQUEST、DID_CHANGE_RENEWAL_STATUS、REFUND/REFUND_DECLINED、EXPIRED/
测试的时候按照自动续期订阅流程测试,沙盒不区分通知先后次序,沙盒REFUND的通知大概比CONSUMPTION_REQUEST晚2个小时
消耗品、非消耗品,沙盒REFUND的通知大概比CONSUMPTION_REQUEST晚3-5分钟