Android:inApp购买收据验证google play

Bin*_*ran 71 android in-app-purchase android-pay

我使用谷歌钱包作为我的支付网关,购买产品后谷歌给我一个以下的响应

{ 
 "orderId":"12999763169054705758.1371079406387615", 
 "packageName":"com.example.app",
 "productId":"exampleSku",
 "purchaseTime":1345678900000,
 "purchaseState":0,
 "developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
 "purchaseToken":"rojeslcdyyiapnqcynkjyyjh"
 }
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用Google Play新推出的收据验证.在Google Developer控制台中,我在权限中通过服务帐户制作了证书密钥.但我很困惑如何在从Google Play商店购买产品后使用收据验证.

所以,任何人都可以请帮我该怎么办收货验证InApp采购.

Mar*_*ock 183

Google通过Google Play Developer API提供收据验证,API中有两个您最感兴趣的端点:Purchases.products:getPurchases.subscriptions:get.

Purchases.products: get可用于验证非自动续订产品购买,Purchases.subscriptions: get用于验证和重新验证自动续订产品订阅.

要使用任意端点必须知道packageName,productId,purchaseToken所有的这些都可以在你购买收到的有效载荷中.您还需要access_token通过创建Google API服务帐户来获取该帐户.

要开始使用服务帐户,请先转到Google Play开发者控制台API访问设置页面,然后点击创建新项目按钮:

创建一个新的Google API项目

您现在应该看到一个新的链接项目和一些新的部分,在"服务帐户"部分中,单击"创建服务帐户"按钮.

创建一个新的服务帐户

您将看到一个信息框,其中包含创建服务帐户的说明.单击指向Google Developers Console的链接,将生成一个新选项卡.

打开Goog​​le Developers Console

现在单击"创建新客户端ID",从选项中选择"服务帐户",然后单击"创建客户端ID

创建新的客户端ID

将下载一个JSON文件,这是您将用于交换的JSON Web令牌,access_token以确保其安全.

接下来,将标签切换回Google Play开发者控制台,然后在信息框中点击完成.您应该在列表中看到新的服务帐户.单击服务帐户电子邮件旁边的授予访问权限.

授予访问权限

在"为此用户选择角色"下,选择"财务",然后单击"添加用户".

将角色设置为财务

您现在已经设置了服务帐户,并且具有执行收据验证的所有必要访问权限.接下来是将您的JWT与access_token进行交换.

access_token交易所一小时后到期,你所以需要一些服务器代码来处理这和谷歌已经提供了一些图书馆在许多语言来处理这个(名单并不详尽):

我不会详细介绍,因为有很多关于如何使用这些库的文档,但是我会提到你想要使用https://www.googleapis.com/auth/androidpublisher作为OAuth2作用域,client_email来自JWT作为issuer你可以从private_key和获得的公钥.密码短语notasecret将用于signing_key.

一旦你有了access_token你的好处(至少在下一个小时,你将需要按照上一段中的相同过程请求一个新的).

要检查消耗品(非自动续订)购买的状态,get请向以下地址发出http 请求:https://www.googleapis.com/androidpublisher/v2/applications/com.example.app/purchases/products/exampleSku/tokens/rojeslcdyyiapnqcynkjyyjh?access_token=your_access_token

如果你得到一个200 http响应代码,一切都按计划进行,你的购买是有效的.404将表示您的令牌无效,因此购买很可能是欺诈尝试.401表示您的访问令牌无效,403表示您的服务帐户访问权限不足,请检查您是否在Google Play开发者控制台中为访问帐户启用了财务.

200的响应看起来与此类似:

{
  "kind": "androidpublisher#productPurchase",
  "purchaseTimeMillis": long,
  "purchaseState": integer,
  "consumptionState": integer,
  "developerPayload": string
}
Run Code Online (Sandbox Code Playgroud)

有关每个媒体资源的说明,请参阅https://developers.google.com/android-publisher/api-ref/purchases/products.

订阅类似,但端点如下所示:

https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/subscriptions/subscriptionId/tokens/token?access_token=you_access_token

响应应包含以下属性:

