微信代扣 Android 开发流程

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

微信代付文档截图

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

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

  //签约
  @POST("/xxx/contracts")
  Observable<Response<Contract>> 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<Response<OrderStatus>> 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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,828评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,953评论 25 709
  • 因为筹备三亚的摄影基地需要大量资金,这两天让北京的房产公司出售公寓和商铺,由于北京的限购政策要求只有公司才能购买商...
    一世惊鸿阅读 721评论 0 0
  • 父亲把一件价值10块钱的衣服,交给孩子“你要把衣服卖出去,卖到20元”孩子一脸诧异,但看到贫穷的家境,他想为家庭做...
    永远的mark阅读 3,339评论 0 2
  • 相信大家对大年初二的习俗都不陌生,在这一天,大半个中国已经出嫁的女儿都要回娘家,老家也不例外。 初二这一天,已经出...
    8c8392d58a4a阅读 2,726评论 1 0

友情链接更多精彩内容