目录
1.注册 Google Play 开发者帐号
2.在 Google Play 管理中心启用结算相关功能
3.创建和配置产品
4.代码
可能遇到的问题
1.注册 Google Play 开发者帐号
????????注册需要准备Gmail邮箱、手机号、Visa卡(谷歌开发者账号注册需要支付25美元)。注册地址,请科学上网
2.在 Google Play 管理中心启用结算相关功能
????????设置开发者帐户后,必须发布包含 Google Play 结算库的应用版本。
????????在应用程序?build.gradle 文件添加依赖项
dependencies {
...
...
implementation "com.android.billingclient:billing:4.0.0"
...
...
}
????????在AndroidManifest.xml中添加权限。
<uses-permission android:name="com.android.vending.BILLING" />
3.创建和配置产品
????????后台创建商品的话需要先在后台上传一个带有支付功能的草稿包,确保包名、签名、支付库就可构建APK上传。
? ? ? ? 对于每个产品,您需要提供唯一的产品 ID、标题、描述和定价信息。后台的商品分为一次性消耗和订阅2中类型。
? ? ? ? ?注意产品ID一旦创建之后就不要删除,删除之后就无法再次创建相同的产品ID
4.代码
? ? ? ? 以下代码是一个完整的Google支付类。代码是基于4.0.0版本库。
大致流程:
????????初始化一个BillingClient实例
????????链接GooglePlay
? ? ? ? 获取可购买的产品列表
? ? ? ? 购买产品
? ? ? ? 消耗购买的产品
package com.game.billing;
import android.app.Activity;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
// Google pay
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.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import java.util.ArrayList;
import java.util.List;
public class BillingWrapper implements BillingClientStateListener, SkuDetailsResponseListener, PurchasesUpdatedListener, ConsumeResponseListener {
private static final String LOG_TAG = "BillingWrapper";
private static final int STATE_NULL = 0;
private static final int STATE_QUERY = 1;
private static final int STATE_BUY = 2;
private int state = STATE_NULL;
private BillingClient billingClient;
private boolean isBillingClientConnection;
private List<String> skuList = new ArrayList<>();
private List<SkuDetails> skuDetailsList = null;
private String toPurchaseSkuId = "";
private Activity mActivity = null;
private static BillingWrapper _instance = null;
public static BillingWrapper getInstance() {
if (_instance == null) {
_instance = new BillingWrapper();
}
return _instance;
}
private void log(String msg) {
Log.d(LOG_TAG, msg);
}
public void InitBilling(@NonNull Activity activity) {
mActivity = activity;
billingClient = BillingClient.newBuilder(activity)
.setListener(this)
.enablePendingPurchases()
.build();
state = STATE_NULL;
startConnection();
}
///START链接///
public void startConnection() {
billingClient.startConnection(this);
}
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
isBillingClientConnection = true;
log("The BillingClient is ready.");
if ( state == STATE_QUERY ) {
querySkuDetailsAsync();
} else if ( state == STATE_BUY ) {
launchBillingFlow();
} else {
}
state = STATE_NULL;
} else {
isBillingClientConnection = false;
log(billingResult.getDebugMessage() + " responseCode = " + billingResult.getResponseCode());
}
}
@Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
isBillingClientConnection = false;
}
///END链接///
///START查询///
public void getProductList(String keys) {
skuList.clear();
for (String k : keys.split("_")) {
skuList.add(k);
}
if (!isBillingClientConnection) {
state = STATE_QUERY;
startConnection();
} else {
querySkuDetailsAsync();
}
}
private void querySkuDetailsAsync() {
billingClient.querySkuDetailsAsync(SkuDetailsParams.newBuilder()
.setSkusList(skuList)
.setType(BillingClient.SkuType.INAPP)
.build(), this);
}
@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
skuDetailsList = list;
log("Google billingClient.querySkuDetailsAsync succeed.");
} else {
log("Google billingClient.querySkuDetailsAsync failed. responseCode = " + responseCode);
}
}
///END查询///
///START支付///
public void buyStoreItem(String skuId) {
toPurchaseSkuId = skuId;
if (!isBillingClientConnection) {
state = STATE_BUY;
startConnection();
} else {
launchBillingFlow();
}
log("billingClient.buyStoreItem");
}
private void launchBillingFlow() {
if (toPurchaseSkuId.isEmpty()) {
return;
}
SkuDetails skuDetails = null;
if (skuDetailsList != null) {
for (SkuDetails sku : skuDetailsList) {
if (sku.getSku().equals(toPurchaseSkuId)) {
skuDetails = sku;
break;
}
}
}
if (skuDetails == null) {
return;
}
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
log("try buy: " + skuDetails.toString());
// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(mActivity, billingFlowParams);
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
log("launchBillingFlow successful.");
} else {
log("launchBillingFlow failed. " + billingResult.getDebugMessage());
}
}
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
// To be implemented in a later section.
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
log("onPurchasesUpdated successful.");
if (!purchases.isEmpty()) {
Purchase one = purchases.get(0);
consumeAsync(one);
}
} else {
log("onPurchasesUpdated failed. " + billingResult.getDebugMessage());
}
}
///END支付///
///START消耗///
private void consumeAsync(Purchase purchase) {
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.consumeAsync(consumeParams, this);
}
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
log("onConsumeResponse successful. ");
} else {
log("onConsumeResponse failed. responseCode = " + responseCode + " " + billingResult.getDebugMessage());
}
}
///END消耗///
}
可能遇到的问题
1.支付时提示"无法购买您要买的商品"
? ? ? ? 确保安装版本与后台的版本一致,包含AppVersion,bundleVersion,签名。确保支付的账号在测试人员列表中。同时需要测试人员接受的测试邀请
|