{
  "kind": "androidpublisher#subscriptionPurchase",
  "startTimeMillis": long,
  "expiryTimeMillis": long,
  "autoRenewing": boolean
}
Run Code Online (Sandbox Code Playgroud)

有关属性说明,请参阅https://developers.google.com/android-publisher/api-ref/purchases/subscriptions,并注明startTimeMillisexpiryTimeMillis会根据订阅的持续时间进行更改.

快乐验证!

  • 这是我第一次看到在2天的搜索中实施服务器支付验证的详细指南.竖起大拇指.在某处可以使用现成的服务器代码吗?我觉得很奇怪,我无法在任何地方找到类似的东西 (3认同)
  • @MarcGreenstock 感谢您的详细回答。 (3认同)

Jes*_*run 20

马克的答案很棒.我只想补充一点,Google Play Developer API Client Library for Java可以让您在从服务器连接到Google Play服务器时更加简单.该库自动处理刷新身份验证令牌,并提供类型安全的API,因此您不必使用URL.

以下是设置Publisher单例的方法:

httpTransport = GoogleNetHttpTransport.newTrustedTransport();
jsonFactory = JacksonFactory.getDefaultInstance();      
credential = GoogleCredential.fromStream(getClass().getResourceAsStream("/path/to/your/key.json")).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));
publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential).setApplicationName(APP_NAME).build();
Run Code Online (Sandbox Code Playgroud)

以下代码查询产品购买:

ProductPurchase product = publisher.purchases().products().get(PACKAGE_NAME, sku, token).execute();
Integer purchaseState = product.getPurchaseState();
product.getPurchaseTimeMillis();
product.getConsumptionState();
product.getDeveloperPayload();
Run Code Online (Sandbox Code Playgroud)

您可以类似地查询订阅:

SubscriptionPurchase sub = publisher.purchases().subscriptions().get(PACKAGE_NAME, sku, token).execute();
sub.getAutoRenewing();
sub.getCancelReason();
...
Run Code Online (Sandbox Code Playgroud)

  • 这是 Java 服务器上的代码,还是在调用任意服务器之前在 Android 上执行的代码? (2认同)
  • @jeshurun 感谢您的代码。致其他读者`APP_NAME = APP_PACKAGE_NAME`。 (2认同)
  • 谢谢你!对我来说,我使用了 `new FileInputStream(...`,而不是 `getClass().getResourceAsStream(...`)。 (2认同)

Ank*_*dal 13

我遇到了类似的问题,问题出在我们在谷歌开发者项目中所做的设置。

请参阅create-play-service-credentials进行设置。使用您创建应用内产品时所用的同一主帐户。

确保删除前一个。

链接到 Google 开发者项目 您的 Play 开发者帐户需要链接到 Google 开发者项目。

1a. 打开“设置”>“开发者帐户”菜单并选择“API 访问”

API访问

1b. 选择链接将您的 Play 帐户连接到 Google 开发者项目

选择项目链接

1c. 同意条款与条件

同意条款条件

2. 创建服务帐户 接下来我们需要创建一个服务帐户。这是通过 Google API 控制台完成的。

2a. 选择创建服务帐户

创建服务帐户

2b. 创建服务帐户密钥凭证

服务帐户

2c. 输入服务帐户的详细信息- 有一个“可选”步骤用于授予角色访问权限。确保您授予对当前用户角色的访问权限。

输入服务帐户详细信息

2d. 下载您的 JSON 凭证: json 凭证

3. 授予访问权限

3a. 在 Play 管理中心中,选择授予新创建的服务帐号访问权限

授予访问权限

3b. 授予以下权限:

应用权限

此后等待 48 小时,以允许 Google 传播 API 的所有访问权限。


Woj*_*lik 7

@marc-greenstock 提供了一个很好的答案,但是,使用 Google Play Android Developer API 验证收据非常重要。

如果您在使用此 API 时遇到任何问题,并且授予权限或链接到您的服务帐户之前添加了应用内产品,则需要打开“应用内产品”并执行一些更新。例如,您可以编辑产品描述并保存。您应该立即获得许可。

我花了几个小时思考我做错了什么......