





















iOS应用内购,那真不是一般的坑。
最近了解了一下iOS和Android的应用内购,也就是在App里进行购买。
一般来说,购买分为两种,一种是一次性的,比如购买金币,这种处理很简单,就不多说了;另外一种就是订阅,也就是每个月或者 每一定周期,就会付费一次,比如VIP会员,这是我们今天的主角。
来看一下常见的流程:

对于订阅来说,很重要的一个环节是处理通知,比如当用户取消、续订、升降级等事件发生时,我们的服务端都会收到一个通知。
对于Google的通知,处理起来很简单,直接获取 expiryTimeMillis 即可知道什么时候过期。
When checking the developer API, you should always do the following:
- If expiryTimeMillis is in the future, always grant entitlement.
- If autoRenewing = false, try to get the user to resignup because the subscription will end at expiry time.
- If paymentState = 0,send the user to the subscriptions center using the subscriptions center deep-link to
fix their payment issue.
其中还包括宽限期,也会体现到
expiryTimeMillis里
Google 的通知坑比较少,我踩到的一个就是,如果没有正确处理通知(返回200),那么Google就会开启无限循环通知,短短几个 小时内,就会收到数万次请求。
Apple的可就坑爹了:
首先 receipt 校验返回的结构特别奇葩:
{
"latest_receipt": "MIIbngYJKoZIhvcNAQcCoIIbj...",
"status": 0,
"receipt": {
"download_id": 0,
"receipt_creation_date_ms": "1486371475000",
"application_version": "2",
"app_item_id": 0,
"receipt_creation_date": "2017-02-06 08:57:55 Etc/GMT",
"original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
"request_date_pst": "2017-02-06 04:41:09 America/Los_Angeles",
"original_application_version": "1.0",
"original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
"request_date_ms": "1486384869996",
"bundle_id": "com.yourcompany.yourapp",
"request_date": "2017-02-06 12:41:09 Etc/GMT",
"original_purchase_date_ms": "1375340400000",
"in_app": [{
"purchase_date_ms": "1486371474000",
"web_order_line_item_id": "1000000034281189",
"original_purchase_date_ms": "1486371475000",
"original_purchase_date": "2017-02-06 08:57:55 Etc/GMT",
"expires_date_pst": "2017-02-06 01:00:54 America/Los_Angeles",
"original_purchase_date_pst": "2017-02-06 00:57:55 America/Los_Angeles",
"purchase_date_pst": "2017-02-06 00:57:54 America/Los_Angeles",
"expires_date_ms": "1486371654000",
"expires_date": "2017-02-06 09:00:54 Etc/GMT",
"original_transaction_id": "1000000271014363",
"purchase_date": "2017-02-06 08:57:54 Etc/GMT",
"quantity": "1",
"is_trial_period": "false",
"product_id": "com.yourcompany.yourapp",
"transaction_id": "1000000271014363"
}],
"version_external_identifier": 0,
"receipt_creation_date_pst": "2017-02-06 00:57:55 America/Los_Angeles",
"adam_id": 0,
"receipt_type": "ProductionSandbox"
},
"latest_receipt_info": [{
"purchase_date_ms": "1486371474000",
"web_order_line_item_id": "1000000034281189",
"original_purchase_date_ms": "1486371475000",
"original_purchase_date": "2017-02-06 08:57:55 Etc/GMT",
"expires_date_pst": "2017-02-06 01:00:54 America/Los_Angeles",
"original_purchase_date_pst": "2017-02-06 00:57:55 America/Los_Angeles",
"purchase_date_pst": "2017-02-06 00:57:54 America/Los_Angeles",
"expires_date_ms": "1486371654000",
"expires_date": "2017-02-06 09:00:54 Etc/GMT",
"original_transaction_id": "1000000271014363",
"purchase_date": "2017-02-06 08:57:54 Etc/GMT",
"quantity": "1",
"is_trial_period": "true",
"product_id": "com.yourcompany.yourapp",
"transaction_id": "1000000271014363"
}, {
"purchase_date_ms": "1486371719000",
"web_order_line_item_id": "1000000034281190",
"original_purchase_date_ms": "1486371720000",
"original_purchase_date": "2017-02-06 09:02:00 Etc/GMT",
"expires_date_pst": "2017-02-06 01:06:59 America/Los_Angeles",
"original_purchase_date_pst": "2017-02-06 01:02:00 America/Los_Angeles",
"purchase_date_pst": "2017-02-06 01:01:59 America/Los_Angeles",
"expires_date_ms": "1486372019000",
"expires_date": "2017-02-06 09:06:59 Etc/GMT",
"original_transaction_id": "1000000271014363",
"purchase_date": "2017-02-06 09:01:59 Etc/GMT",
"quantity": "1",
"is_trial_period": "false",
"product_id": "com.yourcompany.yourapp",
"transaction_id": "1000000271016119"
}],
"environment": "Sandbox"
}
其次字段结构特别坑爹
latest_receipt_info 是一个列表,但是服务端通知中,是一个结构体latest_receipt_info 里,而当过期发生时,通知体现在 latest_expired_receipt_info 里pending_renewal_info 的 grace_period_expires_date_ms 里Apple还有一个坑爹之处是,Sandbox环境特别不稳定
这就是本文想记录的IAP坑爹之处。
参考资料:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。