最近公司接入微信刷卡支付,网上根本没见到很直接的教程(可能眼拙),一直摸滚打爬,加班加点才走通,忍不了必须写一写
微信 刷卡支付/查询/撤销... 必须要有公众号然后去申请,申请自己去看文档,这里主要演示java对接代码
必要准备:
名称 | 变量名 | 示例 | 描述 |
公众账号ID | appid | wx8888888888888888 | 微信分配的公众账号ID,可在微信公众平台-->开发-->基本配置里面查看,商户的微信支付审核通过邮件中也会包含该字段值 |
商户号 | mch_id | 1900000109 | 微信支付分配的商户号 |
子商户号 | sub_mch_id | 1900000109 | 微信支付分配的子商户号,开发者模式下必填 |
证书路径 | certPath | x/xx/apiclient_cert.p12 | 本地证书 |
API密钥 | key | dyjs3tlWXCs1eBzs5ihGrmK8w0HdvXcR |
保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全-->密钥设置 |
这里用SSM框架
先导入微信的SDK (SKD下载点这里)
配置一个xxx.properties
1 //这里写的数据都是乱写的,不要暴露出去
2 wechat_appid=wx888888888888
3 wechat_mch_id=19000000000190
4 wechat_sub_mch_id=19000000000191
5 wechat_certPath=D:/cert/apiclient_cert.p12
6 wechat_key=adasdfsfwADEdDWw3E344Ee32
7 wechat_httpConnectionTimeoutMs=8000
8 wechat_httpReadTimeoutMs=10000
配置微信初始化的类 WechatPayConstants.java
1 package com.test.bean;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.InputStream;
7 import java.net.InetAddress;
8
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 import com.github.wxpay.sdk.WXPayConfig;
13 //这里要实现微信的配置
14 public class WechatPayConstants implements WXPayConfig{
15
16 public WechatPayConstants(String appId,String mchId,String subMchId,
17 String certPath,int httpConnectionTimeoutMs,int httpReadTimeoutMs,String key) throws Exception{
18 try {
19 File file = new File(certPath);
20 InputStream certStream = new FileInputStream(file);
21 this.certData = new byte[(int) file.length()];
22 certStream.read(this.certData);
23 certStream.close();
24 } catch (Exception e) {
25 Logger logger = LoggerFactory.getLogger( WechatPayConstants.class);
26 logger.info("文件:"+certPath+"没找到");
27 }
28 this.openApiDomain = openApiDomain;
29 this.appId = appId;
30 this.mchId = mchId;
31 this.subMchId = subMchId;
32 this.httpConnectionTimeoutMs = httpConnectionTimeoutMs;
33 this.httpReadTimeoutMs = httpReadTimeoutMs;
34 this.key = key;
35 this.serviceIP = InetAddress.getLocalHost().getHostAddress();
36 }
37
38 private byte[] certData;
39
40 private String appId;
41
42 private String mchId;
43
44 private String subMchId;
45
46 private String serviceIP;
47
48 private int httpConnectionTimeoutMs;//连接超时时间(毫秒)
49
50 private int httpReadTimeoutMs;//读取超时时间(毫秒)
51
52 private String key;
53 @Override
54 public String getAppID() {
55 return appId;
56 }
57
58 @Override
59 public String getMchID() {
60 return mchId;
61 }
62
63 public String getSubMchID() {
64 return subMchId;
65 }
66
67
68 public String getServiceIP(){
69 return serviceIP;
70 }
71
72 @Override
73 public InputStream getCertStream() {
74 ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
75 return certBis;
76 }
77
78 @Override
79 public int getHttpConnectTimeoutMs() {
80 return httpConnectionTimeoutMs;
81 }
82
83 @Override
84 public int getHttpReadTimeoutMs() {
85 return httpReadTimeoutMs;
86 }
87
88 @Override
89 public String getKey() {
90 return key;
91 }
92
93
94 }
配置spring-xxx.xml 进行初始化
1 <bean id="wechatPayConstants" class="com.test.bean.WechatPayConstants">
2 <constructor-arg index="0" value="${wechat_appid}"/>
3 <constructor-arg index="1" value="${wechat_mch_id}"/>
4 <constructor-arg index="2" value="${wechat_sub_mch_id}"/>
5 <constructor-arg index="3" value="${wechat_certPath}"/>
6 <constructor-arg index="4" value="${wechat_httpConnectionTimeoutMs}"/>
7 <constructor-arg index="5" value="${wechat_httpReadTimeoutMs}"/>
8 <constructor-arg index="6" value="${wechat_key}"/>
9 </bean>
10
11 <bean id="wxPay" class="com.github.wxpay.sdk.WXPay">
12 <constructor-arg ref="wechatPayConstants"/>
13 </bean>
实现层java代码
1 //这里只给实现方法--刷卡支付
2 @Autowired
3 private WechatPayConstants wechatPayConstants;
4
5 @Autowired
6 WXPay wxPay;
7
8 public String WXPayment(BigDecimal totalFee,authCode,out_trade_no){
9
10 Map<String, String> request = new HashMap<String,String>();
11 request.put("appid", wechatPayConstants.getAppID());
12 request.put("mch_id", wechatPayConstants.getMchID());
13 request.put("sub_mch_id", wechatPayConstants.getSubMchID());
14 request.put("nonce_str", System.currentTimeMillis() / 1000 + "");
15 request.put("body", "xxx店面消费");
16 request.put("out_trade_no",out_trade_no);
17 request.put("total_fee", totalFee.intValue());//金额单位:分
18 request.put("auth_code", authCode);
19 request.put("spbill_create_ip", wechatPayConstants.getServiceIP());
20 String sign = "";
21 try {
22 sign = WXPayUtil.generateSignedXml(request, "sign");
23 } catch (Exception e) {
24 e.printStackTrace();
25 }
26 request.put("sign", sign);
27 Map<String, String> response = null;
28 try {
29 response = wxPay.microPay(request);
30 } catch (Exception e) {
31 e.printStackTrace();
32 throw new Exception("网络错误,请重新支付");
33 }
34 if (response != null) {
35 String return_code = response.get("return_code");
36 if (!"SUCCESS".equals(return_code)){
37 return "通讯失败!"
38 }else{
39 String result_code = response.get("result_code");
40 if ("SUCCESS".equals(result_code)) {
41 return "支付成功!";
42 }else{
43 String err_code = response.get("err_code");
44 if ("USERPAYING".equals(err_code)) {
45 //支付中调查询接口
46 return queryWXPayment(out_trade_no,null);
47 }else{
48 return response.get("err_code_des");
49 }
50 }
51 }
52
53 }else{
54 return "网络传输异常";
55 }
56
57 }
1 //查询 实现 out_trade_no
2 @Override
3 public String queryWXPayment(String out_trade_no,String transaction_id) {
4 Map<String, String> request = new HashMap<String,String>();
5 request.put("appid", wechatPayConstants.getAppID());
6 request.put("mch_id", wechatPayConstants.getMchID());
7 request.put("sub_mch_id", wechatPayConstants.getSubMchID());
8 request.put("nonce_str", System.currentTimeMillis() / 1000 + "");
9 request.put("out_trade_no", out_trade_no);
10 if (!StringUtils.isBlank(transaction_id)) {
11 request.put("transaction_id", transaction_id);
12 }
13 String sign = "";
14 try {
15 sign = WXPayUtil.generateSignedXml(request, "sign");
16 } catch (Exception e) {
17 e.printStackTrace();
18 }
19 request.put("sign", sign);
20 Map<String, String> response = null;
21 try {
22 response = wxPay.orderQuery(request);
23 } catch (Exception e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 throw new QtException("订单查询失败");
27 }
28 if (response != null) {
29 String return_code = response.get("return_code");
30 String result_code = response.get("result_code");
31
32 if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {
33 if ("SUCCESS".equals(response.get("trade_state"))) {
34 return "支付成功";
35 }
36
37 } else if("REVOKED".equals(response.get("trade_state"))){
38 return "撤销成功";
39 }else{
40 //
41
42 }
43
44 }else{
45 return "网络通讯异常";
46 }
47
48 //这里写个超时处理,先判断支付时间和现在时间,再调用查询接口,建议使用短连接,返回支付中给前台,前台判断支付中继续发送查询接口,直到后台判断超时调用撤销接口
49 if(超时){
50 return cancelWXPayment(out_trade_no,transaction_id);
51 }else{
52 return "支付中";
53 }
54
55 }
//撤销
@Override
public String cancelWXPayment(String out_trade_no,String transaction_id) {
Map<String, String> request = new HashMap<String,String>();
request.put("appid", wechatPayConstants.getAppID());
request.put("mch_id", wechatPayConstants.getMchID());
request.put("sub_mch_id", wechatPayConstants.getSubMchID());
request.put("nonce_str", System.currentTimeMillis() / 1000 + "");
request.put("out_trade_no", out_trade_no);
if (!StringUtils.isBlank(transaction_id)) {
request.put("transaction_id", transaction_id);
}
String sign = "";
try {
sign = WXPayUtil.generateSignedXml(request, "sign");
} catch (Exception e) {
e.printStackTrace();
}
request.put("sign", sign);
Map<String, String> response = null;
try {
response = wxPay.reverse(request);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new Exception("撤销失败");
}
if (response != null) {
String return_code = response.get("return_code");
String result_code = response.get("result_code");
if(!"SUCCESS".equals(result_code)){
queryWXPayment(out_trade_no,transaction_id);
}else{
return "撤销成功";
}
}else{
return "网络通讯异常";
}
}
方法的实现自己定义,我这里图简单,只写了几个需要的,参数最好是一个对象,这里只是简单的举例子,以上
来源:oschina
链接:https://my.oschina.net/u/4356045/blog/4057727