Google play之应用内支付接入

作者: 牛牛技术 | 来源:发表于2018-02-12 19:49 被阅读882次

    前言

    如果要接入google登录,可以参考我的前一篇文章Google Play登录SDK接入

    官方文档

    google应用内支付V3接入Android官方文档

    官方Sample

    Google应用内支付官方样例

    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一致

    相关文章

      网友评论

        本文标题:Google play之应用内支付接入

        本文链接:https://www.haomeiwen.com/subject/mnrdtftx.html