Google Pay接入流程

12,044 阅读7分钟
应用创建

创建应用需要上传一个签名后的包。可以是个空包,也就是说,可以上传一个和正式包一样包名和签名的就可以提前获得回复的key。

GooglePay内购及订阅概念

1.GoogleInapp(内购)

GoogleInapp也叫google内购,内购分为两个步骤,第一步为购买。购买成功后,需要消耗该商品。如果该商品未消耗,那么当前设备下次购买该商品将会失败,返回code码为7.用户如果第一次购买该商品,在两小时内可以不通过开发者同意进行退款(该规则同样适用于订阅功能)。在服务器校验流程中,可以根据code码判断是否退款。

2.GoogleSubs(订阅)

googleSubs也叫google订阅。定期的扣除用户的费用。直到用户到googlePlay中接触订阅。

/**
     * 用于订阅商品
     *
     * @param context
     * @param productId Google play store 后台定义的商品的id。如果错误的话,将提示检索失败
     * @param payload   该字段随机生成一定长度的字符串,用于生成的订单支付成功后根据google返回的订单信息关联。
     */
    public void subsGoods(Activity context, String productId, String payload)

业务接入流程

整体接入流程图

  1. 调用queryProductDetails(productId,listener)方查询google后台是否拥有该商品id。如果有该商品id,同时返回该商品价格,货币,描述信息等信息
  2. 根据返回信息到服务器创建预支付订单。
  3. 创建成功后,调用googlePay.buyGoods(activity,productId,developerPayload)购买方法,下面分为两种情况,一种是购买成功,触发onBuySuccess(OrderParam orderParam)方法(下一步骤为4),一种是购买失败,而失败中如果是由于未消耗造成的会返回状态码为7(下一步骤为6);触发haveGoodsUnConsume()方法。
  4. 购买成功,到服务器校验该商品.
  5. 如果商品校验成功,调用googlePay.consumeAsync(mPurchasingItemType,purchaseData, dataSignature)方法消耗该商品,如果消耗失败,那么下次购买时,到步骤1,直到消耗成功后才能进行下一次支付,这样可以百分百的保证不丢单.
  6. 根据返回的状态码为7时,会触发haveGoodsUnConsume方法,在该方法中调用handQueryInventoryAsync()方法查询未消耗商品的信息
  7. 根据查询到的信息,到服务器校验该商品信息;(下一步骤为5)。

GooglePay接入方法说明

初始化GooglePay对象

/**
     * 初始化Google pay
     *
     * @param context                上下文参数
     * @param base64EncodedPublicKey 购买需要的公钥
     * @param listener               初始化和购买的回调
     */
    public GooglePay(Activity context, String base64EncodedPublicKey, GooglePayStatus listener)

GooglePayStatus中包含购买过程会用到的方法

/**
     * 初始化失败是,调用该方法。在调用购买时,需要对该参数进行判断
     * https://www.jianshu.com/p/87ffdb7bc439
     * 该文章有提到解决方法
     *
     * @param boo
     */
    public abstract void initFailed(boolean boo);

    /**
     * 各种的支付过程中的状态
     *
     * @param code
     */
    public abstract void onGgStatus(int code);

    /**
     * 调用购买或订阅成功时会回调该方法
     *
     * @param data 返回Google  pay购买成功返回的参数
     */
    public abstract void onBuySuccess(OrderParam data);

    /**
     * 调用消耗商品成功
     */
    public abstract void onConsumeSuccess();

    /**
     * <p>
     * public void setIsAutoConsume(boolean isAutoConsume) {
     * this.isAutoConsume = isAutoConsume;
     * }
     * <p>
     * 当setIsAutoConsume 设置为true时,
     * 将会回调该方法,根据自己的业务逻辑进行处理消耗商品逻辑
     *
     * @param purchase
     */
    public void unConsumeAsync(Purchase purchase) {

    }

    public void cancelPurchase() {

    }

    /**
     * 购买时,有未消耗的商品,回调该方法
     */
    public void haveGoodsUnConsume() {

    }

    /**
     * 其他错误
     * @param status
     * @param error
     */
    public void ohterError(int status, String error) {

    }

购买成功后的回调,需要在onActivityResult方法中处理

