准备工作
1,在Google play console 注册开发者账号,新建你的项目
2.下载这google play service和billing library, billing v3以上版本,现在好像已经出到v5了
3.下载好之后,在下图这个sdk路径下,samples是官方提供的demo, 我们需要的是IInAppBillingService.aidl这个文件,这个应该是google支付的通信文件
4.将IInAppBillingService.aidl拷贝到com.android.vending.billing这个路径下
5.将官方samples里的这些类全部拷贝到你的代码里,这些都是些google支付的辅助工具类,核心的支付代码后面我会贴出来, 另外记得加入支付权限:com.android.vending.BILLING
6.接下来在你的 google play console 里的应用内商品上传你的apk, 注意点:(1) 确保你的apk是签名后的 (2)确保你的apk已经加入了支付权限 (3)如果你的商品已经上线了应用商店的话,此版本你最好是提交beta版或者alpha版 (4) 测试版的话最好添加测试人员,封闭式测试,如何添加测试人员和封闭式测试后面会讲。设置商家账号的话大概是设置一些绑定的支付等信息,按着里面对应设置就行
7.添加完应用内商品后,这一栏会编程下图的样子,这个是添加你的商品的,你可以添加很多很多的商品,可以设置商品的id,名称,简介,价格等,注意这个商品的id设置后就不能再改动的,其他都可以改,商品id就是后面支付代码里要用到的sku。还有就是选择受管理商品,因为这个才是应用内购物。
8.添加测试人员:创建列表,然后点击进入你的列表页,如果你一次添加多个账号,那个账号之间要用逗号隔开。请注意,开发者账号是不能作为测试人员的,开发者账号也就是登陆这个play console 平台的账号。
9.在你在应用版本发布beta版或者alpha版的时候, 你就可以悬着测试方法,我选择的是封闭式测试,至于这几种测试方式有何不同,可以去开发者文档里看看。然后就是选择你的测试全体, 最下面有一条链接,这个链接你可以发送给其他要测试的人员,他们打开点击里面的要成为测试人员后就会成为你的测试人员了,如果说没有成为测试人员资格之类的话,请在第10点那张图里添加那个测试人员的账号,然后再点击就可以了
10.注意点,这里没说要逗号隔开,但是如果添加多个账号的话,账号之间也是要用逗号隔开的
11.支付是需要用到publickey的,这个publickey在你的服务与API里可以找到,这个publickey在调用时候最好从后台服务器中获取,安全性会好点
12.购买流程
(1) 初始化IabHelper 并查询是否有可消耗的商品
/**
* 初始化IabHelper
*/
private void setupIabHelper(String base64EncodedPublicKey) {
showLog("base64EncodedPublicKey--------" + base64EncodedPublicKey);
iabHelper = new IabHelper(this, base64EncodedPublicKey);
iabHelper.enableDebugLogging(true);
iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
showLog("Setup finished----------");
if (!result.isSuccess()) {
// Oh noes, there was a problem.
alert("Problem setting up in-app billing: " + result);
return;
}
// Have we been disposed of in the meantime? If so, quit.
if (iabHelper == null) return;
// IAB is fully set up. Now, let's get an inventory of stuff we own.
showLog("Setup successful. Querying inventory");
List<String> additionalSkuList = new ArrayList();
additionalSkuList.add(SKU_80);
additionalSkuList.add(SKU_500);
additionalSkuList.add(SKU_1200);
additionalSkuList.add(SKU_2500);
additionalSkuList.add(SKU_6500);
additionalSkuList.add(SKU_14000);
iabHelper.queryInventoryAsync(true, additionalSkuList, queryInventoryFinishedListener);
}
});
}
/**
* 查询用户所拥有的商品信息
*/
IabHelper.QueryInventoryFinishedListener queryInventoryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
showLog("查询商品----" + "Query inventory finished");
// Have we been disposed of in the meantime? If so, quit.
if (iabHelper == null) return;
// Is it a failure?
if (result.isFailure()) {
alert("Failed to query inventory: " + result);
return;
}
showLog("Query inventory was successful.");
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
if (inventory.getPurchase(SKU_80) != null && verifyDeveloperPayload(inventory.getPurchase(SKU_80))) {
showLog("need consume sku_80.");
iabHelper.consumeAsync(inventory.getPurchase(SKU_80), consumeFinishedListener);
}
if (inventory.getPurchase(SKU_500) != null && verifyDeveloperPayload(inventory.getPurchase(SKU_500))) {
showLog("need consume sku_500.");
iabHelper.consumeAsync(inventory.getPurchase(SKU_500), consumeFinishedListener);
}
if (inventory.getPurchase(SKU_1200) != null && verifyDeveloperPayload(inventory.getPurchase(SKU_1200))) {
showLog("need consume sku_1200.");
iabHelper.consumeAsync(inventory.getPurchase(SKU_1200), consumeFinishedListener);
}
if (inventory.getPurchase(SKU_2500) != null && verifyDeveloperPayload(inventory.getPurchase(SKU_2500))) {
showLog("need consume sku_2500.");
iabHelper.consumeAsync(inventory.getPurchase(SKU_2500), consumeFinishedListener);
}
if (inventory.getPurchase(SKU_6500) != null && verifyDeveloperPayload(inventory.getPurchase(SKU_6500))) {
showLog("need consume sku_6500.");
iabHelper.consumeAsync(inventory.getPurchase(SKU_6500), consumeFinishedListener);
}
if (inventory.getPurchase(SKU_14000) != null && verifyDeveloperPayload(inventory.getPurchase(SKU_14000))) {
showLog("need consume sku_14000.");
iabHelper.consumeAsync(inventory.getPurchase(SKU_14000), consumeFinishedListener);
}
}
};
(2)发起购买
/**
* 发起购买
*/
private void launchPurchaseFlow(String sku) {
if (checkPlayServices())
iabHelper.launchPurchaseFlow(this, sku, IabHelper.ITEM_TYPE_INAPP, REQUEST_CODE, purchaseFinishedListener, new Date().toString() + sku);
}
/**
* 购买商品
*/
IabHelper.OnIabPurchaseFinishedListener purchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (null != purchase)
showLog("购买商品------" + "Purchase finished: " + result + "purchase-" + purchase + ", OriginalJson: " + purchase.getOriginalJson() + "signture----" + purchase.getSignature());
// if we were disposed of in the meantime, quit.
if (iabHelper == null) return;
if (result.isFailure()) {
// alert("Error purchasing: " + result); // TODO 用户取消或其他情况
return;
}
if (!verifyDeveloperPayload(purchase)) {
alert("Error purchasing. Authenticity verification failed.");
return;
}
iabHelper.consumeAsync(purchase, consumeFinishedListener); // 消耗商品
if (!TextUtils.isEmpty(money) && wealth != 0 && null != purchase && null != purchase.getOriginalJson() && null != purchase.getSignature() && null != purchase.getOrderId()) {
showLog("购买商品成功========" + "money-----" + money + "----wealth-----" + wealth + "\npurchaseDta::::" + purchase.getOriginalJson() + "\ndataSignature::::" + purchase.getSignature());
getP().doBillingRecord(PreferenceUtil.getString(Conf.PF_USER_ID_KEY), PreferenceUtil.getString(Conf.PF_TOKEN_KEY),
money, wealth, purchase.getOriginalJson(), purchase.getSignature(), purchase.getOrderId());
}
}
};
(3)消耗商品(消耗了才能再次购买)
/**
* 消耗商品
* (如果商品是可以重复购买的情况下,
* 在查询结束对需要消耗的商品进行消耗掉,
* 或者购买完商品对商品进行消耗)
*/
IabHelper.OnConsumeFinishedListener consumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
showLog("消耗商品---------" + "Consumption finished. Purchase: " + purchase + ", result: " + result);
// if we were disposed of in the meantime, quit.
if (iabHelper == null) return;
// We know this is the "gas" sku because it's the only one we consume,
// so we don't check which sku was consumed. If you have more than one
// sku, you probably should check...
if (result.isSuccess()) {
// successfully consumed, so we apply the effects of the item in our
// game world's logic, which in our case means filling the gas tank a bit
showLog("消耗商品成功" + "orderId---" + purchase.getOrderId() + "---PurchaseTime----" + purchase.getPurchaseTime() + "----sku-----" + purchase.getSku());
} else {
alert("Error while consuming: " + result);
}
}
};
(4) 回调与destroy
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (null != data)
showLog("回调信息-----------" + requestCode + "," + resultCode + "," + "purchaseData:" + data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA) + "--dataSignature---" + data.getStringExtra(RESPONSE_INAPP_SIGNATURE));
if (iabHelper == null) return;
// Pass on the activity result to the helper for handling
if (!iabHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
showLog("handleActivityResult---------------");
} else {
showLog("onActivityResult handled by IABUtil-------------.");
}
}
// We're being destroyed. It's important to dispose of the helper here!
@Override
protected void onDestroy() {
super.onDestroy();
// very important:
showLog("destroy helper.");
if (iabHelper != null) {
iabHelper.dispose();
iabHelper = null;
}
}
在发起购买前最好判断下手机当前是否支持google play service, 判断如下
/**
* Check the device to make sure it has the Google Play Services APK.If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, 101).show();
} else {
alert("This device is not supported, Please install google play services");
finish();
}
return false;
}
return true;
}
最后,就剩下测试了,关于测试的账号要注意的:
1.测试账号必须要绑定visa卡或者paypal账号,而且不能是开发者账号
2.由于国内种种原因(你懂得),必须开vpn, 蓝灯挺好用的,而且最好是链接到美国的
3.控制台里将开发账号绑定好结算等等信息
4.你的google商店要登陆你的测试账号从商店上下载应用并测试,我开始是这样测试的,可以支付,但是跑项目测试不行,后来放了一晚后,就可以了,具体原因我也不知道,但是建议用多几款机型测试,国内手机可以安装谷歌安装器来安装谷歌服务(跑本地的项目测试的话记得包名、签名、版本号等信息都要与线上测试的版本一致)
接入前,建议看看开发者文档,会对整个接入流程更加清晰,由于英文不好,这里我就附上中文版的:https://developer.android.com/google/play/billing/versions.html