IAP应用的收据验证
Receipt Verification Service (RVS)允许验证您的应用用户所进行的购买。
RVS概述
下表显示了带有收据验证的购买工作流程。RVS在IAP API完成购买并将购买收据返回给应用后启动。
步骤 | 组件 | 任务 |
---|---|---|
步骤1 | IAP API | IAP API与用户交互以完成购买。IAP API向应用返回购买收据。 |
步骤2 | 应用 | 应用将购买收据转发给应用服务器。 |
步骤3 | 应用服务器 | 应用服务器向RVS服务器发送验证收据请求。 |
步骤4 | RVS服务器 | RVS服务器确认收据是否有效。 |
步骤5 | 应用服务器 | 应用服务器向用户提供内容。 |
上表中的步骤与下图中的标注匹配:

只要是通过亚马逊购买,您还可以使用RVS访问在其他平台(如您的网站)中购买的订阅。以下情景描述了此工作流程:
- 应用用户从您的公司网站上通过亚马逊购买订阅。
- 应用收到所购买订阅的收据
- 为允许访问,应用会向您的服务器发送收据中的信息。最后,服务器通过查询RVS来验证此交易。
设置RVS
RVS提供了两个环境选项,具体取决于应用是处于开发/测试阶段,还是已发布到亚马逊应用商店:
- RVS沙盒: 在开发和测试应用时,请使用RVS沙盒环境验证App Tester测试工具生成的收据。要设置RVS沙盒,请参阅RVS沙盒环境的说明。
- RVS生产服务器: 将应用发布到亚马逊应用商店后,您可以使用Amazon RVS生产服务器。请参阅RVS生产环境的说明。
RVS请求语法
使用RVS来验证在PurchaseResponse
或PurchaseUpdatesResponse
中收到的收据对象。这些响应对象包含表示用户唯一标识符的用户ID值。PurchaseResponse
中的收据包含ReceiptId
,它与用户ID联合用于对购买执行带外服务器端验证。出于安全原因,来自您的服务器的请求需要传递共享密钥以确认您的身份。
这些请求使用以下格式:
<Protocol>//<Server>/<[_RVSSandbox_]>/version/<Operation_version_number>/verifyReceiptId/developer/<Shared_Secret>/user/<UserId>/receiptId/<ReceiptId>
将尖括号中的词语替换为要验证交易的以下值:
- Protocol: 用于与服务器或沙盒通信的协议,如https:。
- Server: 要与之通信的RVS服务器的URL。
- 如果您使用的是RVS沙盒,请使用“localhost:8080”或设置Tomcat的任何位置。
- 如果是RVS生产服务器,则URL为“appstore-sdk.amazon.com”。
- [RVSSandbox]: 如果是RVSSandbox,请使用值“RVSSandbox”。如果是RVS生产服务器,请省略此字段。
- Operation_version_number:
verifyReceiptId
操作的版本号。此版本号独立于IAP版本号。当前verifyReceiptId
版本号为“1.0”。 - Shared_secret: 用于标识发出请求的开发者的共享密钥。可在亚马逊应用商店中您的开发者账户“Shared Key”(共享密钥)页面上找到共享密钥:https://developer.amazon.com/sdk/shared-key.html。对于RVSSandbox,共享密钥可以是任何非空字符串。
- UserId: 代表亚马逊应用商店应用中不同亚马逊客户的ID:
purchaseResponse->userData->userId
。 - ReceiptId: 购买的唯一ID:
purchaseResponse->receipt->receiptId
或purchaseUpdatesResponse->receipts->receipt->receiptId
。
RVS响应语法
RVS提供了RESTful JSON API接口。作为最佳实践,使用JSON解析器类从RVS服务器读取JSON响应。
在发出验证交易的请求后,RVS服务器或沙盒将返回响应代码来指示请求是否成功。如果成功,则返回的JSON响应将包括有关交易的信息。
以下示例显示了一个成功响应:
{
"autoRenewing":false,
"betaProduct":false,
"cancelDate":null,
"freeTrialEndDate":null,
"gracePeriodEndDate":null,
"parentProductId":null,
"productId":"com.amazon.iapsamplev2.gold_medal",
"productType":"CONSUMABLE",
"purchaseDate":1399070221749,
"quantity":1,
"receiptId":"wE1EG1gsEZI9q9UnI5YoZ2OxeoVKPdR5bvPMqyKQq5Y=:1:11",
"renewalDate":null,
"term":null,
"termSku":null,
"testTransaction":true
}
RVS响应代码
Receipt Verification Service将使用以下代码之一进行响应,这些代码指示验证检查的结果:
响应代码 | 描述 |
---|---|
HTTP 200 | 成功: 收据ID、用户ID和共享密钥都是有效的。产品类型是以下项之一: “ENTITLED”、“CONSUMABLE”或“SUBSCRIPTION” |
HTTP 400 | 此receiptId表示的交易无效,或没有找到此receiptId的交易。 |
HTTP 496 | sharedSecret无效 |
HTTP 497 | 用户ID无效 |
HTTP 500 | 出现内部服务器错误 |
成功交易的RVS响应字段
下表列出并描述了成功交易的RVS响应中包含的字段:
字段 | 数据类型 | 描述 |
---|---|---|
autoRenewing |
布尔值 | 表示客户的订阅是否会自动续订。 |
betaProduct |
布尔值 | 指示所购买的产品是否是动态应用测试产品。 |
cancelDate |
长整数 | 取消购买的日期,或订阅到期的日期。如果购买未取消,则此字段为null。 |
freeTrialEndDate |
长整数 | 表示订阅处于免费试用期内。提供订阅免费试用的结束日期,以epoch(毫秒)为单位。如果订阅不在免费试用期内,则此字段为null。 |
gracePeriodEndDate |
长整数 | 表示订阅处于宽限期内。提供订阅宽限期的结束日期,以epoch(毫秒)为单位。如果订阅不在宽限期内,则此字段为null。 |
parentProductId |
字符串 | Null。预留以供将来使用。 |
productId |
字符串 | 您在应用中为此商品定义的SKU。 |
productType |
字符串 | 所购买产品的类型。有效产品类型为CONSUMABLE、SUBSCRIPTION和ENTITLED。 |
purchaseDate |
长整数 | 购买日期,以纪元以后的毫秒数存储。对于订阅商品,purchaseDate 代表首次购买日期,而不是后续续订的购买日期。 |
quantity |
整数 | 购买的数量。始终为null或1。 |
receiptID |
字符串 | 购买的唯一标识符。 |
renewalDate |
长整数 | 需要续订订阅购买的日期。日期以纪元以后的毫秒数存储。 |
term |
字符串 | 订阅IAP将保持有效的持续时间(期限从购买之日开始)。期限由数字和时间段(天、周、月、年)构成,如1周或2个月。 |
termSku |
字符串 | 对应于订阅期的唯一SKU。 |
testTransaction |
布尔值 | 表明此购买是不是作为亚马逊发布和测试过程的一部分进行的。 |
取消日期和续订日期
renewalDate
字段包含自动续订订阅购买下一次需要续订的日期。此字段仅适用于订阅购买。
cancelDate
字段包含订阅购买到期的日期或亚马逊客户服务取消购买的日期。
续订日期和取消日期字段以毫秒为单位存储。可以使用java.util.Date(timeInMillis)
将值转换为日期对象。
消费品或权利购买
在有效的收据中,取消日期和续订日期都包含空值。如果取消日期字段不为null,它将包含亚马逊客户服务取消购买的日期。
订阅购买
在有效的订阅收据中,取消日期为null。如果cancelDate
字段不为null,它将包含订阅到期的日期或亚马逊客户服务取消购买的日期。
renewalDate
字段包含自动续订订阅购买下一次需要续订的日期。如果订阅未设置为自动续订,字段值将为null。
在以下示例中,用户具有已取消的订阅:
- 订阅的有效期为2016年1月1日 – 2016年1月3日。在此收据中,此订阅的purchaseDate设置为01/01/2016,cancelDate设置为03/01/2016。
- 如果此订阅后来在2016年1月4日重新激活,则订阅将具有第二个收据。第二个收据将显示purchaseDate为04/01/2016,cancelDate为null。
RVS沙盒和生产示例
请参阅RVS示例。