Google play之應用內支付接入
阿新 • • 發佈:2019-02-09
前言
官方文件
官方Sample
google提供的官方sample是已經對官方api經過封裝了的,而google官方文件是按照最原裝的程式碼進行
描述的,所以本文將按照sample方式接入
SDK接入
- google應用內支付不用新增jar包,不用新增依賴,只需要一個aidl檔案:IInAppBillingService.aidl 可以從sample中獲得,並且將其放在: com.android.vending.billing包下
- 將sample中的util中的所用類拷貝到自己的專案的util下,這些類是已經對官方的api進行二次封裝了
配置資原始檔
在AndroidManifest.xml檔案中,新增以下許可權:
<uses-permission android:name="com.android.vending.BILLING" />
SDK中的API呼叫
- 初始化
//設定自己從google控制檯得到的公鑰
mHelper = new IabHelper(activity, "YOUR_PUBLIC_KEY");
//除錯模式
mHelper.enableDebugLogging(true);
Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper. OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if (!result.isSuccess()) {
Log.d(TAG, "Setup fail.");
return;
}
if (mHelper == null){
Log.d(TAG, "Setup fail.");
return;
}
Log.d(TAG, "Setup success.");
}
});
- 查詢庫存
/**
* 查詢庫存
* */
private void queryInventory(){
Log.e(TAG, "Query inventory start");
try {
mHelper.queryInventoryAsync(mGotInventoryListener);
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}
/**查詢庫存的回撥*/
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.e(TAG, "Query inventory finished.");
if (result.isFailure()) {
Log.e(TAG, "Failed to query inventory: " + result);
return;
}
Log.e(TAG, "Query inventory was successful." + inventory.getPurchase(mPayInfo.getProductId()));
if (inventory.hasPurchase(mPayInfo.getProductId())){
//庫存存在使用者購買的產品,先去消耗
}else{
//庫存不存在
}
}
};
- 購買商品
google應用內支付呼叫購買介面的時候,應先確保使用者沒有存在這個商品的購買(買了但是沒有消耗)
//在合適的地方呼叫購買
mHelper.launchPurchaseFlow(mActivity, sku, RC_REQUEST, mPurchaseFinishedListener, extra);
購買的回撥
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
if (result.isFailure()) {
// Oh noes! pay fail
Log.d(TAG,"Error purchasing: " + result);
return;
}
Log.d(TAG, "Purchase successful.");
//模擬檢測public key
checkPk(purchase);
}
};
購買成功後,應該將購買返回的資訊傳送到自己的服務端,自己的服務端再去利用public key去驗籤
- 消耗商品
使用者購買成功後,如果是可重複購買的商品,應該立刻將這個商品消耗掉,以及在購買之前應確保使用者不存在這個商品,如果存在就呼叫消耗商品的介面去將商品消耗掉
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
消耗商品的回撥
private IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
if (result.isSuccess()) {
Log.d(TAG, "Consumption successful. Provisioning.");
}
else {
Log.d(TAG,"Error while consuming: " + result);
}
}
};
安全問題
- 由於利用官方的sample實現方式是在app客戶端利用公鑰進行驗籤, 也就是將支付的回撥暴露在客戶端了,這種方式不可取,可以對sample裡面進行驗籤的部分程式碼進行改造,取消本地驗籤,然後將支付成功回撥的資訊傳輸到自己伺服器,在伺服器驗籤再將結果返回給客戶端
常見問題
- 確保包名和google控制檯配置一致
- 確保購買時候傳輸的productId和在google控制檯配置一致
- 確保App的version和google控制檯的version一致
- 確保keystore和上傳到google控制檯的keystore一致