经历了google支付从v1到v5版本,想吐槽想Google后台,变化非常平凡一段时间不上去快不认识了。这次想记录下客户端接入v5支付的流程。
支付流程如下图:
GooglePlayV3以后添加到maven,直接引用就能用
maven {
url 'https://dl.google.com/dl/android/maven2/'
name 'Google'
}
dependencies {
def billing_version = "5.0.0"
implementation "com.android.billingclient:billing:$billing_version"
implementation 'com.google.android.gms:play-services-base:17.1.0'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-identity:17.0.0'
implementation 'com.google.android.gms:play-services-wallet:18.0.0'
implementation 'com.google.android.gms:play-services-games:18.0.1'
implementation "com.google.guava:guava:20.0"
}
具体实现流程如下:
1.先实现google登录
GoogleSignInOptions options =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
GoogleSignInClient mSignInClient = GoogleSignIn.getClient(context, options);
Intent intent = mSignInClient.getSignInIntent();
UnityPlayer.currentActivity.startActivityForResult(intent, SIGN_CODE);
2.连接google play
//准备连接
BillingClient m_BillingClient = BillingClient.newBuilder(mainActivity)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.build();
m_BillingClient.startConnection(billingClientStateListener);
//startConnection callback,连接回调
private BillingClientStateListener billingClientStateListener = new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
int responseCode = billingResult.getResponseCode();
String debugMessage = billingResult.getDebugMessage();
Log.d(TAG, "onBillingSetupFinished: " + responseCode + " " + debugMessage);
if (responseCode == BillingClient.BillingResponseCode.OK) {
m_IsInit = true;
if (m_CallBack != null)
m_CallBack.onCallBack();
}
}
@Override
public void onBillingServiceDisconnected() {
Log.d(TAG, "onBillingServiceDisconnected");
}
};
3.先检查历史支付情况,没有消耗的消耗掉,google只允许一个订单
//查询订阅情况
private void queuePurchasSUBS()
{
try
{
m_BillingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.SUBS)
.build(),
new PurchasesResponseListener() {
public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> list) {
// check billingResult
// process returned purchase list, e.g. display the plans user owns
Log.d(TAG, "queryPurchases: SUBS count :" + list.size());
if (list != null && list.size() > 0)
{
for (int i = 0 ;i<list.size() ;i++)
{
consumePurchase(BillingClient.ProductType.SUBS,list.get(i));
}
}
queuePurchasINAPP();
}
}
);
}catch (Exception e)
{
e.printStackTrace();
if (m_IsStartPay)
{
//ProgressbarUtil.hideLoadingView();
m_IsStartPay = false;
}
}
}
//查询支付订单
private void queuePurchasINAPP()
{
try{
m_BillingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.INAPP)
.build(),
new PurchasesResponseListener() {
public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> list) {
// check billingResult
// process returned purchase list, e.g. display the plans user owns
Log.d(TAG, "queryPurchases: INAPP count :" + list.size());
if (list != null && list.size() > 0)
{
for (int i = 0 ;i<list.size() ;i++)
{
consumePurchase(BillingClient.ProductType.INAPP,list.get(i));
}
}
if (m_CallBack != null)
{
m_CallBack.onCallBack();
m_CallBack = null;
}
}
}
);
}catch (Exception e)
{
e.printStackTrace();
if (m_IsStartPay)
{
//ProgressbarUtil.hideLoadingView();
m_IsStartPay = false;
}
}
}
//订阅和普通支付走不同消耗
private void consumePurchase(final String skuType , final Purchase purchase)
{
Log.d(TAG,"comsumePurchase params : " +skuType );
if (skuType == BillingClient.ProductType.INAPP)
{
Log.d(TAG,"comsumePurchase BillingClient.ProductType.INAPP " );
ConsumeParams consumeParams =
ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
m_BillingClient.consumeAsync(consumeParams, new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
int responseCode = billingResult.getResponseCode();
String debugMessage = billingResult.getDebugMessage();
Log.d(TAG, "onConsumeResponse: " + responseCode + " " + debugMessage);
//消耗完成通知web服务器
toPlatformNotifyOrder(BillingClient.ProductType.INAPP,purchase);
}
}
});
}
if (skuType == BillingClient.ProductType.SUBS)
{
Log.d(TAG,"comsumePurchase BillingClient.ProductType.SUBS " );
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
m_BillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
@Override
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
int responseCode = billingResult.getResponseCode();
String debugMessage = billingResult.getDebugMessage();
Log.d(TAG, "onAcknowledgePurchaseResponse: " + responseCode + " " + debugMessage);
//消耗完成通知web服务器
toPlatformNotifyOrder(BillingClient.ProductType.SUBS,purchase);
}
});
}
}
}
4.处理完历史订单后,正式支付
public void querySkuDetails() {
if (m_CurPayItem == null) return;
Log.d(TAG, "querySkuDetails : " + m_CurPayItem.sku +" " + m_CurPayItem.skuType );
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.of(QueryProductDetailsParams.Product.newBuilder()
.setProductId(m_CurPayItem.sku)
.setProductType(m_CurPayItem.skuType)
.build()))
.build();
//查询支付项
m_BillingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
public void onProductDetailsResponse(BillingResult billingResult,List<ProductDetails> productDetailsList) {
// check billingResult
// process returned productDetailsList
if (productDetailsList.size() > 0)
{
ProductDetails productDetails = productDetailsList.get(0);
Log.i(TAG, "onSkuDetailsResponse: productDetails :" + productDetails.getProductId());
Log.i(TAG, "onSkuDetailsResponse: m_CurPayItem.sku :" + m_CurPayItem.sku);
ImmutableList productDetailsParamsList;
//处理订阅和普通支付查询结果
if (m_CurPayItem.skuType == BillingClient.ProductType.SUBS && productDetails.getSubscriptionOfferDetails() != null)
{
productDetailsParamsList = ImmutableList.of(
BillingFlowParams.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(productDetails.getSubscriptionOfferDetails().get(0).getOfferToken())
.build()
);
}else
{
productDetailsParamsList = ImmutableList.of(
BillingFlowParams.ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
.build()
);
}
//实行支付功能,支付后结果在PurchasesUpdatedListener中
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.setObfuscatedAccountId(m_CurPayItem.orderId)
.build();
BillingResult launchBillingResult = m_BillingClient.launchBillingFlow(mainActivity, billingFlowParams);
Log.d(TAG,"queryProductDetailsAsync BillingResult : " +launchBillingResult.getResponseCode()+" "+ launchBillingResult.getDebugMessage());
}else
{
//ProgressbarUtil.hideLoadingView();
Toast.makeText(UnityPlayer.currentActivity, "購買失敗", Toast.LENGTH_SHORT).show();
}
}
}
);
}
//监听支付回调
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {
if (billingResult == null) {
Log.wtf(TAG, "onPurchasesUpdated: null BillingResult");
return;
}
int responseCode = billingResult.getResponseCode();
String debugMessage = billingResult.getDebugMessage();
Log.i(TAG, "onPurchasesUpdated: $responseCode $debugMessage");
m_IsStartPay = false;
switch (responseCode) {
case BillingClient.BillingResponseCode.OK:
Log.i(TAG, "onPurchasesUpdated: BillingClient.BillingResponseCode.OK ,clear m_CurPayItem size:" + list.size());
Purchase purchase = list.get(0);
String orderid = purchase.getAccountIdentifiers().getObfuscatedAccountId();
Log.d(TAG,"buy success purchase orderid : " + orderid + " " + m_CurPayItem.orderId);
//支付完成消耗产品
consumePurchase(m_CurPayItem.skuType,purchase);
m_CurPayItem = null;
break;
case BillingClient.BillingResponseCode.USER_CANCELED:
Log.i(TAG, "onPurchasesUpdated: User canceled the purchase");
Toast.makeText(UnityPlayer.currentActivity, "用戶取消", Toast.LENGTH_SHORT).show();
break;
case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
Log.i(TAG, "onPurchasesUpdated: The user already owns this item");
break;
case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
Log.e(TAG, "onPurchasesUpdated: Developer error means that Google Play " +
"does not recognize the configuration. If you are just getting started, " +
"make sure you have configured the application correctly in the " +
"Google Play Console. The SKU product ID must match and the APK you " +
"are using must be signed with release keys."
);
break;
}
}
};
以上代码仅为代码,参考文件如下文章来源:https://www.toymoban.com/news/detail-514847.html
https://download.csdn.net/download/gqj108/87218063文章来源地址https://www.toymoban.com/news/detail-514847.html
到了这里,关于记录下GooglePlay V5支付的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!