Google支付Java服务端订单校验
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-----nMIIE...n-----END PRIVATE KEY-----n", "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.comobot/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.comeference/com/android/billingclient/api/BillingFlowParams.Builder#setobfuscatedaccountid指定时才会出现。 |
obfuscatedExternalProfileId | string 与您应用中的用户个人资料唯一关联的 id 的混淆版本。只有在购买时使用https://developer.android.comeference/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"}