Google In-app Billing 支付接入笔记

###准备工作

  • 手机 google service 安装,VPN 选择 ,google wallet 绑定visa信用卡
  • Develop Console 配置应用
  • In-app billing 接入

问题总结

google in-app-billing提示“无法购买你要的商品”
  • 保证Package Name, 包名一致
  • 保证VersionCode, 上传的包和你测试的包一致
  • 保证Payment List, google后台的单据名和你游戏中配置的一致
  • 保证Payment Key, google后台Key和你的Key一致
  • 保证Test User, 你在测试阶段可以正常支付你的游戏
  • 保证GooglePlay商店, 这个一般来说只要弹出支付是没问题的, 但是如果商店无法使用,请检查VPN
  • Google Play Developer Console -> 设置 -> API权限 里启用 Games Services Publishing API
    #####google in-app-billing提示“需要验证身份,你需要登录自己的google账号
  • 检查商品ID是否正确
后台校验失败
  • Google Play Developer Console -> 设置 -> 用户账号和权限 里添加服务账号(Console 后台生P12文件的服务账号)

主要代码

public class GooglePaySP {
    public static final String DATA_SAVE_NAME = "tobin_google_billing_data";
    private static final String PURCHASE_KEY = "tobin_google_orders_purchase";
    public static void savePurchase(Context ctx, Purchase purchase) {
        SharedPreferences sp = ctx.getSharedPreferences(DATA_SAVE_NAME, 0);
        String purchasesStr = sp.getString(PURCHASE_KEY, null);
        try {
            JSONObject object;
            if (purchasesStr == null) {
                object = new JSONObject();
            } else {
                object = new JSONObject(purchasesStr);
            }
            if (!object.has(purchase.getDeveloperPayload())) {
                object.put(purchase.getDeveloperPayload(), purchase.toJson());
                sp.edit().putString(PURCHASE_KEY, object.toString()).commit();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public static void removePurchase(Context ctx, Purchase purchase) {
        SharedPreferences sp = ctx.getSharedPreferences(DATA_SAVE_NAME, 0);
        String purchasesStr = sp.getString(PURCHASE_KEY, null);
        try {
            JSONObject object;
            if (purchasesStr == null) {
                return;
            }
            object = new JSONObject(purchasesStr);
            if (object.has(purchase.getDeveloperPayload())) {
                object.remove(purchase.getDeveloperPayload());
                sp.edit().putString(PURCHASE_KEY, object.toString()).commit();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public static List<Purchase> getAllPurchases(Context ctx) {
        SharedPreferences sp = ctx.getSharedPreferences(DATA_SAVE_NAME, 0);
        String purchasesStr = sp.getString(PURCHASE_KEY, null);
        List<Purchase> result = new ArrayList<>();
        try {
            JSONObject object;
            if (purchasesStr == null) {
                return result;
            }
            object = new JSONObject(purchasesStr);
            Iterator i = object.keys();
            while (i.hasNext()) {
                result.add(new Purchase().initWithJson(object.getJSONObject(i.next().toString())));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Error e) {
            e.printStackTrace();
        }
        return result;
    }
}

帮助类

public class GooglePayHelper {
    private static GooglePayHelper instance;
    private IabHelper mHelper;
    private boolean iabSetupOK;
     private Activity activity ;
    private GooglePayHelper() {
    }
    public static GooglePayHelper getInstance() {
        if (instance == null)
            instance = new GooglePayHelper();
        return instance;
    }

    public void initGooglePay(final Activity context){
    	this.activity = context;
		// base64PublicKey 不建议写客户端
		// Security.verifyPurchase 中修改返回true 跳过本地校验
        mHelper = new IabHelper(context, "");
        //调试模式
        mHelper.enableDebugLogging(true,"TobinIabHelper");
//        mHelper.enableDebugLogging(false,"TobinIabHelper");
        Log.d("Tobin", "Starting setup.");
        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            @Override
            public void onIabSetupFinished(IabResult result) {
                Log.d("Tobin", "Setup finished.");

                if (!result.isSuccess()) {
                    Log.d("Tobin", "Setup fail.");
                    Toast.makeText(context,"google play billing init fail.",Toast.LENGTH_LONG).show();
                    return;
                }
                if (mHelper == null){
                    Log.d("Tobin", "Setup fail.");
                    return;
                }

                iabSetupOK = true;
                Log.d("Tobin", "Setup success.");

                queryInventory();

            }
        });

    }

    public boolean isIabSetupOK() {
        return iabSetupOK;
    }

    /**
     * 查询库存
     * */
    private void queryInventory(){
        Log.e("Tobin", "Query inventory start");
        try {
            mHelper.queryInventoryAsync(mGotInventoryListener);
        } catch (IabHelper.IabAsyncInProgressException e) {
            Log.i("Tobin","Error queryInventoryAsync. Another async operation in progress.");
            e.printStackTrace();
        }
    }

    /**查询库存的回调*/
    private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        @Override
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            Log.d("Tobin", "Query inventory finished.");
            if (result == null || result.isFailure()) {
                Log.e("Tobin", "Failed to query inventory: " + result);
                return;
            }

			//库存存在用户购买且未发货的产品
            List<Purchase> listLocal = GooglePaySP.getAllPurchases(activity);
            if (listLocal.size() > 0) {
                Log.i("Tobin","SharedPreferences Local Purchase: " + listLocal.toString());
                for (final Purchase p : listLocal){
                    Log.i("Tobin", p.getOriginalJson());
                    // 请求服务器发货 HttpURLConnection post params
                    //@Override onSuccess()
                    	GooglePaySP.removePurchase(activity ,p);
                }
            }

			//库存存在用户购买的产品,先去消耗
            List<Purchase> list = inventory.getAllPurchases();
            Log.i("Tobin"," List:" + list.toString() + " list:" +list.size());
            if (list.size() > 0) {
                for (final Purchase p : list){
                    Log.i("Tobin", p.getOriginalJson());
                    consumePurchase(p);
                }
//                consumeAllPurchase(list);
            }
        }
    };

    // (arbitrary) request code for the purchase flow
    private static final int RC_REQUEST = 10001;

    /**
     * google game支付
     */
    public void googlePay(final Activity ctx,final String ServerID,final String User,final String PayNum, final String sku,
                          final String OrderNo, final String orderSign) {

        Log.e("Tobin","googlePay sku: " + Orderid);
        if (!iabSetupOK){
            mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
                @Override
                public void onIabSetupFinished(IabResult result) {
                    Log.d("Tobin", "Setup finished.");

                    if (!result.isSuccess()) {
                        Log.d("Tobin", "Setup fail.");
                        return;
                    }
                    if (mHelper == null){
                        Log.d("Tobin", "Setup fail.");
                        return;
                    }

                    iabSetupOK = true;
                    Log.d("Tobin", "Setup success.");

                }
            });
            Toast.makeText(ctx,"google play billing init fail.",Toast.LENGTH_LONG).show();
            return;
        }

        // 请求订单号 HttpURLConnection post params
        // @Override onSuccess()
        	try {
				 // 在合适的地方调用购买
//                    mHelper.launchPurchaseFlow(ctx, sku, RC_REQUEST, mPurchaseFinishedListener, extra);
            } catch (IabHelper.IabAsyncInProgressException e) {
                  Log.i("Tobin","Error launching purchase flow. Another async operation in progress.");
            } 
    }

    // 购买的回调
    private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        @Override
        public void onIabPurchaseFinished(IabResult result,final Purchase purchase) {
            Log.d("Tobin", "Purchase finished: " + result + ", purchase: " + purchase);
            if (result.isFailure()) {
                // Oh noes! pay fail
                Log.d("Tobin","Error purchasing: " + result);
                if (result.getResponse() == 7){
//                    该商品尚未消耗,暂时不能购买
                    queryInventory();
                }
                // 支付失败
                // Callback...
                return;
            }
            Log.d("Tobin", "Purchase successful.");
            Log.i("Tobin","getSignature: " + purchase.getSignature());
            Log.i("Tobin","getOriginalJson: " + purchase.getOriginalJson());
            //模拟检测public key 消耗商品
            consumePurchase(purchase);
            GooglePaySP.savePurchase(activity ,purchase);
            // 支付成功
            // Callback...
            // 支付成功请求服务器校验发货 HttpURLConnection post params
            //@Override onSuccess()
            //	 GooglePaySP.removePurchase(activity,purchase);
        }
    };

