本文介绍了如何将 Google Play 结算库集成到您的应用中以开始销售商品
1、添加 Google Play 结算库依赖项
将以下行添加到build.gradle您应用的文件的“依赖项”部分:
dependencies {
…
implementation ‘com.android.billingclient:billing:4.0.0’
}
新建GooglePay.java文件
2.初始化
/**
* 初始化BillingClient
*/
public void initBillingClient(){
mBillingClient = BillingClient.newBuilder(mInstance)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.build();
startConnection();
}
3.google Play 建立连接
private void startConnection() {
mBillingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
//链接成功最好去查询订单,做掉单处理
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
s_isConnectGooglePlay = true;
querySkuDetailsAsync();
queryPurchases();
}
}
@Override
public void onBillingServiceDisconnected() {
s_isConnectGooglePlay = false;
}
});
}
/**
* 查询应用内商品详细信息 并且返回给客户端显示价格
*/
public void querySkuDetailsAsync() {
if(mProductArray == null) {
Log.e(“GooglePay”, “initSkuList: can not find mProductArray”);
return;
}
List skuList = new ArrayList<> ();
try {
JSONArray jsonArray = new JSONArray(mProductArray);
for (int i = 0; i < jsonArray.length(); ++i) {
skuList.add(jsonArray.getString(i));
}
}
catch (Exception e){
Log.e(“GooglePay”, “can not get shop list”);
}
// s_Map_skuList.clear();
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult,List skuDetailsList) {
// Process the result.
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_DISCONNECTED) {
//未连接
s_isConnectGooglePlay = false;
return;
}
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
if (skuDetailsList != null)
{
JSONArray array =new JSONArray();
for (SkuDetails skuD : skuDetailsList)
{
//s_Map_skuList.put(skuD.getSku(), skuD);
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put(“name”, skuD.getSku());
jsonObject.put(“prize”, skuD.getPrice());
array.put(jsonObject);
}
catch (Exception e) {
Log.e(“GooglePay”, “get shop list fail”);
}
}
}
}
}
});
}
/**
* 购买商品
*/
private void BuyPurchase() {
//先展示商品
if(mProductId==null){
Log.d(“google pay”,“mProductId is null”);
return;
}
List skuList = new ArrayList<>();
skuList.add(mProductId);
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);//INAPP应用内支付
mBillingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List skuDetailsList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
for (SkuDetails skuDetails : skuDetailsList) {
String sku = skuDetails.getSku();//商品id
if (mProductId.equals(sku)) {
//启动购买
BillingFlowParams purchaseParams =
BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
mBillingClient.launchBillingFlow(mInstance, purchaseParams);
//购买状态将在PurchasesUpdatedListener.onPurchasesUpdated返回
}
}
}
}
});
}
/**
* 商品查询,商品购买,商品回调,商品验证以及回调方法
*/
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List purchases) {
//交易更新将会在这里回调
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (Purchase purchase : purchases) {
String googlePayOrderId = purchase.getOrderId();
String purchaseToken = purchase.getPurchaseToken();
//服务器验证
verifyPayment(mUserName, mProductId, purchaseToken);
}
} else if (responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
Log.d(“google pay cancel”,“cancel”);
//取消支付
} else if (responseCode == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
//已存在这个未完成订单,查询订单验证然后消耗掉
Log.d(“mBillingClient”,“ITEM_ALREADY_OWNED”);
queryPurchases();
} else {
Log.d(“google pay errror”,“error”);
//还有很多其他状态,判断进行相应处理
}
}
};
/**
* 验证支付,需要后端处理 后端验证返回客户端,验证成功将消耗商品
* @param userName 用户昵称
* @param productId 商品id
* @param purchaseToken 商品token
* 成功返回:
*
* 失败返回:{“status”:“err”}
*/
private void verifyPayment(final String userName,final String productId,final String purchaseToken) {
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void… voids) {
String url = mServerUrl + “xxxxxxxxxxxxx”;
String postData = “uname=” + URLEncoder.encode(userName) + “&token=” + purchaseToken + “&productId=” +productId;
String result = HttpHelper.getInstance().HttpPos(url, postData);
return result;
}
@Override
protected void onPostExecute(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
String status = jsonObject.getString(“status”);
Log.d(“jsonObject”,jsonObject.toString());
if (status.equals(“succeed”)) {//成功
//int repeat = jsonObject.getInt(“repeat”);
consume(purchaseToken);
}
else{ //失败
}
} catch (Exception e) {
Log.e("GooglePay", "verifyOrder Exception" + e.getMessage());
}
}
};
task.execute();
}
/**
* 补单处理
* 查询购买交易,以确保所有购买交易都得到成功处理,如购买未发货,或者未消耗 补单
*/
private void queryPurchases() {
if (mBillingClient != null && mBillingClient.isReady()) {
Purchase.PurchasesResult result = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
List<Purchase> purchasesList = result.getPurchasesList();
if (purchasesList != null) {
for (int i = 0; i < purchasesList.size(); i++) {
if (purchasesList.get(i).isAcknowledged()) {
//已确认/已验证,消耗即可
consume(purchasesList.get(i).getPurchaseToken());
} else {
//TODO 因google支付新版没有透传字段,所以我们的订单号需要手动关联,
// 数据库查询gp订单对应的我方订单号或者服务端进行订单关联
Purchase purchase = purchasesList.get(i);
ArrayList sku = purchase.getSkus();//谷歌的商品id
String purchaseToken = purchase.getPurchaseToken();
verifyPayment(mUserName,ArrayList2String(sku), purchaseToken);
}
}
}
}
}
/**
* ArrayList类型转成String类型
* @param arrayList
* @return
*/
public String ArrayList2String(ArrayList<String> arrayList) {
String result = "";
if (arrayList != null && arrayList.size() > 0) {
for (String item : arrayList) {
result += item + ",";
}
result = result.substring(0, result.length() - 1);
}
return result;
}
/**
* 消耗商品
* @param purchaseToken 商品token
*/
private void consume(String purchaseToken) {
if (mBillingClient != null && mBillingClient.isReady()) {
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchaseToken)
.build();
ConsumeResponseListener listener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// Handle the success of the consume operation.
}
}
};
mBillingClient.consumeAsync(consumeParams, listener);
}
}