Google支付Java服务端订单校验 – zhanglei
Google支付Java服务端订单校验
原文链接:https://blog.csdn.net/qq_40193787/article/details/123507578
一、Google Play 结算系统概览
Google Play 结算系统是一项可让您在 Android 应用中销售数字产品和内容的服务。
您可以使用 Google Play 结算系统销售以下类型的数字内容:
一次性商品:一次性商品是指用户可以通过一次性的非定期付费(通过用户的付款方式收取)购买的内容。
一次性商品可以是消耗型商品,也可以是非消耗型商品:
- 消耗型商品是指用户为了获得应用内内容(如游戏代币)而消耗的商品。当用户消耗该商品时,您的应用会分配关联的内容,而用户随后可以
再次购买相应的商品。- 非消耗型商品是指购买一次就能永久使用的商品。示例包括付费升级和关卡包等等。
订阅:订阅是一种让用户定期使用内容的商品。订阅会自动续订,直到被取消。订阅的示例包括在线杂志浏览和音乐在线播放服务等等。
借助 Google Play 管理中心,您可以非常灵活地创建订阅产品。例如,您可以设置结算周期、提供免费试订、提供初次体验价、在付款失败时提供宽限期,以及允许用户暂停订阅来替代取消。如需了解详情以及查看订阅功能的完整列表,请参阅实现订阅专用功能。
摘自:https://developer.android.google.cn/google/play/billing?hl=zh-cn
二、Google Play 主要支付流程
1、客户端根据服务端提供的商品ID列表向谷歌服务器拉取Google Play控制台配置的商品信息,获取商品价格并展示。
2、用户购买商品,客户端调起谷歌支付。
3、支付成功后,Google服务器将支付结果返回给客户端。
4、客户端携带支付结果向服务端发送支付校验请求,校验通过后处理下一步业务
三、Google Play 控制台准备
1、进入Google控制台,选择开发者账号登录
2、进入API权限设置,初始状态是没有的(我这里是已经创建了),直接创建一个新的项目就可以了。
3、给该API服务创建一个服务账号。
4、按照弹窗的提示进行操作。
5、点击创建一个服务账号。
6、写好必填的名称即可直接点击完成。
7、点击进入刚刚创建好的账号(可以复制一下,等等添加权限的时候需要粘贴过去),选择添加密钥。
8、选择Json格式,点击创建,然后保存好生成的Json文件。
9、回到控制台,给刚刚创建好的服务账号添加权限。
10、邀请刚刚添加的服务账户并授权后完成邀请。
11、进入应用的商品页面,重新保存一下商品(修改一下描述信息,然后修改回来即可),不然请求Google服务器进行校验时,会出现401没有用户没有api权限的问题!!!!!!
至此完成了控制台的准备工作。
四、Java 服务端处理
1、maven依赖
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidpublisher</artifactId>
<version>v3-rev24-1.24.1</version>
</dependency>
2、校验代码
/**
* @param packageName 应用程序包名
* @param productId 商品id
* @param purchaseToken 购买令牌
* @return
* @throws IOException
* @throws GeneralSecurityException
*/
public ProductPurchase checkOrder(String packageName, String productId, String purchaseToken) throws IOException, GeneralSecurityException {
GoogleCredentials credentials = GoogleCredentials.fromStream(new ClassPathResource("私钥文件.json").getInputStream())
.createScoped(Sets.newHashSet(AndroidPublisherScopes.ANDROIDPUBLISHER));
AndroidPublisher androidPublisher = new AndroidPublisher.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(),
new HttpCredentialsAdapter(credentials)).build();
//一次性商品
ProductPurchase productPurchase = androidPublisher.purchases().products().get(packageName, productId, purchaseToken).execute();
//订阅
//SubscriptionPurchase subscriptionPurchase = androidPublisher.purchases().subscriptions().get(packageName, productId, purchaseToken).execute();
System.out.println(JsonUtil.toJson(productPurchase));
return productPurchase;
}
3、私钥文件
{
"type": "service_account",
"project_id": "xxx",
"private_key_id": "xxx",
"private_key": "-----BEGIN PRIVATE KEY-----
MIIE...
-----END PRIVATE KEY-----
",
"client_email": "xxx",
"client_id": "xxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/developer%40pc-api-8544243815725524966-996.iam.gserviceaccount.com"
}
4、请求结果
{
"acknowledgementState":0,
"consumptionState":0,
"developerPayload":"",
"kind":"androidpublisher#productPurchase",
"orderId":"GPA.3308-7963-0055-36023",
"purchaseState":0,
"purchaseTimeMillis":1652178403396,
"purchaseType":0,
"regionCode":"US"
}
字段 | |
---|---|
kind |
string 这种表示 androidpublisher 服务中的一个 inappPurchase 对象。 |
purchaseTimeMillis |
string (int64 format) 购买产品的时间,自纪元(1970 年 1 月 1 日)以来的毫秒数。 |
purchaseState |
integer 订单的购买状态。可能的值为: 0. 已购买 1. 已取消 2. 待定 |
consumptionState |
integer inapp产品的消费状态。可能的值为: 0. 尚未消费 1. 已消费 |
developerPayload |
string 开发人员指定的字符串,其中包含有关订单的补充信息。 |
orderId |
string 与购买应用内产品相关的订单 ID。 |
purchaseType |
integer inapp 产品的购买类型。仅当此购买不是使用标准应用内结算流程进行时才设置此字段。可能的值有: 0. 测试(即从许可证测试帐户购买) 1. 促销(即使用促销代码购买) 2. 奖励(即通过观看视频广告而不是付费) |
acknowledgementState |
integer inapp 产品的确认状态。可能的值为: 0. 尚未确认 1. 已确认 |
purchaseToken |
string 为识别此次购买而生成的购买令牌。 |
productId |
string 应用内产品 SKU。 |
quantity |
integer 与购买应用内产品相关的数量。 |
obfuscatedExternalAccountId |
string 与您的应用中的用户帐户唯一关联的 id 的混淆版本。只有在购买时使用https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setobfuscatedaccountid指定时才会出现。 |
obfuscatedExternalProfileId |
string 与您应用中的用户个人资料唯一关联的 id 的混淆版本。只有在购买时使用https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setobfuscatedprofileid指定时才会出现。 |
regionCode |
string 授予产品时用户的 ISO 3166-1 alpha-2 计费区域代码。 |
5、附客户端支付结果
{
"originalJson":"{"orderId":"GPA.3308-7963-0055-36023","packageName":"com.xx","productId":"test_001","purchaseTime":1652087527765,"purchaseState":0,"purchaseToken":"onaneopknaamljbljegbignl.AO-J1OxgUizChLw-Zg7ouBVLEULe8aDYxARV7DAvs6ECkwbcgFI5doEDl7Ks2CXO6JWnyMmrZwZe85Nr6PA_3ycUmWMVqnK6zsdde-6WY0PkIJsn0x0VsWY","quantity":1,"autoRenewing":true,"acknowledged":false}",
"signature":"NCbU1RdAvGsrOow8lW/7x7GL4f7Ks2IbIWEQ1qPQwsapCPpjxx8Xcgyqfz8QD/kaeG+tH5l1PW7vGbObZwzxgglLQP5qmeR23sIq8srX3vAT3SUoCoEy6dYGnPomGSzJqLZOOf7e7QS/9+ivuij/J0Y1fMjpEowm+WY8LLGiHVguqpObg07rJdoMa16DaBU4/dtZUoFD3KVWPSAQRtqU/hzXG+iJ+fPEs2DMMRzTNZ4LR5V/wJEy43527imtUlk9d8vKlf2RZVSa/4pWtfdqQmBHV8b1lY4fut9gPuifUEoFxmYzQV8j6jZKEQSayS+50USecIjNh1o9eSFD1j8q4Au003du003d"
}