public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
        if (googlePay != null && googlePay.isSetupDone()) {
            return googlePay.handleActivityResult(requestCode, resultCode, data);
        }
        return false;
    }

查询商品是否存在,如果存在,返回该商品id的相关信息

/**
    * 查询商品的详情信息,同时用于判断服务器是否配置了该商品id。
    *
    * @param productId  待查询的商品id
    * @param listener 回调信息
    */
   private void queryItemDetails(String productId, IQueryProductDetailListener listener)
package com.google.pay;

public interface IQueryProductDetailListener {

   /**
    * @param price    价格
    * @param currency 货币单位
    * @param other    商品名称
    */
   void querySuccess(long price, String currency, String other);

   /**
    * 查询失败,不存在该商品
    *
    * @param status
    * @param msg
    */
   void queryFailed(int status, String msg);

   /**
    * 查询失败
    */
   void queryIdNoExist();

}

调用购买方法


   /**
    * 用于购买商品
    *
    * @param context
    * @param productId Google play store 后台定义的商品的id。如果错误的话,将提示检索失败
    * @param payload   该字段随机生成一定长度的字符串,用于生成的订单支付成功后根据google返回的订单信息关联。
    */
   public void buyGoods(Activity context, String productId, String payload)

消耗商品的方法

/**
    * 该方法用户手动消耗购买的商品。默认情况下,购买成功后不消耗商品。需要调用该方法。
    * 下面三个参数都是Purchase获取到的。
    *
    * @param mPurchasingItemType  
    * @param purchaseData
    * @param dataSignature
    */
   public void consumeAsync(String mPurchasingItemType, String purchaseData, String dataSignature)

服务器校验流程

Purchase purchase = inventory.getPurchase(product);
Log.d(TAG, "Purchase state: " + purchase.getPurchaseState());
// 0 (purchased), 1 (canceled), or 2 (refunded).

处理退款校验参考链接

测试相关

www.jianshu.com/p/9d7f3dc7a…

其他问题说明

支付遭拒

1.1 应用商品可能违反了当地的政策,例如vpn在中东很多国家是违法的。 1.2 由于代理的vpn,ip频繁切换导致过银行风控 1.3 绑定的银行卡地址和google后台注册的地址不相符和,可以通过修改google的地址进行解决,但是该种方式很复杂,成功率很低。 1.4 出现支付遭拒的订单号客户端是由两串number构成的,如果是成功的情况,订单号是由GPA.number构成。 1.5 出现支付遭拒是一件正常的事情,我咨询过很多做游戏和应用的开发,在国外都有遇到支付遭拒的情况,应该能排查代码的问题。 1.6 手机设备root过,不能支付成功

关于绑定银行卡支付

  1. 如果使用真实货币支付,首先你需要一张支持外币的信用卡。例如mastcard,visa等。在绑定银行卡的过程中,你可能需要切换你的账单地址,否者很难绑定成功,总之,这个过程比较麻烦。测试支付可以添加测试账号测试。

不能弹出Google 支付的界面

  1. 你是否给Google Service显示悬浮框权限
  2. 该账号是否已经存在购买的商品,但是还未消耗,此时也不会弹出支付框

测试设备服务不支持

  1. google service版本太低,需要到应用商店的设置中,点击版本号,提示更新。这个过程有点慢,感觉点击没有反应,实际上是在后台下载。需要等一会儿,或者需要重启一下设备等。反正就是要让应用商店更新到最新的版本。否者会出现设备不支持google pay。

关于Google play store 升级

如果手机的Google 服务先关组件是通过三方安装,那么很有可能版本比较低。不支持支付的api version3. 此时需要对Google play stroe 进行升级。在菜单栏中-->设置-->点击版本号。然后点击确认。需要注意的是,点击确认后,手机可能看试没有反应。实际上在下载。根据网络情况,等一定时间,重启手机。应用就更新了。

初始化失败

如果Google服务的版本已经是最新了还出现出事话失败的情况,可以通过以下方式解决。

  1. 需要将手机中的google账号全部删除

  2. 然后把google service和google play商店中的缓存全部清理掉

  3. 重新登录账号。。

  4. 手机没有安装service相关组件,下载go安装器安装手机相关的组件,需要手动更新下,默认下载的版本有些老。

Demo地址

其他支付,包括微信,支付宝,支付宝外币,stripe等