google play 结算集成文档:https://developer.android.google.cn/google/play/billing/integrate?hl=zh-cn
google play 结算是用于应用内的虚拟商品支付(与google pay api是有区别的),发起支付与付款流程有app端完成。
服务端需要提供给app端接口有2个:创建自己系统的订单、app端支付完后验证支付状态并处理购买交易。
支付流程(一次性消耗商品)
1.app 查询google play 后台配置好的商品
2.用户选择商品,app请求服务端生成创建商户订单
3.app端向google play 传入商户订单id并发起支付,用户支付
4.app收到支付成功结果,将相关信息传入服务端
5.服务端请求google api 验证商品交易状态
6.服务端请求google api 消耗订单
1.创建系统订单
商户订单id创建逻辑跟自己系统业务相关,不列具体代码,只要返回订单id给app即可。
app端购买商品时传入商户订单id,使商户系统订单id与google 产生对应关系。
经参考网上相关文章学到,app端可以用以下参数传递商户订单id :
setObfuscatedProfileId(orderId)
2.支付状态并处理购买交易
2.1 验证购买商品状态
2.2 一次消耗商品确认消耗(消耗就相当于是订单确认,如果没有确认google会在3天后自动退款,商品也无法再次购买)
用户在app端支付完后,会返回购买token给app,app将对应参数传给服务端接口,服务端请求google api 查询购买产品(purchases.products.get),判断交易状态并处理自己系统业务,然后请求消耗订单(purchases.products.consume)。
引入sdk
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidpublisher</artifactId>
<version>v3-rev20230406-2.0.0</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>1.3.0</version>
</dependency>
public void checkOrder(String packageName ,String productId,String purchaseToken) throws Exception {
ProductPurchase purchase = get(packageName ,productId,purchaseToken);
//订单状态为(0.已购买1.已取消2.待处理),消费状态(0.尚未消耗1.已消耗)
Integer purchaseState = purchase.getPurchaseState();
Integer consumState = purchase.getConsumptionState();
String purchaseOrderId = purchase.getObfuscatedExternalProfileId();
if(0 != purchaseState){
//未完成支付,返回
return;
}
//处理系统业务
if(0== consumState ){
consume(packageName ,productId,purchaseToken);
}
}
//初始化AndroidPublisher
private AndroidPublisher buildAndroidPublisher(){
try {
List<String> scopes = Lists.newArrayList(AndroidPublisherScopes.ANDROIDPUBLISHER);
InputStream inputStream = this.class.getResourceAsStream("api秘钥json文件");
credentials = GoogleCredentials.fromStream(inputStream).createScoped(scopes);
GsonFactory jsonFactory = GsonFactory.getDefaultInstance();
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
AndroidPublisher publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, requestInitializer).build();
return publisher;
}catch (Exception e){
}
}
public ProductPurchase get(String packageName ,String productId,String purchaseToken) throws Exception{
ProductPurchase purchase = null;
try{
AndroidPublisher publisher = buildAndroidPublisher();
AndroidPublisher.Purchases.Products products = publisher.purchases().products();
AndroidPublisher.Purchases.Products.Get productRequest = products.get(packageName,productId,purchaseToken);
purchase = productRequest.execute();
}catch (Exception ex) {
}
return purchase;
}
@Override
public void consume(String packageName ,String productId,String purchaseToken) throws Exception{
try{
AndroidPublisher publisher = buildAndroidPublisher();
AndroidPublisher.Purchases.Products products = publisher.purchases().products();
AndroidPublisher.Purchases.Products.Consume consumeRequest = products.consume(packageName,productId,purchaseToken);
consumeRequest.execute();
} catch (Exception ex) {
}
}
3.创建服务账号请求api接口密钥
参考 https://blog.csdn.net/qq_37611096/article/details/118030549