Google Play 支付文檔:https://developer.android.com/google/play/billing/integrate
Google Play 支付庫已經(jīng)升級到5.0了,相對之前的版本有不少的變化,現(xiàn)在記錄下!
接入Google Play 流程還是和之前一樣:
1.去Google console 申請開發(fā)者賬號? https://play.google.com/console/??
2.創(chuàng)建項(xiàng)目,上傳APK
3.去Google console項(xiàng)目后臺開始設(shè)置商品:點(diǎn)擊左側(cè)Products---->In-app products(內(nèi)購商品)或者Subscription(訂閱商品)
?4.等Google Pay Console 后臺創(chuàng)建好商品后,客戶端和后端就可以開始集成了:
? 4.1:將 Google Play 結(jié)算庫依賴項(xiàng)添加到應(yīng)用的
dependencies {
val billing_version = "5.0.0"
implementation("com.android.billingclient:billing:$billing_version")
}
4.2:初始化支付SDK(也就是初始化BillingClient):支付過程中BillingClient用的比較多,一般項(xiàng)目中只創(chuàng)建一個(gè)BillingClient
private BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.build();
初始化的時(shí)候需要一個(gè):PurchasesUpdatedListener,PurchasesUpdatedListener是監(jiān)聽?wèi)?yīng)用中所有購買交易的更新,這個(gè)listener非常重要,當(dāng)用戶購買或者訂閱后都會(huì)走這個(gè)回調(diào)
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
// To be implemented in a later section.
}
};
4.3初始化SDK后,需要與 Google Play 建立連接,使用startConnection()方法,startConnection是異步進(jìn)行,這個(gè)時(shí)候需要一個(gè)BillingClientStateListener進(jìn)行回調(diào)連接的結(jié)果,當(dāng)連接完成會(huì)走onBillingSetupFinished()回調(diào),通過返回的billingResult.getResponseCode()去判斷是否真正的鏈接成功,這個(gè)code 有下面幾個(gè)值,這個(gè)BillingClientStateListener還有一個(gè)Google Play 失去連接的回調(diào),這個(gè)時(shí)候我們需要實(shí)現(xiàn)重試邏輯,就是再次調(diào)用startConnection()函數(shù)。
@Retention(RetentionPolicy.SOURCE)
public @interface BillingResponseCode {
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;
int ITEM_UNAVAILABLE = 4;
int DEVELOPER_ERROR = 5;
int ERROR = 6;
int ITEM_ALREADY_OWNED = 7;
int ITEM_NOT_OWNED = 8;
}
public void startConnection() {
mBillingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
queryProductDetailsParams();
queryOldOrder();
}
}
@Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
}
});
}
?4.4 獲取商品
? ? ? 當(dāng)startConnection()回調(diào)成功時(shí),這個(gè)時(shí)候我們就可以根據(jù)ProductId去Google Play獲取具體的商品了,這個(gè)時(shí)候一般會(huì)通過API去自己的Server 獲取一個(gè)ProductIdList,然后根據(jù)后臺返回的productId去Google Play 獲取商品詳情。
查詢內(nèi)購的商品:
List<String> skuList = new ArrayList<>();
skuList.add("ProductId01");
skuList.add("ProductId02");
skuList.add("ProductId03");
skuList.add("ProductId04");
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<SkuDetails> skuDetailsList) {
// Process the result.
Log.i(TAG, "querySkuDetailsAsync 1 onSkuDetailsResponse billingResult.getResponseCode : " + billingResult.getResponseCode() + " skuDetailsList :" + skuDetailsList);
mInAppSkuDetailsHashMap.clear();
if (skuDetailsList != null && skuDetailsList.size() > 0) {
for (SkuDetails skuDetails : skuDetailsList) {
mInAppSkuDetailsHashMap.put(skuDetails.getSku(), skuDetails);
}
}
}
});
查詢訂閱的商品:
// The BillingClient is ready. You can query purchases here.
List<String> subscribeSkuList = new ArrayList<>();
subscribeSkuList.add("Subscribe01");
subscribeSkuList.add("Subscribe01");
subscribeSkuList.add("Subscribe01");
SkuDetailsParams.Builder subscribeParams = SkuDetailsParams.newBuilder();
subscribeParams.setSkusList(subscribeSkuList).setType(BillingClient.SkuType.SUBS);
mBillingClient.querySkuDetailsAsync(subscribeParams.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
// Process the result.
Log.i(TAG, "querySkuDetailsAsync 2 onSkuDetailsResponse billingResult.getResponseCode : " + billingResult.getResponseCode() + " skuDetailsList :" + skuDetailsList);
mSubscribeSkuDetailsHashMap.clear();
if (skuDetailsList != null && skuDetailsList.size() > 0) {
for (SkuDetails skuDetails : skuDetailsList) {
mSubscribeSkuDetailsHashMap.put(skuDetails.getSku(), skuDetails);
}
}
}
});
當(dāng)商品查詢成功后就可以結(jié)合Server返回的商品信息給用戶展示商品列表了
注意:有些 Android 設(shè)備安裝的可能是舊版 Google Play 商店應(yīng)用,不支持訂閱等某些商品類型。在您的應(yīng)用進(jìn)入結(jié)算流程之前,您可以調(diào)用?isFeatureSupported()?以確定設(shè)備是否支持您要銷售的商品。如需查看可支持的商品類型的列表,請參閱?BillingClient.FeatureType。
4.5.啟動(dòng)購買流程(開始購買)
? ?當(dāng)用戶點(diǎn)擊某個(gè)商品時(shí),從應(yīng)用發(fā)起購買請求,請從應(yīng)用的主線程調(diào)用?launchBillingFlow()?方法。此方法接受對?BillingFlowParams?對象的引用,該對象包含通過調(diào)用?queryProductDetailsAsync()?獲取的相關(guān)?ProductDetails?對象。如需創(chuàng)建?BillingFlowParams
?對象,請使用?BillingFlowParams.Builder?類。
購買內(nèi)購的商品:
public void buyInAppProduct(SkuDetails skuDetails) {
if (skuDetails == null) {
return;
}
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
mBillingClient.launchBillingFlow(ActivityUtils.getTopActivity(), billingFlowParams).getResponseCode();
}
購買訂閱的商品:
public void buySubscribeProduct(SkuDetails skuDetails) {
if (skuDetails == null) {
return;
}
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
mBillingClient.launchBillingFlow(ActivityUtils.getTopActivity(), billingFlowParams).getResponseCode();
}
// An activity reference from which the billing flow will be launched.
Activity activity = ...;
ImmutableList productDetailsParamsList =
ImmutableList.of(
ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
// to get an offer token, call ProductDetails.getSubscriptionOfferDetails()
// for a list of offers that are available to the user
.setOfferToken(selectedOfferToken)
.build()
);
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.build();
// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
4.6購買成功的回調(diào)
?在咱們4.2初始化SDK的時(shí)候添加了一個(gè)PurchasesUpdatedListener,當(dāng)用戶購買成功后Google Play 會(huì)調(diào)用?onPurchasesUpdated(),我們根據(jù)
responseCode去區(qū)分用戶購買成功與否.
如果成功購買商品,系統(tǒng)還會(huì)生成一個(gè)token,它是一個(gè)唯一標(biāo)識符,表示用戶及其所購應(yīng)用內(nèi)商品的商品 ID??梢栽诒镜卮鎯?chǔ)token,可以將令牌傳遞到安全的后端服務(wù)器(推薦用該方法)
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
if (billingResult == null) {
return;
}
int responseCode = billingResult.getResponseCode();
switch (responseCode) {
case BillingClient.BillingResponseCode.OK:
for (Purchase purchase : purchases) {
SkuDetails skuDetails = null;
String json = purchase.getOriginalJson();
if (!TextUtils.isEmpty(json)) {
PurchaseData purchaseData = GsonConverter.fromJson(json, PurchaseData.class);
if (purchaseData != null) {
skuDetails = getSkuDetailsDependProductId(purchaseData.getProductId());
}
}
handlePurchase(purchase, (skuDetails != null && (BillingClient.SkuType.SUBS.equals(skuDetails.getType()))), "onPurchasesUpdated");
}
break;
case BillingClient.BillingResponseCode.USER_CANCELED:
Log.i(TAG, "purchasesUpdatedListener 3 user cancel ");
break;
default:
Log.i(TAG, "purchasesUpdatedListener 4 error " + responseCode);
break;
}
}
};
@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
if (billingResult.getResponseCode() == BillingResponseCode.OK
&& purchases != null) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
} else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
} else {
// Handle any other error codes.
}
}
4.7.處理購買交易(消費(fèi)訂單)
當(dāng)用戶購買成功后,訂單必須消費(fèi),如果不消費(fèi),三天后Google會(huì)自動(dòng)退款,撤銷購買交易。
消費(fèi)內(nèi)購的商品:
void handlePurchase(Purchase purchase) {
// Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener.
Purchase purchase = ...;
// Verify the purchase.
// Ensure entitlement was not already granted for this purchaseToken.
// Grant entitlement to the user.
ConsumeParams consumeParams =
ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
ConsumeResponseListener listener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
// Handle the success of the consume operation.
}
}
};
billingClient.consumeAsync(consumeParams, listener);
}
? 消費(fèi)訂閱商品:訂閱的處理方式與非消耗型商品類似。您可以使用 Google Play 結(jié)算庫中的?BillingClient.acknowledgePurchase()?或 Google Play Developer API 中的?Purchases.Subscriptions.Acknowledge?確認(rèn)訂閱。所有初始訂閱購買交易都需要確認(rèn)。訂閱續(xù)訂不需要確認(rèn)
BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...
void handlePurchase(Purchase purchase) {
if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
}
}
}
4.8 查詢歷史訂單,消費(fèi)待處理的交易
public void queryOldOrder() {
mBillingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull List<Purchase> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
onHandlerQueryPurchases(list, false);
}
}
});
mBillingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull List<Purchase> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
onHandlerQueryPurchases(list, true);
}
}
});
4.9?處理多件購買交易:
Google Play 允許客戶在一筆交易中購買多件相同的應(yīng)用內(nèi)商品,只需在購物車中指定商品數(shù)量即可(4.0 及更高版本的 Google Play 結(jié)算庫支持該功能)。應(yīng)用應(yīng)根據(jù)指定購買數(shù)量來處理多件購買并授予權(quán)利。注意:多件購買適用于消耗型應(yīng)用內(nèi)商品,即可以購買、消耗及再次購買的產(chǎn)品。請勿為不支持重復(fù)購買的商品啟用該功能。
為了實(shí)現(xiàn)多件購買,應(yīng)用的配置邏輯需要檢查商品數(shù)量??梢詮囊韵?API 訪問?quantity
?字段:
- Google Play 結(jié)算庫中的?getQuantity()。
- Google Play Developer API 中的?Purchases.products.quantity。
添加用于處理多件購買的邏輯后,需要在 Google Play 管理中心的應(yīng)用內(nèi)商品管理頁面上為相應(yīng)的商品啟用多件購買功能。文章來源:http://www.zghlxwxcb.cn/news/detail-490681.html
注意:請確保應(yīng)用接受多件購買,然后再在 Play 管理中心啟用該功能。您能需要強(qiáng)制更新到提供支持的應(yīng)用版本,然后才能對商品啟用該功能。文章來源地址http://www.zghlxwxcb.cn/news/detail-490681.html
到了這里,關(guān)于安卓集成Google Play支付(谷歌支付)最新版本的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!