java版微信支付/查询/撤销
2024-09-04 02:29:16
最近公司接入微信刷卡支付,网上根本没见到很直接的教程(可能眼拙),一直摸滚打爬,加班加点才走通,忍不了必须写一写
微信 刷卡支付/查询/撤销... 必须要有公众号然后去申请,申请自己去看文档,这里主要演示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
//这里写的数据都是乱写的,不要暴露出去
wechat_appid=wx888888888888
wechat_mch_id=19000000000190
wechat_sub_mch_id=19000000000191
wechat_certPath=D:/cert/apiclient_cert.p12
wechat_key=adasdfsfwADEdDWw3E344Ee32
7 wechat_httpConnectionTimeoutMs=8000
8 wechat_httpReadTimeoutMs=10000
配置微信初始化的类 WechatPayConstants.java
package com.test.bean; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.InetAddress; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.github.wxpay.sdk.WXPayConfig;
//这里要实现微信的配置
public class WechatPayConstants implements WXPayConfig{ public WechatPayConstants(String appId,String mchId,String subMchId,
String certPath,int httpConnectionTimeoutMs,int httpReadTimeoutMs,String key) throws Exception{
try {
File file = new File(certPath);
InputStream certStream = new FileInputStream(file);
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
} catch (Exception e) {
Logger logger = LoggerFactory.getLogger( WechatPayConstants.class);
logger.info("文件:"+certPath+"没找到");
}
this.openApiDomain = openApiDomain;
this.appId = appId;
this.mchId = mchId;
this.subMchId = subMchId;
this.httpConnectionTimeoutMs = httpConnectionTimeoutMs;
this.httpReadTimeoutMs = httpReadTimeoutMs;
this.key = key;
this.serviceIP = InetAddress.getLocalHost().getHostAddress();
} private byte[] certData; private String appId; private String mchId; private String subMchId; private String serviceIP; private int httpConnectionTimeoutMs;//连接超时时间(毫秒) private int httpReadTimeoutMs;//读取超时时间(毫秒) private String key;
@Override
public String getAppID() {
return appId;
} @Override
public String getMchID() {
return mchId;
} public String getSubMchID() {
return subMchId;
} public String getServiceIP(){
return serviceIP;
} @Override
public InputStream getCertStream() {
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;
} @Override
public int getHttpConnectTimeoutMs() {
return httpConnectionTimeoutMs;
} @Override
public int getHttpReadTimeoutMs() {
return httpReadTimeoutMs;
} @Override
public String getKey() {
return key;
} }
配置spring-xxx.xml 进行初始化
<bean id="wechatPayConstants" class="com.test.bean.WechatPayConstants">
<constructor-arg index="0" value="${wechat_appid}"/>
<constructor-arg index="1" value="${wechat_mch_id}"/>
<constructor-arg index="2" value="${wechat_sub_mch_id}"/>
<constructor-arg index="3" value="${wechat_certPath}"/>
<constructor-arg index="4" value="${wechat_httpConnectionTimeoutMs}"/>
<constructor-arg index="5" value="${wechat_httpReadTimeoutMs}"/>
<constructor-arg index="6" value="${wechat_key}"/>
</bean> <bean id="wxPay" class="com.github.wxpay.sdk.WXPay">
<constructor-arg ref="wechatPayConstants"/>
</bean>
实现层java代码
//这里只给实现方法--刷卡支付
@Autowired
private WechatPayConstants wechatPayConstants; @Autowired
WXPay wxPay; public String WXPayment(BigDecimal totalFee,authCode,out_trade_no){ 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("body", "xxx店面消费");
request.put("out_trade_no",out_trade_no);
request.put("total_fee", totalFee.intValue());//金额单位:分
request.put("auth_code", authCode);
request.put("spbill_create_ip", wechatPayConstants.getServiceIP());
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.microPay(request);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("网络错误,请重新支付");
}
if (response != null) {
String return_code = response.get("return_code");
if (!"SUCCESS".equals(return_code)){
return "通讯失败!"
}else{
String result_code = response.get("result_code");
if ("SUCCESS".equals(result_code)) {
return "支付成功!";
}else{
String err_code = response.get("err_code");
if ("USERPAYING".equals(err_code)) {
//支付中调查询接口
return queryWXPayment(out_trade_no,null);
}else{
return response.get("err_code_des");
}
}
} }else{
return "网络传输异常";
} }
//查询 实现 out_trade_no
@Override
public String queryWXPayment(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.orderQuery(request);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new QtException("订单查询失败");
}
if (response != null) {
String return_code = response.get("return_code");
String result_code = response.get("result_code"); if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {
if ("SUCCESS".equals(response.get("trade_state"))) {
return "支付成功";
} } else if("REVOKED".equals(response.get("trade_state"))){
return "撤销成功";
}else{
// } }else{
return "网络通讯异常";
} //这里写个超时处理,先判断支付时间和现在时间,再调用查询接口,建议使用短连接,返回支付中给前台,前台判断支付中继续发送查询接口,直到后台判断超时调用撤销接口
if(超时){
return cancelWXPayment(out_trade_no,transaction_id);
}else{
return "支付中";
} }
//撤销
@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 "网络通讯异常";
} }
方法的实现自己定义,我这里图简单,只写了几个需要的,参数最好是一个对象,这里只是简单的举例子,以上
最新文章
- AngularJS入门心得4——漫谈指令scope
- JavaScript函数之美~
- 请将 php.ini 中的 short_open_tag 设置为 On,否则无法继续安装。
- JavaScript实现绑定DOM的定时器插件
- HA(High available)-Keepalived高可用性集群(双机热备)单点实验-菜鸟入门级
- 自定义表并实现Identity登录(一)
- windows server 2008服务器IIS绑定阿里云域名
- 查看Linux版本系统信息方法汇总
- 本地或者是koala软件编译less文件为css
- POJ 3104 Drying(二分答案)
- HTML5 Web SQL Database 与 Indexed Database 的 CRUD 操作
- MSH:一个简单SH工具实现
- Promise对象的简单用法
- 在Visual Studio 2017上配置Glut
- mybatis中使用Integer类型的参数<;if>;判断问题
- Thinkphp5 captcha扩展包安装,验证码验证以及点击刷新
- 面试题fugui
- JDBC driver for MySQL连接提示";The connection property &#39;zeroDateTimeBehavior&#39; acceptable values are: &#39;CONVERT_TO_NULL&#39;, &#39;EXCEPTION&#39; or &#39;ROUND&#39;. The value &#39;convertToNull&#39; is not acceptable.";解决方案
- C#设计模式(3)——工厂方法模式(转)
- iview 刷新滞后于html问题
热门文章
- 【Linux】CentOS6上mysql5.7安装
- HDU-4185-Oil Skimming(最大匹配)
- springboot扫描自定义的servlet和filter代码详解_java - JAVA
- jvm——CodeCache
- 【leetcode】1191. K-Concatenation Maximum Sum
- 【leetcode】1186. Maximum Subarray Sum with One Deletion
- JS几种数组遍历方式总结
- jquery 3.1 tets
- Java面试题系列(六)优化tomcat配置
- SpringBoot2.2版本配置绑定