前言:该项目是源于二次接手,部分项目支付的配置已经搭建完成,主要负责调试,第一次接手支付模块,本项目是基于web端的扫码支付,与退款(没有涉及到部分退款,只涉及全退)
1.准备工作
申请到商家的账户时要获取以下参数
这些都是在注册的时候拿到的 (还有参数sign_key)
notify_url : 是扫码支付完微信会返回给你支付后的信息(例如:是否支付成功,支付方式,单号等等)
Unified_Order_URL : 微信支付时的接口 (全网统一的接口,天王老子用微信支付也是这个接口,因为它是用你上面注册的时候的商户ID等信息来判断的)
Unfiled_refund_URL : 微信退款时的接口(和支付接口原因一样)
注意 :上面这张图是将这些信息写到了配置文件yml中,并且写在配置文件中,方便高可用性
2. 然后就是开始写与微信链接的业务
- a. 首先在控制层创建一个接口,返回类型 R 或者 void ,参数 订单信息 (这里如何你这边返回的是 R 类型,你这边就要将二维码信息转为字符串 ,void 的话不需要,在postman测试时会返回二维码图片,建议转为字符串封装到 R 中,方便前端处理)
- b. 在service层中给 传给微信返回支付二维码信息时 的参数赋值(传出的具体参数建议官网,将传的参数以key value 的形式封装到map中)
下面是格式也是为什么封装到map中的原因
这里有一些坑:微信支付的钱的单位是 “分” ,不是 “元”,需要 ×100,(例如1元的话,转为100分);单号 "out_trade_no" 是 32 位以内 ,以上两个在支付宝那边是不存在的;还有就是回调的路径 “notify_url” 必须是外网可以访问到的 (这里你可以部署到测试服务器,或者使用 “花生壳” 应用做内网穿透 ,做映射可以让外网可以访问到) - 这里还有一个参数 sign 需要上面的信息用MD5加密后赋给 sign ,
要导入这个类 WXPayUtil 这个类里面封装了MD5加密的方法String signature = WXPayUtil.generateSignature(map, weiXinPayConfig.getSign_key()); 参数:map就是上面填的信息 getSign_key 就是在商户注册时的sign_key
然后也将 sign = signature 放到之前的map中 - 最后将map 转成xml的字符串
String requestDataXml = WXPayUtil.mapToXml(map);
- 补充:WXPayUtil 需要引入jar包
-
<dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency>
3. 与微信那边建立连接获取微信返回的支付数据
String returnXml = HttpClientUtils.doPostByXml(weiXinPayConfig.getUnified_Order_URL(), requestDataXml); 参数 order_url 微信下单的连接(全网统一) requestDataXml 上面map转xml的字符串
4. 微信返回的数据转换
a.首先,第一步判断返回的状态信息
是否响应成功 return_code 参数是由转换为map的一个参数 ,当SUCCESS是为成功
可以参考微信文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 来判断信息
b.第二步就可以处理自己的业务逻辑(也可以在微信回调成功之后处理业务逻辑,但要注意如果因为超时等多种情况,导致回调多次,从而业务处理多次,注意!!!!)
5.业务处理回调
这是当你支付后微信会向你的接口发出回调接口,该接口一定是外网可以访问到的接口,如果没有处理微信会发多次回调信息给该接口
将以下的回调信息相应给微信
String resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
out.write(resXml.getBytes());
这里不知道为什么直接返回字符串不可以,我这边就将它转为了字节流相应给微信