    // 消耗商品
    private void consumePurchase(Purchase purchase){
        try {
            mHelper.consumeAsync(purchase, mConsumeFinishedListener);
        }catch (IabHelper.IabAsyncInProgressException e){
            Log.d("Tobin","Error consuming gas. Another async operation in progress.");
            e.printStackTrace();
        }
    }

    // 消耗商品的回调
    private IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
        @Override
        public void onConsumeFinished(Purchase purchase, IabResult result) {
            Log.d("Tobin", "Consumption finished. Purchase: " + purchase + ", result: " + result);
            if (result.isSuccess()) {
                Log.d("Tobin", "Consumption successful. Provisioning.");
            }
            else {
                Log.d("Tobin","Error while consuming: " + result);
            }
        }
    };

	// 获取支付回调  onActivityResult 中调用
    public boolean handlerResult(int requestCode, int resultCode, Intent data) {
        return requestCode == RC_REQUEST && mHelper != null && mHelper.handleActivityResult(requestCode, resultCode, data);
    }

	// activity 销毁调用
    public void onDestroy() {
        Log.i("Tobin","GooglePayHelper onDestroy mHelper dispose");
        if (mHelper !=null){
            try {
                mHelper.dispose();
                mHelper = null;
            }catch (IabHelper.IabAsyncInProgressException e){
                e.printStackTrace();
            }
        }
    }

}

你可能感兴趣的:(Android)