前言
如果要接入google登录,可以参考我的前一篇文章Google Play登录SDK接入
官方文档
官方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一致
网友评论