微信支付开发总结

  前期做过支付宝的支付相关,近期需要做微信支付,总体来讲并不是那么难,将思路总结一下,还有一些遇到的问题说一下:

  首先说怎么去设计

  微信支付、支付宝支付以及一些第三方系统的接口调用,他们是独立于我们系统的,但又需要用到,那么我们就尽量将这些独立系统的接口与我们的解耦开来,不要过多的耦合在一起,对于这类的结合建议独立写一个工具或者service来封装调用,这些接口或工具方法的入参和出参完全按照第三方的接口文档中的必用参数封装对象,
然后就可以当我们的业务中用到了就去制定参数给他传参,得到返回结果。应用到我们系统中
其实官网demo中已经提供了充足的工具,我们可以用demo中的封装类也可以不用自己封装,但是其中的工具类签名,xml解析等可以借鉴,有些也可以网上找一些xml字符串的post调用工具等。

我用到的xmlstr post工具

public static String creatXmlPostAndTransData(String urlStr,String xmlInfo) {
        String line = "";
        StringBuffer resultSting = new StringBuffer();
        try {
            //声明URL
            URL url = new URL(urlStr);
            //1.创建链接
            URLConnection con = url.openConnection();
            //2.封装报文传输进行传输
            //调用getXmlInfo(Map<String, Object> dataMap)进行报文的封装
            byte[] xmlData = xmlInfo.getBytes();
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setRequestProperty("Cache-Control", "no-cache");
            con.setRequestProperty("Content-Type", "text/xml");
            con.setRequestProperty("Content-length",String.valueOf(xmlData.length));
            OutputStreamWriter out = new OutputStreamWriter(
                    con.getOutputStream());
            System.out.println(">>>>>>>>>>接口地址为urlStr=" + urlStr);
//            System.out.println(">>>>>>>>>>传入的报文xmlInfo=" + xmlInfo);
            out.write(new String(xmlInfo.getBytes("ISO-8859-1")));
            out.flush();
            out.close();
            //3.获取返回报文
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            //对返回值报文进行打印
            for (line = br.readLine(); line != null; line = br.readLine()) {
                //对返回的报文进行结果判断<RspCode>0000</RspCode>
//                System.out.println(">>>>>>>>>>>>>>>>>>>返回的结果报文内容为:---------"+line);
                //对返回的报文进行拼接,然后返回给业务层,在业务层进行判断
                resultSting.append(line);
            }
            return resultSting.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultSting.toString();
    }

下面对官方的支付流程做些说明:

1、小程序内调用登录接口,获取到用户的openid,调用登陆接口wx.login(Object object)获取登陆凭证code,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key)等

2、商户server调用支付统一下单,调用pay/unifiedorder
本次签名也需要sign字段参与,该接口后台与下一步3合并直接返回给小程序端请求支付的参数

3、商户server调用再次签名,api参见公共api【再次签名】小程序调起支付API,调用wx.requestPayment(OBJECT)发起微信支付
本次签名也需要sign字段参与

4、商户server接收支付通知,api参见公共api【支付结果通知API】
验证签名不需要sign字段参与

5、商户server查询支付结果,api参见公共api【查询订单API】

签名规则写的比较清楚,认真理解即可

微信支付接口中,支付下单不需要证书,涉及资金回滚的接口会使用到API证书,包括退款、撤销接口。商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全 。

验证签名错误时可以采用官方的在线工具校验

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1

 我在调用签名时候,验证通过,但是仍然报签名错误,最终竟然是因为编码问题,把商品描述由中文改为英文后ok,下面是网上看到的一些签名错误的可能原因

1) 使用微信的在线签名工具检查签名是否和程序生成的一致

https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1 签名工具用谷歌打开。

选择MD5,XML,然后把请求参数xml放进去,就能校验签名。

2)如果和微信的在线签名工具一致,说明程序没有错误,确定是API密钥错误(被别人改动或者记错了)

在商户平台的账户信息中更改API密钥(账户设置-安全设置-API安全), 15分钟后生效

2.1)统一下单用的是A商户号,也必须是A商户号登陆商户平台设置key才对。

2.2)要注意统一下单请求参数中total_fee参数的类型是int类型。

3) 如果和微信的在线签名工具不一致,说明程序有错误,常见的错误可能是:

3.1) 编码问题,确保所有的都是utf-8的. 如果有中文, 可以先把中文改成英文重新签名,看是否签名错误,如果英文不会错中文才会错,基本肯定是编码问题

3.2:)消息中字段大小写和文档中完全一致

原文地址:https://www.cnblogs.com/xiaoyao-001/p/13099678.html