android同胞我相信很多人跟我一樣谷歌支付運(yùn)行自己的app的時(shí)候調(diào)用支付發(fā)現(xiàn)都是出現(xiàn)一個(gè)問(wèn)題簽名不同我們今天就來(lái)解決這個(gè)問(wèn)題
先正常導(dǎo)入接入流程后面會(huì)提到問(wèn)題的解決
1、導(dǎo)入依賴(lài)
//谷歌支付
def billing_version = "5.0.0"
implementation "com.android.billingclient:billing-ktx:$billing_version"
2、清淡文件添加權(quán)限
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="com.farsitel.bazaar.permission.PAY_THROUGH_BAZAAR" />
3、代碼接入kotlin的代碼是在activity里面寫(xiě)
companion object {
private val billProxy = GoogleBillHelper()
private var billingListenerImpl: GoogleBillingListenerImpl? = null
}
//初始化
billingListenerImpl = GoogleBillingListenerImpl(this)
//建立連接
GoogleBillingManager.getInstance().createClient(this)
//調(diào)用方法
onClickGooglePlay()
/**
* 點(diǎn)擊購(gòu)買(mǎi)
* 換起Google 支付面前 ,需要查詢(xún)是否有對(duì)應(yīng)的APP商品
* @param view
*/
private fun onClickGooglePlay() {
billProxy
.onQuerySkuDetailsAsync(
billingListenerImpl,
BillingClient.ProductType.INAPP,
"fzvip_weak")
}
//事件監(jiān)聽(tīng)
private class GoogleBillingListenerImpl(private val activity: Activity) : GoogleBillingListener {
/**
* 產(chǎn)品查詢(xún)成功
*
* @param list
*/
override fun onProductDetailsSus(list: List<ProductDetails>) {
if (null == list || list.size <= 0) {
Log.e("TAG", "沒(méi)有查詢(xún)到相關(guān)產(chǎn)品~~~~")
return
}
//查詢(xún)方法中只傳了一個(gè)商品,所以直接取第一個(gè)了
//根據(jù)實(shí)際情況處理~
Log.e(TAG, "onProductDetailsSus: " )
list.forEach {
Log.e(TAG, "onProductDetailsSus: "+it )
billProxy.onOpenGooglePlay(this, activity, it)
}
}
/**
* 購(gòu)買(mǎi)監(jiān)聽(tīng)
*
* @param result
* @param purchases
*/
override fun onPurchasesUpdated(result: BillingResult?, purchases: MutableList<Purchase>?) {
Log.e(TAG, "onPurchasesUpdated: "+result?.responseCode )
Log.e(TAG, "onPurchasesUpdated: "+result?.debugMessage )
if (null == purchases || purchases.size == 0) {
return
}
//循環(huán)調(diào)用消耗
for (purchase in purchases) {
billProxy.onConsumeAsync(this, purchase)
}
}
/**
* 消費(fèi)監(jiān)聽(tīng)
* @param purchaseToken
*/
override fun onConsumeSus(purchaseToken: String) {
Log.e("TAG", "消費(fèi)結(jié)束,處理自己的業(yè)務(wù)邏輯~~~")
//去與后臺(tái)驗(yàn)證。處理APP的頁(yè)面邏輯, 比如充值后發(fā)放金幣啥的~~~
}
}
override fun onDestroy() {
super.onDestroy()
//結(jié)束連接
GoogleBillingManager.getInstance().endConn()
}
4、支付的類(lèi)和接口直接用就可以
1、第一個(gè)類(lèi)
/**
* @author by JHY
* Date: 2023/4/20 15:40
* Desc:支付的具體操作
* 1.查詢(xún)
* 2.購(gòu)買(mǎi)
* 3.消費(fèi)
*/
public class GoogleBillHelper {
public static final String TAG = GoogleBillHelper.class.getSimpleName();
/**
* 查詢(xún)商品詳情
*
* @param billingListener : 接口監(jiān)聽(tīng)
* @param productIds :商品id 。對(duì)應(yīng)Google 后臺(tái)的
* @param productType :取值
* BillingClient.ProductType.INAPP(一次性商品)
* BillingClient.ProductType.SUBS(訂閱)
*/
public void onQuerySkuDetailsAsync(GoogleBillingListener billingListener, String productType, String... productIds) {
if (null == productIds || productIds.length == 0
|| !GoogleBillingManager.getInstance().isReady()
) {
return;
}
List<QueryProductDetailsParams.Product> skuList = new ArrayList<>();
for (String productId : productIds) {
QueryProductDetailsParams.Product product = QueryProductDetailsParams
.Product.newBuilder()
.setProductId(productId)
.setProductType(productType)
.build();
//添加對(duì)應(yīng)的 產(chǎn)品id 去查詢(xún)?cè)斍? skuList.add(product);
}
QueryProductDetailsParams params = QueryProductDetailsParams
.newBuilder()
.setProductList(skuList)
.build();
GoogleBillingManager.getInstance().getBillingClient().queryProductDetailsAsync(params, (billingResult, list) -> {
if (BillingClient.BillingResponseCode.OK == billingResult.getResponseCode()) {
if (null != billingListener) {
billingListener.onProductDetailsSus(list);
}
} else {
Log.e("TAG", "code : " + billingResult.getResponseCode() + " message : " + billingResult.getDebugMessage());
}
});
}
/**
* 打開(kāi)支付面板
*
* @param billingListener
* @param activity
* @param details
*/
public void onOpenGooglePlay(GoogleBillingListener billingListener, Activity activity, ProductDetails details) {
Log.e(TAG, "onOpenGooglePlay: ");
if (null == details) {
return;
}
List<BillingFlowParams.ProductDetailsParams> params = new ArrayList<>();
//根據(jù)自己的判斷是否是連續(xù)包月還是一次性消費(fèi)連續(xù)包月需要添加setOfferToken不加不能調(diào)谷歌支付面板
//就是一次性商品是一個(gè)商品連續(xù)包月的話里面有優(yōu)惠卷
if (details.getProductId().equals("fzvip_android_succession_quarter")) {
//添加購(gòu)買(mǎi)數(shù)據(jù)
BillingFlowParams.ProductDetailsParams productDetailsParams = BillingFlowParams.ProductDetailsParams
.newBuilder()
.setProductDetails(details)
.setOfferToken(details.getSubscriptionOfferDetails().get(0).getOfferToken())
.build();
params.add(productDetailsParams);
} else {
BillingFlowParams.ProductDetailsParams productDetailsParams = BillingFlowParams.ProductDetailsParams
.newBuilder()
.setProductDetails(details)
.build();
params.add(productDetailsParams);
}
SharedPreferences mProductId = activity.getSharedPreferences("ProductId", Context.MODE_PRIVATE);
String mProductId1 = mProductId.getString("mProductId", "");
//
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(params)
.setObfuscatedAccountId(mProductId1)//Uid
.build();
//響應(yīng)code 碼
int responseCode = GoogleBillingManager.getInstance().getBillingClient().launchBillingFlow(activity, billingFlowParams).getResponseCode();
Log.e(TAG, "onOpenGooglePlay: " + responseCode);
//成功換起
if (BillingClient.BillingResponseCode.OK == responseCode) {
//添加購(gòu)買(mǎi)監(jiān)聽(tīng)
GoogleBillingManager.getInstance().setBillingListener(billingListener);
}
}
/**
* 消費(fèi)商品
* 對(duì)于購(gòu)買(mǎi)類(lèi)型的商品需要手動(dòng)調(diào)用一次消費(fèi)方法 (目的:用戶可以再次購(gòu)買(mǎi)此商品)
*
* @param billingListener
* @param purchase
*/
public void onConsumeAsync(GoogleBillingListener billingListener, Purchase purchase, Activity activity) {
QMUITipDialog tipDialog = new QMUITipDialog.Builder(activity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("正在加載")
.create();
tipDialog.show();
if (!GoogleBillingManager.getInstance().isReady()) {
return;
}
ConsumeParams consumeParams =
ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
ConsumeResponseListener listener = (billingResult, purchaseToken) -> {
if (billingResult.getResponseCode() == 5 && BillingClient.BillingResponseCode.OK == 0) {
//連續(xù)訂閱
if (null != billingListener) {
tipDialog.dismiss();
billingListener.onConsumeSus(purchaseToken);
} else {
tipDialog.dismiss();
Log.e(TAG, "消費(fèi)失敗 code : " + billingResult.getResponseCode() + " message : " + billingResult.getDebugMessage());
}
}
//一次性消費(fèi)
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
if (null != billingListener) {
tipDialog.dismiss();
billingListener.onConsumeSus(purchaseToken);
} else {
tipDialog.dismiss();
Log.e(TAG, "消費(fèi)失敗 code : " + billingResult.getResponseCode() + " message : " + billingResult.getDebugMessage());
}
}
};
GoogleBillingManager.getInstance().getBillingClient().consumeAsync(consumeParams, listener);
}
}
2、第二個(gè)類(lèi)
/**
* @author by JHY
* Date: 2023/4/20 15:40
* Desc:Google 支付管理
*/
public class GoogleBillingManager {
private static GoogleBillingManager instance;
private BillingClient billingClient;
private GoogleBillingListener billingListener;
private GoogleBillingManager() {
}
public static GoogleBillingManager getInstance() {
if (instance == null) {
synchronized (GoogleBillingManager.class) {
if (instance == null) {
instance = new GoogleBillingManager();
}
}
}
return instance;
}
/**
* 創(chuàng)建支付客戶端
*/
public void createClient(Context context) {
if (null == context) {
return;
}
billingClient = BillingClient.newBuilder(context.getApplicationContext())
.enablePendingPurchases()
.setListener(new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
if (null != billingListener) {
billingListener.onPurchasesUpdated(billingResult, purchases);
}
}
})
.build();
//啟動(dòng)支付連接
startConn();
}
public BillingClient getBillingClient() {
return billingClient;
}
/**
* 添加監(jiān)聽(tīng)事件
*/
public void setBillingListener(GoogleBillingListener billingListener) {
this.billingListener = billingListener;
}
/**
* 是否準(zhǔn)備好了
*
* @return
*/
public boolean isReady() {
return !(null == billingClient || !billingClient.isReady());
}
/**
* 啟動(dòng)連接
*/
private void startConn() {
if (isReady()) {
return;
}
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.e("TAG", "連接成功,可以開(kāi)始操作了~~~");
}
}
@Override
public void onBillingServiceDisconnected() {
//連接失敗。 可以嘗試調(diào)用 startConnection 重新建立連接
Log.e("TAG", "連接失敗");
}
});
}
/**
* 結(jié)束連接
*/
public void endConn() {
if (null != billingClient) {
billingClient.endConnection();
}
}
}
3、接口
/**
* @author by JHY
* Date: 2023/4/20 15:40
* Desc:監(jiān)聽(tīng)
*/
public interface GoogleBillingListener {
/**
* 購(gòu)買(mǎi)監(jiān)聽(tīng)
*
* @param result
* @param purchases
*/
void onPurchasesUpdated(BillingResult result, List<Purchase> purchases);
/**
* 查詢(xún)商品詳情成功
*
* @param list
*/
void onProductDetailsSus(List<ProductDetails> list);
/**
* 商品消費(fèi)成功
*
* @param purchaseToken
*/
void onConsumeSus(String purchaseToken);
}
重點(diǎn)總結(jié):這些東西我寫(xiě)完發(fā)現(xiàn)調(diào)用完了之后開(kāi)始支付如果運(yùn)行我們android studio上面的app根本行不通無(wú)法支付只能出來(lái)彈框他不能成功喚起支付頁(yè)面、解決的話很簡(jiǎn)單就是我們不安裝自己的去安裝Google play平臺(tái)上面我們上傳上去的app光說(shuō)可能聽(tīng)不太懂我們直接上圖片
1、我們直接點(diǎn)擊自己的上傳的app
2、查看自己需要的版本
3、下載apk就可以了
4、彈框下載apk就可以測(cè)試了文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-644965.html
到這里基本就可以了如果還有別的我們可以一起討論文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-644965.html
到了這里,關(guān)于谷歌支付接入流程(一次性支付,連續(xù)訂閱)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!