微信代扣 Android 开发流程

最近几天采坑了微信代扣,开发流程很简单,但是官方文档实在缺少一个具体的指引,导致走了很多弯路,因此本文分享一下自己的经验。
微信代扣开发者文档: https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1

微信代扣 Android 开发流程_第1张图片
微信代付文档截图

上图是文档的网页截图,其中红框里的 SDK 需要配置一下,APP跳转签约页面方法指引 是外部唤起微信的方法,(话说这个入口我找了好久才发现,一把辛酸泪……)
文档很长,对于各个端做什么也没有明确描述,所以我站在 Android 端的角度,讲一下开发流程。总共分以下三步:

1、调用服务端接口进行签约
服务端接口的返回类型是自定义的 Contract 类,其中 contractIdcontractUrl 是 Android 端能用到的。(接口格式以你们服务端给的为准,此处仅供参考)

  //签约
  @POST("/xxx/contracts")
  Observable> getContract();

public class Contract {
    @JsonProperty("contract_id")
    public String contractId; // 微信给的签约合同号

    @JsonProperty("contract_url")
    public String contractUrl;// 可以调起微信的url

    @JsonProperty("product_id")
    public String productId; // IOS 会用到的 id,Android 端可以直接忽略
}

2、利用服务端返回的 contractUrl 调起微信签约付款页

private void toWeChatScan(String url) {
      try {
          WeChatPayUtil.pay(getActivity(), url);
      } catch (Exception e) {
          //若无法正常跳转,在此进行错误处理
          Toast.makeText(getContext(), "跳转到微信失败",Toast.LENGTH_SHORT).show();
      }
}
public class WeChatPayUtil {
    private static IWXAPI sWXAPI;
     /**
     * 微信代扣
     * @param pActivity
     * @param url
     * @return
     * @throws Exception
     */
    public static boolean pay(Activity pActivity, String url) throws Exception {
        if (sWXAPI == null) {
            sWXAPI = WXAPIFactory.createWXAPI(pActivity, WeChatHelper.WECHAT_APP_ID);
        }
        if (微信未安装) {
            ToastUtils.showLongToast(pActivity, R.string.toast_text_weixin_not_installed);
            return false;
        }
        toWechatContractPay(url);
        return true;
    }
    private static void toWechatContractPay(String url) {
        OpenWebview.Req req = new OpenWebview.Req();
        req.url = url;
        sWXAPI.sendReq(req);
    }
}

3、调用服务端接口轮询检查支付状态
微信代付的话,在微信中支付完成后,并不会同步返回结果给我们的 app,只会把支付结果通知我们的服务器,所以需要在我们的 app 中对服务器进行轮询来检查支付结果。
检查也不需要很多次,我们项目里是轮询 5 次,1 秒一次,已经足够了。
(接口格式以你们服务端给的为准,此处仅供参考)

    /**
     * 查看自动续费签约状态
     *
     * @param packageId
     * @param contractId
     * @return
     */
    @GET("/xxx/contracts/{contract_id}")
    Observable> getOrderStatus(@Path("contract_id") String contractId);

其中的 contract_id 是在步骤1中返回的,这里需要用这个合同号来检查状态。

public class OrderStatus {
    @JsonProperty("status")
    public String status;//granted, ungranted, pending, unsubscribed

    @JsonProperty("singed_at")
    public long singedAt;//签约成功的时间(这个只有在 granted 状态时才有效)

    @JsonProperty("contract_type")
    public String contractType;//wechat, iap

    @JsonProperty("withhold")
    public OrderStatusWithhold withhold;
}

public class OrderStatusWithhold {
    @JsonProperty("status")
    public String status;//<"created", "pending", "succeeded", "failed">

    @JsonProperty("error_message")
    public String errorMessage;

}

需要注意上面两个 status 代表不同的意义, orderStatus.status 是签约状态,而orderStatusWithhold.status 是扣款状态,有可能签约成功,但是扣款时因为余额不足等原因而失败。

附一个讲代扣整体过程的文章,要开发的话值得一看:
http://jverson.com/2015/12/20/wechat/

你可能感兴趣的:(微信代扣 Android 开发流程)