in-app billing支付可以从django app服务端端验证吗

记录自己学到的,感悟到的.
购买 In-app Billing 商品
购买 In-app Billing 商品
一旦你的应用连接上了 Google Play,你就可以初始化内购商品的购买请求了。Google Play 提供了结算接口,可以让用户进入使用他们的支付方式,所以你的程序不必直接处理支付交易。
When an item is purchased, 当一个商品被购买后,Google Play 会认为这个用户已经拥有了此商品,并且直到这个商品被”消耗“后才会让用户再购买一个有相同商品ID的商品。你可以在你的程序里控制如何消耗商品,消耗后再告诉Google Play,Google Play会让这个商品再次可以购买。
你也可以通过向Google Play查询,快速获取用户已经购买的商品列表。这个方式很有用。举个例子,在用户启动你的应用时,你想把用户已经购买的商品交给用户.注1
购买一个商品
通过调用 IabHelper 的 launchPurchaseFlow(Activity, String, int, OnIabPurchaseFinishedListener, String) 方法从你的应用中开始一个购买请求。你必须在你Activity的主线程里调用这个方法。下面是对launchPurchaseFlow方法中使用参数的解释:
第一个参数是调用的 Activity。第二个参数是要购买商品的商品ID(也称做商品的SKU)。确保你用的是ID而不是商品名字。此前你应该已经在开发者控制台定义并且激活了这个商品,否则这个商品将不会被识别。第三个参数是请求码。这个码可以是任何正整数。Google Play 会把这个码连同购买回应一起返给调用 Activity的onActivityResult 方法。第四个参数是一个监听器(listener)。当购买操作完成以及处理收到Google Play的购买回应时,这个监听器会被通知。第五个参数含有一个‘developer payload’的字符串,你可以用来发送有关一个订单的额外信息(可以是一个空字符串)。通常这个参数会以一个唯一标示这次购买请求的字符串token来使用。如果你指定了一个字符串类型的值,Google Play会把这个值连同购买回应一起发给你。随后,当你对这个商品进行查询时,Google Play也会把这个字符串连同商品详细信息一起返给你。
安全建议: 一个好的做法就是你传一个有助于你的程序识别是哪个用户购买了商品的字符串,这样你以后就可以验证这个用户的购买是否是真实的。对于可消耗的商品,你可以使用一个随机生成的字符串,对于不可消耗的商品,你应该使用一个唯一标示用户的字符串。
下面的例子随便使用了一个请求码10001和一个加密的 developer playload 字符串,展示如何购买一个商品ID为 SKU_GAS的商品。
mHelper.launchPurchaseFlow(this, SKU_GAS, 10001,
mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
If the purchase order is successful, 如果购买成功,Google Play会把返回的数据存到一个 Purchase对象中,这个对象会传给listener。
下面的例子展示了根据此次购买是否成功以及用户购买的是 gas 还是 premiun upgrade,在listener所做的处理。在这个例子中,gas是一个可以购买多次的内购商品,所以你应该在允许用户再次购买之前消耗掉这个商品。学习如何消耗商品,查看 消耗商品 部分。
这个 premium upgrade 是一个一次性购买商品,所以你不必消耗它。购买成功后立刻更新UI是很好的做法,这样你的用户就可以看到他们新购买的物品。
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
else if (purchase.getSku().equals(SKU_GAS)) {
// consume the gas and update the UI
else if (purchase.getSku().equals(SKU_PREMIUM)) {
// give user access to premium content and update the UI
安全建议: 当你从 Google Play收到购买返回消息时,一定要检查返回Purchase对象中的数据签名,订单号和developerPayload,确保是你想要的值。你应该验证订单号 orderId 是你先前没有处理过的独一无二的值,以及 developerPayload 字符串符合你先前发送购买请求设置的token(译者注:发送的developerPayload是加密的,可能是MD5,也可能是Base64,因为这个payload是原样返给你的,你解密对比一下是不是原值)。
作为更长远的安全措施,你应该在你自己的安全服务器做验证。P.S.这段内容和我先前写的博客里的建议差不多。
查询购买的商品
每次购买成功后,Google Play的内购服务就会把用户的购买数据缓存在本地。一个好的做法就是多通过In-app Billing服务查询用户的购买,举例来说,不论何时程序启动或者恢复,都去查询一下,这样用户当前所拥有的内购商品的情况都可以反映到你程序中。
通过调用 IabHelper 中的queryInventoryAsync(QueryInventoryFinishedListener) 方法来获取用户的购买信息。
这个QueryInventoryFinishedListener 参数设置了一个监听器,当查询操作完成以及处理查询回应结果时,这个监听器都会收到通知。在你程序的主线程调用这个方法是安全的。
mHelper.queryInventoryAsync(mGotInventoryListener);
如果查询成功,查询结果就会存到一个 Inventory 对象中并传回给监听器。In-app Billing 服务只会返回当前登陆设备用户所完成的购买信息。
IabHelper.QueryInventoryFinishedListener mGotInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (result.isFailure()) {
// handle error here
// does the user have the premium upgrade?
mIsPremium = inventory.hasPurchase(SKU_PREMIUM);
// update UI accordingly
你可以通过使用 In-app Billing Version 3 API 来追踪购买物品存在Google Play上的所有权信息。一旦一个物品被购买,它就会被认作“拥有”状态,当处在此状态时就不可以再次从Google Play购买。对于这个物品,你必须向Google Play发送一个消耗请求,这样Google Play才可以重新让这个商品可以被买。所有的受管理内购商品都是可消耗的。在你的程序里如何使用这个消耗机制取决于你。一般来说,你会为那些短暂起作用,用户可能想多次购买的商品实现消耗(例如,游戏内货币或者可重复使用的游戏Token),而像那些购买一次就可以提供持久效果的商品就不需要实现消耗(例如,额外升级)。
你负责控制和追踪如何内购商品给用户。例如,如果用户购买了游戏内货币,你就应该把购买的货币数量更新到玩家的财产中。
安全建议: 用户购买可消耗商品成功后,在把商品给用户前,你要先发送一个消耗请求,确保你从Google Play收到消耗成功的回应后才可以把商品发给用户。
为了记录购买消耗,你可以调用IabHelper 中的 consumeAsync(Purchase, OnConsumeFinishedListener) 方法。这个方法中的第一个参数是 Purchase 对象,代表的是消耗的物品。 第二个参数是 OnConsumeFinishedListener,当消耗操作完成以及处理来自Google Play的消耗回应时,都会通知这个listener。 可以在程序主线程调用这个方法。
在下面这段代码中,你想消耗用户先前在你程序中购买的气体道具。
mHelper.consumeAsync(inventory.getPurchase(SKU_GAS),
mConsumeFinishedListener);
下面代码展示了如何实现 OnConsumeFinishedListener.
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (result.isSuccess()) {
// provision the in-app purchase to the user
// (for example, credit 50 gold coins to player's character)
// handle error
程序启动时检查可消耗物品
一个重要的事,就是在用户启动你应用的时候检查可消耗物品。通常来说,你会首先在In-app Billing服务中查询用户已经购买了商品信息(v通过queryInventoryAsync),然后通过Inventory获取可消耗 Purchase 对象。如果你的程序检测到用户拥有可消耗物品,不管是那种,你都应该马上向Google Play发送一个消耗请求,随后把这个物品发给用户。 看看TrivialDrive 例子是如何实现在应用启动时做这个检测的。
注1:原文 This is useful, for example, when you want to restore the user's purchases when your user launches your app.
没有更多推荐了,Android: In-app-billing 付费机制Google示例
原文地址:http://neurosoft.blogspot.tw/2013/07/android-in-app-billing-google.html
AndroidManifest.xml中必須增加底下宣告:
android:name="com.android.vending.BILLING"
Package的名稱必須Rename,package com.wsj.android.trivialdrivesample;
換入你上傳App後的金鑰,String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0B...省略.....";
產生程式中對應的物品,以便測試 手機的primary gmail帳號要設成測試gmail帳號,不能用開發者的gmail帳號!
//Does the user have the premium upgrade?
boolean mIsPremium = false;
//Does the user have an active subscription to the infinite gas plan?
boolean mSubscribedToInfiniteGas = false;
//SKUs for 產品:the premium upgrade(non-consumable)and gas(consumable)
static final String SKU_PREMIUM = "premium";
static final String SKU_GAS = "gas";
//SKU for our 訂閱subscription (infinite gas)
static final String SKU_INFINITE_GAS = "infinite_gas";
//(arbitrary) request code for the purchase flow
static final int RC_REQUEST = 10001;
//The helper object
IabHelper mHelper;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//load game data
loadData();
//建議不要直接用一個字串來設定,這樣比較容易被破解!
String base64EncodedPublicKey ="....";
//產生helper物件,傳入context和金鑰
mHelper = new IabHelper(this, base64EncodedPublicKey);
//設定debug logging(for a production app, set it to false)
mHelper.enableDebugLogging(true);
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if (!result.isSuccess()) {
//有問題發生!
complain("Problem in in-app billing:"+result);
// 起始成功,接著查詢此裝置已經擁有的物品
Log.d(TAG, "Setup successful.Querying inventory.");
mHelper.queryInventoryAsync(mGotInventoryListener);
//當我們查詢購買物品和訂閱資訊時,系統會呼叫此Callback
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new
IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
Log.d(TAG, "Query inventory was successful.");
*Check items we own.Notice that for each purchase,we check
*the developer payload to see if it's correct! See
*verifyDeveloperPayload().
// 檢查是否有升級成premium?
Purchase premiumPurchase=inventory.getPurchase(SKU_PREMIUM);
mIsPremium = (premiumPurchase != null &&
verifyDeveloperPayload(premiumPurchase));
Log.d(TAG,"User is"+(mIsPremium ?"PREMIUM":"NOT PREMIUM"));
// 有訂閱無限汽油嗎?infinite gas subscription?
Purchase infiniteGasPurchase=
inventory.getPurchase(SKU_INFINITE_GAS);
mSubscribedToInfiniteGas =(infiniteGasPurchase != null &&
verifyDeveloperPayload(infiniteGasPurchase));
Log.d(TAG, "User " + (mSubscribedToInfiniteGas ? "HAS":
"DOES NOT HAVE")+ " infinite gas subscription.");
if (mSubscribedToInfiniteGas) mTank = TANK_MAX;
// 檢查是否有買汽油gas -- 如果有買,則立刻加入油箱。
Purchase gasPurchase = inventory.getPurchase(SKU_GAS);
if(gasPurchase!=null&&verifyDeveloperPayload(gasPurchase)){
Log.d(TAG, "We have gas. Consuming it.");
// 將汽油用掉
mHelper.consumeAsync(inventory.getPurchase(SKU_GAS),
mConsumeFinishedListener);
updateUi();
setWaitScreen(false);
Log.d(TAG, "Initial inventory query finished.");
//買汽油按"Buy Gas"按鈕
public void onBuyGasButtonClicked(View arg0) {
Log.d(TAG, "Buy gas button clicked.");
if (mSubscribedToInfiniteGas) {
complain("No need!You're subscribed to infinite gas.");
if (mTank &= TANK_MAX) {
complain("Your tank is full. Drive around a bit!");
// launch the gas purchase UI flow.
// notified of completion via mPurchaseFinishedListener
setWaitScreen(true);
Log.d(TAG, "Launching purchase flow for gas.");
/*TODO:for security,generate your payload here for verification
*verifyDeveloperPayload() for more info.We use
*an empty string for example */
String payload = "";
mHelper.launchPurchaseFlow(this, SKU_GAS, RC_REQUEST,
mPurchaseFinishedListener, payload);
//按"Upgrade to Premium"按鈕
public void onUpgradeAppButtonClicked(View arg0) {
Log.d(TAG, "launching purchase flow for upgrade.");
setWaitScreen(true);
/*TODO:for security,generate your payload here for verification*/
String payload = "";
mHelper.launchPurchaseFlow(this, SKU_PREMIUM, RC_REQUEST,
mPurchaseFinishedListener, payload);
//訂閱infinite gas
public void onInfiniteGasButtonClicked(View arg0) {
if (!mHelper.subscriptionsSupported()) {
complain("Subscriptions not supported on your device yet!");
String payload = "";
setWaitScreen(true);
Log.d(TAG, "Launching purchase for infinite gas subscription.");
mHelper.launchPurchaseFlow(this,
SKU_INFINITE_GAS, IabHelper.ITEM_TYPE_SUBS,
RC_REQUEST, mPurchaseFinishedListener, payload);
//當購買程序完成時,呼叫此Callback
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new
IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result,Purchase purchase){
Log.d(TAG,"Purchase ok:"+result+",purchase:"+purchase);
if (result.isFailure()) {
complain("Error purchasing: " + result);
setWaitScreen(false);
if (!verifyDeveloperPayload(purchase)) {
complain("Error purchasing.Authenticity failed.");
setWaitScreen(false);
Log.d(TAG, "Purchase successful.");
if (purchase.getSku().equals(SKU_GAS)) {
// bought 1/4 tank of gas. So consume it.
Log.d(TAG, "Starting gas consumption.");
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
else if (purchase.getSku().equals(SKU_PREMIUM)) {
// bought the premium upgrade!
Log.d(TAG,"Purchase is premium upgrade.");
alert("Thank you for upgrading to premium!");
mIsPremium = true;
updateUi();
setWaitScreen(false);
else if (purchase.getSku().equals(SKU_INFINITE_GAS)) {
// bought the infinite gas subscription
Log.d(TAG, "Infinite gas subscription purchased.");
alert("Thank you for subscribing to infinite gas!");
mSubscribedToInfiniteGas = true;
mTank = TANK_MAX;
updateUi();
setWaitScreen(false);
//當物品完成使用時,呼叫此callback
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new
IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,IabResult result){
Log.d(TAG,"Consumption ok.Purchase:"+purchase+",result:"+result);
//This is "gas" sku because it's the only one we consume,
//so don't check which sku was consumed.If have more than one
//sku, you probably should check...
if (result.isSuccess()) {
//successfully consumed,so apply effects of the item in
//game world's,which means filling the gas tank a bit
Log.d(TAG, "Consumption successful. Provisioning.");
mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
saveData();
alert("It's now"+String.valueOf(mTank)+"/4 full!");
complain("Error while consuming: " + result);
updateUi();
setWaitScreen(false);
Log.d(TAG, "End consumption flow.");
// 記得要在這裡釋放helper物件!
public void onDestroy() {
super.onDestroy();
// very important:
Log.d(TAG, "Destroying helper.");
if (mHelper != null) mHelper.dispose();
mHelper = null;
執行截圖:
没有更多推荐了,In-app billing 接入流程和坑点
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() {
public void onIabSetupFinished(IabResult result) {
showLog("Setup finished----------");
if (!result.isSuccess()) {
alert("Problem setting up in-app billing: " + result);
if (iabHelper == null) return;
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() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
showLog("查询商品----" + "Query inventory finished");
if (iabHelper == null) return;
if (result.isFailure()) {
alert("Failed to query inventory: " + result);
showLog("Query inventory was successful.");
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() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (null != purchase)
showLog("购买商品------" + "Purchase finished: " + result + "purchase-" + purchase + ", OriginalJson: " + purchase.getOriginalJson() + "signture----" + purchase.getSignature());
if (iabHelper == null) return;
if (result.isFailure()) {
if (!verifyDeveloperPayload(purchase)) {
alert("Error purchasing. Authenticity verification failed.");
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() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
showLog("消耗商品---------" + "Consumption finished. Purchase: " + purchase + ", result: " + result);
if (iabHelper == null) return;
if (result.isSuccess()) {
showLog("消耗商品成功" + "orderId---" + purchase.getOrderId() + "---PurchaseTime----" + purchase.getPurchaseTime() + "----sku-----" + purchase.getSku());
alert("Error while consuming: " + result);
(4) 回调与destroy
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;
if (!iabHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
showLog("handleActivityResult---------------");
showLog("onActivityResult handled by IABUtil-------------.");
protected void onDestroy() {
super.onDestroy();
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();
alert("This device is not supported, Please install google play services");
return false;
return true;
最后,就剩下测试了,关于测试的账号要注意的:
1.测试账号必须要绑定visa卡或者paypal账号,而且不能是开发者账号
2.由于国内种种原因(你懂得),必须开vpn, 蓝灯挺好用的,而且最好是链接到美国的
3.控制台里将开发账号绑定好结算等等信息
4.你的google商店要登陆你的测试账号从商店上下载应用并测试,我开始是这样测试的,可以支付,但是跑项目测试不行,后来放了一晚后,就可以了,具体原因我也不知道,但是建议用多几款机型测试,国内手机可以安装谷歌安装器来安装谷歌服务(跑本地的项目测试的话记得包名、签名、版本号等信息都要与线上测试的版本一致)
接入前,建议看看开发者文档,会对整个接入流程更加清晰,由于英文不好,这里我就附上中文版的:
没有更多推荐了,}

我要回帖

更多关于 app远程查询服务端 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信