java版微信支付/查询/撤销

半世苍凉 提交于 2020-05-04 04:56:28

最近公司接入微信刷卡支付,网上根本没见到很直接的教程(可能眼拙),一直摸滚打爬,加班加点才走通,忍不了必须写一写

微信 刷卡支付/查询/撤销... 必须要有公众号然后去申请,申请自己去看文档,这里主要演示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 }
View Code

 

配置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>
View Code

实现层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 }
View Code
 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     }
View Code
//撤销 
@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 "网络通讯异常";
}



}

方法的实现自己定义,我这里图简单,只写了几个需要的,参数最好是一个对象,这里只是简单的举例子,以上

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!