谷歌支付

This commit is contained in:
gongduoxiang
2024-08-06 10:28:19 +08:00
parent 403b4c2aa3
commit af6398354c
6 changed files with 332 additions and 107 deletions

View File

@@ -20,7 +20,7 @@ public class CommonHttpConsts {
public static final String DOWNLOAD_GIF = "downloadGif";
public static final String GET_BALANCE = "getBalance";
public static final String CHECK_TOKEN_INVALID = "checkTokenInvalid";
public static final String NOTIFY_GOOGLE = "Charge.google_pay";
public static final String NOTIFY_GOOGLE = "Charge.goole_validate_panduola";
public static final String COMMUNITY_SETREPORT = "Community.setReport";
public static final String GET_USER_HOME = "getUserHome";

View File

@@ -419,13 +419,10 @@ public class CommonHttpUtil {
.execute(callback);
}
public static void notifyGoogle(String purchaseToken, String orderNo, String tradeNo, String allData, String gps_adid, HttpCallback callback) {
public static void notifyGoogle(String purchaseToken, String productId, HttpCallback callback) {
HttpClient.getInstance().get(CommonHttpConsts.NOTIFY_GOOGLE, CommonHttpConsts.NOTIFY_GOOGLE)
.params("purchaseToken", purchaseToken)
.params("orderno", orderNo)
.params("trade_no", tradeNo)
.params("allData", allData)
.params("gps_adid", gps_adid)
.params("productId", productId)
.params("package_name", "com.pandora.sy")
.execute(callback);
}

View File

@@ -0,0 +1,297 @@
package com.yunbao.common.pay.google;
import android.app.Activity;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.QueryProductDetailsParams;
import com.android.billingclient.api.QueryPurchasesParams;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.common.collect.ImmutableList;
import com.yunbao.common.CommonAppContext;
import com.yunbao.common.R;
import com.yunbao.common.http.CommonHttpUtil;
import com.yunbao.common.http.HttpCallback;
import java.util.ArrayList;
import java.util.List;
//谷歌支付
public class GooglePlay implements PurchasesUpdatedListener {
private String TAG = "mLog";
private BillingClient billingClient;
private GoogleBillingListener billingListener;
private GooglePlay() {
init();
}
private boolean init() {
if (getGoogleService() && billingClient == null) {
billingClient = BillingClient.newBuilder(CommonAppContext.sInstance)
.setListener(this)
.enablePendingPurchases()
.build();
startConnection();
return true;
}
if (billingClient != null && !billingClient.isReady()) {//没有连接的话去连接
startConnection();
}
if (billingClient == null)
return false;
return true;
}
private void startConnection() {
if (!billingClient.isReady()) {
//请求连接到GooglePay
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
int code = billingResult.getResponseCode();
if (code != BillingClient.BillingResponseCode.OK) {
String msg = billingResult.getDebugMessage();
Log.e(TAG, "连接到GooglePay失败 code = " + code + " msg = " + msg);
return;
}
Log.e(TAG, "连接到GooglePay成功");
}
//连接失败
@Override
public void onBillingServiceDisconnected() {
Log.e(TAG, "连接到GooglePay失败请重试");
}
});
}
}
//点击商品,先查询商品 然后出来支付界面,调用下单
public void purchase(Activity activity, String orderNumber, String id) {
if (!init()) {
return;
}
ImmutableList<QueryProductDetailsParams.Product> productList = ImmutableList.of(QueryProductDetailsParams.Product.newBuilder()
.setProductId(id)
.setProductType(BillingClient.ProductType.INAPP)
.build());
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(productList)
.build();
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
(billingResult, list) -> {
//查询商品成功
int code = billingResult.getResponseCode();
if (code != BillingClient.BillingResponseCode.OK || list == null || list.isEmpty()) {
String msg = billingResult.getDebugMessage();
Log.e(TAG, "查询商品失败 code = " + code + " msg = " + msg);
return;
}
Log.e(TAG, "查询商品成功");
buyIt(activity, orderNumber, list.get(0));
}
);
}
//开始下单,准备生成订单了
private void buyIt(Activity activity, String orderNumber, ProductDetails productDetails) {
List<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = new ArrayList<>();
productDetailsParamsList.add(BillingFlowParams.ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
// For one-time products, "setOfferToken" method shouldn't be called.
// For subscriptions, to get an offer token, call
// ProductDetails.subscriptionOfferDetails() for a list of offers
// that are available to the user.
//一次性商品不需要传token
// .setOfferToken(selectedOfferToken)
.build());
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.setObfuscatedAccountId(orderNumber)//好像是账号id
.build();
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
int code = billingResult.getResponseCode();
if (code != BillingClient.BillingResponseCode.OK) {
String msg = billingResult.getDebugMessage();
Log.e(TAG, "购买商品失败 code = " + code + " msg = " + msg);
// ToastUtil.show(getString(R.string.pay_suc));
return;
}
Log.e(TAG, "购买商品 " + productDetails.toString());
}
//消耗商品 支付成功之后,调用我们后台下发商品成功之后,调用消耗
public void consume(List<Purchase> list) {
if (!init()) {
return;
}
for (Purchase purchase : list) {
getConsumeGoods(purchase);
}
}
/**
* 消耗所有商品
*/
public void consumeAll() {
if (!init()) {
return;
}
//以下示例展示了如何提取用户的订阅购买交易。请注意queryPurchasesAsync() 仅返回有效订阅和非消耗型一次性购买交易。
QueryPurchasesParams inAppPurchasesQuery = QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build();
billingClient.queryPurchasesAsync(inAppPurchasesQuery, (billingResult, list) -> {
if (BillingClient.BillingResponseCode.OK == billingResult.getResponseCode()) {
for (Purchase purchase : list) {
//0:PurchaseState.UNSPECIFIED_STATE未知状态
//1:PurchaseState.PURCHASED付款完成
//2:PurchaseState.PENDING购买正在等待付款完成。
if (Purchase.PurchaseState.PURCHASED == purchase.getPurchaseState()) {
//调用google去消费
//如果之后还出现谷歌掉单的行为在来处理
CommonHttpUtil.notifyGoogle(purchase.getPurchaseToken(),
purchase.getProducts().get(0), new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
if (code == 0) {
getConsumeGoods(purchase);
}
}
});
}
}
}
});
}
/**
* 公共消费商品接口
*/
private void getConsumeGoods(Purchase purchase) {
if (purchase != null) {
Log.i(TAG, "-----开始消耗商品:" + purchase.toString());
ConsumeParams.Builder consumeParams = ConsumeParams.newBuilder();
consumeParams.setPurchaseToken(purchase.getPurchaseToken());
//调用消耗商品方法
consumeAsync(consumeParams.build(), purchase);
}
}
/**
* 消耗商品
* int SERVICE_TIMEOUT = -3; //服务超时
* int FEATURE_NOT_SUPPORTED = -2; //不支持功能
* int SERVICE_DISCONNECTED = -1; //服务单元已断开
* int OK = 0; //成功
* int USER_CANCELED = 1; //用户按上一步或取消对话框
* int SERVICE_UNAVAILABLE = 2; //网络连接断开
* int BILLING_UNAVAILABLE = 3; //所请求的类型不支持 Google Play 结算服务 AIDL 版本
* int ITEM_UNAVAILABLE = 4; //请求的商品已不再出售。
* int DEVELOPER_ERROR = 5; //提供给 API 的参数无效。此错误也可能说明应用未针对结算服务正确签名或设置,或者在其清单中缺少必要的权限。
* int ERROR = 6; //API 操作期间出现严重错误
* int ITEM_ALREADY_OWNED = 7; //未能购买,因为已经拥有此商品
* int ITEM_NOT_OWNED = 8; //未能消费,因为尚未拥有此商品
*/
private void consumeAsync(ConsumeParams consumeParams, Purchase purchase) {
if (!init()) {
return;
}
billingClient.consumeAsync(consumeParams, (billingResult, purchaseToken) -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.i(TAG, "-----消耗商品成功");
} else {
Log.i(TAG, "-----消耗商品失败" + billingResult.toString() + "---" + purchaseToken + "--code:" + billingResult.getResponseCode());
}
});
}
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
&& purchases != null) {
//支付成功
if (billingListener != null)//消耗掉商品放到外面调用我们服务器成功的时候去消耗 todo 暂时注释掉 这样可以模拟掉单的问题
billingListener.onPaySuccess(purchases);
/*
* 一旦您验证了购买交易,您的应用就可以向用户授予使用权了。若要确认与购买交易相关联的用户账号,
* 您可以使用 Purchases.products:get 返回的 ProductPurchase.obfuscatedExternalAccountId适用于应用内商品的购买交易
* 和 Purchases.subscriptions:get 返回的 SubscriptionPurchase.obfuscatedExternalAccountId适用于服务器端的订阅
* 或者 Purchase.getAccountIdentifiers() 在客户端返回的 obfuscatedAccountId如果在交易时已使用 setObfuscatedAccountId 设置该 ID
* */
// purchases.get(0).getAccountIdentifiers()
for (Purchase purchase : purchases) {
Log.d("mLog", "谷歌支付的回调 " + purchase);
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
//取消支付了
if (billingListener != null)
billingListener.onPayFailed(CommonAppContext.sInstance.getString(R.string.pay_cancel));
} else {
//支付失败
if (billingListener != null)
billingListener.onPayFailed(CommonAppContext.sInstance.getString(R.string.pay_fail));
}
}
/**
* 检测GooglePlay服务是否可用(需要导入包api "com.google.android.gms:play-services-location:11.8.0",也可以不检查,跳过这个代码)
*/
public boolean getGoogleService() {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
if (googleApiAvailability != null) {
int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(CommonAppContext.sInstance);
return resultCode == ConnectionResult.SUCCESS;
}
return false;
}
public String getAdId() {
try {
return AdvertisingIdClient.getAdvertisingIdInfo(CommonAppContext.sInstance).getId();
} catch (Exception e) {
e.printStackTrace();
Log.e("GooglePlay", "获取谷歌的id错误了");
}
return "google_default_id";
}
public void setBillingListener(GoogleBillingListener listener) {
billingListener = listener;
}
/**
* 定义接口返回支付结果
*/
public interface GoogleBillingListener {
void onPaySuccess(List<Purchase> purchases);
void onPayFailed(String msg);
}
public static class GooglePlayHelper {
static GooglePlay googlePlay = new GooglePlay();
}
public static GooglePlay getInstance() {
return GooglePlayHelper.googlePlay;
}
}