服务端验证Google Pay订单的两种方式
Google Pay主要支付流程:
1.手机端向服务端发起支付,生成预订单,给手机端返回生成的订单号
2.手机端向Google发起支付(传入本地服务器生成的订单号)
3.Google服务器将支付结果返回给手机端(因这边用到的是消耗型的产品,所以购买后必须要通知gp我已经消耗了这次交易)
4.手机端向服务端发送校验请求,校验通过后即可处理订单(服务端重试校验,发货,保证订单正常发货成功)
当客户端支付成功后,客户端将支付订单的token 传给服务端,服务端进行再次校验,服务端校验订单有两种方式:
1.引入google apis 调取Google Api 进行验证
2.直接调用Google 提供的API接口去验证
两种验证方式都需要一些配置和相应参数,下面具体讲解
验证方式 一 : 引入google apis 调取Google Api 进行验证
developer文档地址:https://developers.google.com/identity/protocols/oauth2/service-account?hl=zh-cn#delegatingauthority
1.去Google Play Console 选择设置中的API 权限:https://play.google.com/console/u/0/developers/6365974680746954105/api-access
2.第一次进来没有 Google Play Console Developer,这个时候就需要去Google Cloud Platform 后台创建服务账号.首先去Google Cloud 后台https://console.cloud.google.com/ 搜索:Google Play Console Developer 点击启用即可,然后去创建服务账号:
到这里就把Google Play Console Developer创建好了,最后一步也拿到了对应的json了
3.回到Google Play Console 后台 把刚才创建的Google Play Console Developer的服务账号也加入到用户和权限中
然后将服务账号权限,可以直接给管理员admin permission 也可以给 财务权限:
点击API权限中的 查看Play管理中心权限,可以查看应用权限和账号权限,切记要给与对应Project的permission
4.上面三步Google Play Console Developer的环境配置好了,下面就开始实现服务端订单的校验了,Java服务端处理
首先将google apis 接入到项目:
<project>
<dependencies>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidpublisher</artifactId>
<version>v3-rev20211125-1.32.1</version>
</dependency>
</dependencies>
</project>
校验代码:
@RestController
public class GoogleController {// packageName为应用程序包名、productId商品id、purchaseToken谷歌返回的收据@PostMapping("/")public ProductPurchase checkOrder(@RequestBody GooglePayDto googlePayDto,HttpServletRequest requestDto) throws IOException, GeneralSecurityException {//使用服务帐户Json文件获取Google凭据List<String> scopes = new ArrayList<>();scopes.add(AndroidPublisherScopes.ANDROIDPUBLISHER);ResourceLoader resourceLoader = new DefaultResourceLoader();Resource resource = resourceLoader.getResource("classpath:static/刚下载的json文件,这里放到了static目录下");GoogleCredential credential = GoogleCredential.fromStream(resource.getInputStream()).createScoped(scopes);
// 使用谷歌凭据和收据从谷歌获取购买信息HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();JacksonFactory jsonFactory = new JacksonFactory();AndroidPublisher publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential).setApplicationName("应用程序名").build();AndroidPublisher.Purchases purchases = publisher.purchases();final AndroidPublisher.Purchases.Products.Get request = purchases.products().get(googlePayDto.getPackageName(), googlePayDto.getProductId(),googlePayDto.getPurchaseToken());System.out.println("==============="+request+"================");final ProductPurchase purchase = request.execute();//处理业务Integer purchaseState = purchase.getPurchaseState();if (!GooglePayStatus.PURCHASED.getValue().equals(purchaseState) &&!GoogleConsumptionStatus.YET_TO_BE_CONSUMED.getValue().equals(purchase.getConsumptionState())) {log.info("==========>订单校验【成功】");} else {log.info("==========>订单校验【失败】");}return purchase;}
}
public class GooglePayDto {String packageName;String productId;String purchaseToken;public String getPackageName() {return packageName;}public void setPackageName(String packageName) {this.packageName = packageName;}public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}public String getPurchaseToken() {return purchaseToken;}public void setPurchaseToken(String purchaseToken) {this.purchaseToken = purchaseToken;}
}
最后开始Test:
传入三个参数
packageName:包名
productId:商品id
purchaseToken:支付凭证
运行结果:
验证方式 二 : 使用API接口直接验证,developer文档地址:https://developers.google.com/android-publisher/authorization?hl=zh-cn
整体步骤:
创建api项目这个和登录用的项目不是同一个
开启Google Play Android Developer API
设置oauth同意屏幕(就是拉起开发者授权账号登录时的登录页面)
创建web应用的oauth客户端ID
google play开发者后台,API权限菜单中关联刚刚创建的项目,一个google play账号只需要也只能关联一个api项目就行了,这个项目可以查询关联账号中的所有应用的订单
拉起授权页面,使用google开发者账号给项目授权,得到code
通过code,拿到refreshToken,这个token只有第一次才会返回需要永久储存(这个refreshtoken很重要,需要保存下来),如果弄丢,只有重新创建一个oauth客户端ID,然后重复步骤6,7,拿到新的refreshtoken
刷新refreshToken, 得到accessToken,通过accesstoken就可以去查询订单状态了,这里的accessToken一般只有5分钟左右,5分钟后需要重新用refreshToken换取新的accessToken
详细步骤:setp1:
创建api项目google api console
setp2:开启Google Play Android Developer API
搜索“Google Play Android Developer API”,并开启
setp3:开启OAuth同意屏幕
setp4 : 创建OAuth 客户端ID:
创建页面和创建成功后的修改页面可以获取到clientId和clientSecret:
到这里api项目就已经创建好了
setp5: Google Play 后台关联API项目:
setp6:获取code
地址:https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri={填写的重定向地址}&client_id={创建的clientId}
将上面的{XX}替换成创建api项目时填写的重定向地址,和clientId,然后将连接放到浏览器中打开,就会吊起授权界面,使用你的开发者账号授权登录
请求方式:浏览器中打开 授权,URL会重定向,这个时候可以拿到code:
这里可以看到,重定向地址上有两个参数code和scope,我们只需要code就行了,这里的code是urlencode后的,使用时需要decode
setp7:使用code获取refreshToken 这一步可以用Postman发起一个post请求:
url:https://accounts.google.com/o/oauth2/token
请求方式:post
参数:grant_type=authorization_code
code=获取到的code(需要看看code中是否有%号,如果有需要urldecode)
client_id=创建api项目是的clientId(客户端ID)
client_secret=创建api项目时的clientSecret(客户端密钥)
redirect_uri=创建api项目时的重定向地址
这里就获取到refreshToken了,重点重点重点,refreshToken保存下来,它只会在第一次请求中返回,后续用在发一样的请求不会返回refreshtoken,如果不慎弄丢了,需要去重新创建一个WebClientId ,这里切记哈
如果后续再次调用这个接口结果为:
Step 8:使用refreshToken获取accessToken
地址:https://accounts.google.com/o/oauth2/token
请求方式:post
参数:grant_type=refresh_token
refresh_token=刚刚获取到的refreshToken
client_id=创建api项目是的clientId(客户端ID)
client_secret=创建api项目时的clientSecret(客户端密钥)
setp9:这一步也是最后一步了 就是查询订单状态:
查询订单状态
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}?access_token={access_token}
packageName:app包名,必须是创建登录api项目时,创建android客户端Id使用包名
productId:对应购买商品的商品ID
token:购买成功后Purchase对象的getPurchaseToken()
access_token:上面咋们获取到的accessToken
请求方式:get
返回值解释:
{
"purchaseTimeMillis": "16239806",//购买产品的时间,自纪元(1970 年 1 月 1 日)以来的毫秒数。
"purchaseState": 0,//订单的购买状态。可能的值为:0. 已购买 1. 已取消 2. 待定
"consumptionState": 0,//产品的消费状态。可能的值为: 0. 尚未消耗 1. 已消耗
"developerPayload": "",
"orderId": "GPA.XXXXXXX8",//google订单号 "purchaseType": 0,
"acknowledgementState": 0,
"kind": "androidpublisher#productPurchase",
"obfuscatedExternalAccountId": "SDK2106180944530041",//上面客户支付时的透传字段,google指导是用来存放用户信息的,不能过长,否则客户端不能支付
"obfuscatedExternalProfileId": "",
"regionCode": "HK"
}
其实服务端判断consumptionState就够了,如果是1 已经消费就可以实现后续逻辑了,比如发放金币,开启VIP等。
~~to: Ly
服务端验证Google Pay订单的两种方式相关推荐
- 服务器配置公网ftp服务端(软件和python代码两种方法)
FileZilla Server超详细配置 前言 一.配置教程 1.General settings(常规设置) 2.Passive mode settings(被动传输模式设置) 3.Securit ...
- mysql 停从库_MySQL_通过两种方式增加从库——不停止mysql服务,一般在线增加从库有两种方式 - phpStudy...
通过两种方式增加从库--不停止mysql服务 一般在线增加从库有两种方式,一种是通过mysqldump备份主库,恢复到从库,mysqldump是逻辑备份,数据量大时,备份速度会很慢,锁表的时间也会很长 ...
- java服务端验证谷歌支付Google Pay
翻阅大半个谷歌,对服务器验证账单,讲的少之又少,还TM没有看懂 查阅整个百度,发现几乎所有demo都是用世界上最好的语言php写的,这我 在此坐下记录希望能帮到有需要的人 支付流程 前端支付完成,谷歌 ...
- postman关闭ssl验证_【第5期】springboot:苹果内购服务端验证
苹果内购: 只要你在苹果系统购买APP中虚拟物品(虚拟货币,VIP充值等),必须通过内购方式进行支付,苹果和商家进行三七开 验证模式有两种: Validating Receipts With the ...
- Sign in with Apple(object-c) 从开发者后台到服务端验证
Sign in with Apple 前言 准备工作 开发工作(object-c编写) 基本流程 添加依赖库 创建Apple登录Button 向Apple发起请求 接收Apple的回调 注意: 用户注 ...
- JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践
任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...
- ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)
ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需要将相应的ValidationAttri ...
- javascript调用服务端验证控件
//*******************Ajax 调用验证控件(客户端调用服务器验证控件)******************** Page_ClientValida ...
- go token验证_GitHub - goflyfox/gtoken: 基于gf框架的token插件,通过服务端验证方式实现token认证;...
gtoken 介绍 基于GoFrame框架的token插件,通过服务端验证方式实现token认证:已完全可以支撑线上token认证,通过Redis支持集群模式:使用简单,大家可以放心使用: gtoke ...
最新文章
- 转正答辩提问_电信专业学生党支部预备党员转正答辩
- 深度学习与概率、统计的有趣探讨
- Vue axios 中提交表单数据(含上传文件)
- oracle如何往dg加盘_oracle 在物理机上添加磁盘操作
- solaris linux nfs,solaris 10 nfs服务配置
- 数据:BTC全网算力为134.17 EH/s,新增地址数51.05万
- 白板推导系列Pytorch-朴素贝叶斯
- Obj-C 实现设计模式 -- Adapter
- stata domin
- MIT6.828 Part B: Copy-on-Write Fork
- springcloudGateway重写请求后,serverHttpRequest.mutate().header失效
- KMS验证 错误码ERROR CODE0xC004F074
- 深度学习4:网络优化Network Optimization(基于Python MXNet.Gluon框架)
- 深入浅出WMS之入库流程解析
- 实现textarea不自动换行
- 圆形体癣是什么样子的图片_体癣图片
- 激活函数,优化技术和损失函数
- Google OR-Tools(六) 装箱问题 Bin Packing
- js中的的GO和AO
- Echarts 折线图 渐变色 不堆叠