关于如何开通微信支付大家可以直接去【微信支付】官网查阅。这里我们直接进入正题。
public static WeixinPayResult createNative(String callbackUrl, String app_id, String mch_id, String api_key, String out_trade_no, Integer total_fee, String body) {
//1.参数封装
Map param = new HashMap();
param.put("appid", app_id);//公众账号ID
param.put("mch_id", mch_id);//商户
param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
param.put("body", body);
param.put("out_trade_no", out_trade_no);//交易订单号(是由系统内部来生成)
param.put("total_fee", total_fee.toString());//金额(分)
param.put("spbill_create_ip", "127.0.0.1");//支付客户端的IP地址(这里没做记录)
param.put("notify_url", callbackUrl);
param.put("trade_type", "NATIVE");//交易类型
try {
//根据appkey来生成签名,并同时将参数进行转换为xml格式
String xmlParam = WXPayUtil.generateSignedXml(param, api_key);
//2.发送请求(按照官方接口要求,将数据以post请求方式发送)
HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
httpClient.setHttps(true);//以https的协议发送请求
httpClient.setXmlParam(xmlParam);//设置post请求的参数列表
httpClient.post();
//3.获取结果
String xmlResult = httpClient.getContent();
Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
//将返回的结果转换为对象
WeixinPayResult weixinPayResult = new WeixinPayResult();
//防止进行bean复制时,日期为null时报错
ConvertUtils.register(new DateConverter(null), Date.class);
BeanUtils.copyProperties(weixinPayResult, mapResult);
//注意:付款订单编号是后台动态生成,必须要手动添加到返回结果中 勿忘,切记!!!
weixinPayResult.setOut_trade_no(out_trade_no);
return weixinPayResult;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
WXPayUtil.java
代码需要导入微信支付开发的pom坐标
<dependency>
<groupId>com.github.wxpaygroupId>
<artifactId>wxpay-sdkartifactId>
<version>0.0.3version>
dependency>
<dependency>
<groupId>com.thoughtworks.xstreamgroupId>
<artifactId>xstreamartifactId>
<version>1.4.10version>
dependency>
public static WeixinPayResult queryPayStatus(String app_id, String mch_id, String api_key, String out_trade_no) {
Map resultMap = new HashMap();
//1.封装参数
Map param = new HashMap();
param.put("appid", app_id);//appid
param.put("mch_id", mch_id);//商户ID
param.put("out_trade_no", out_trade_no);//要查询的订单号(自己系统所生成订单号)
param.put("nonce_str", WXPayUtil.generateNonceStr());
try {
String xmlParam = WXPayUtil.generateSignedXml(param, api_key);
//2.发送请求
HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
httpClient.setHttps(true);
httpClient.setXmlParam(xmlParam);
httpClient.post();
//3.获取结果
String xmlResult = httpClient.getContent();
Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
//封装结果数据
WeixinPayResult weixinPayResult = new WeixinPayResult();
//防止进行bean复制时,日期为null时报错
ConvertUtils.register(new DateConverter(null), Date.class);
BeanUtils.copyProperties(weixinPayResult, mapResult);
return weixinPayResult;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
相信很多新手在使用【微信支付】接口时,都会选择在前端设置定时器来间隔查询,如果查询到订单状态为【支付成功】再走生成订单的流程。如这种方法的操作是非常错误的,而且还有非常多的安全隐患。
你没看错,流程图也没画错。其实正确的付款支付接口时,生成的付款码和查询订单支付状态是两个完全独立的操作。
防止有些朋友不知道回调方法怎么写,这里也贴出回调方法的实现
callbackUrl: http://你服务器的回调方法根路径/callbackpay
/**
* 微信支付成功后的回调函数
*/
@RequestMapping("/callbackpay")
public Result callbackPay(HttpServletRequest request) {
StringBuffer sb = new StringBuffer();
try {
List<String> readLines = IOUtils.readLines(request.getInputStream(), "utf-8");
for (String readLine : readLines) {
sb.append(readLine);
}
Map<String, String> mapResult = WXPayUtil.xmlToMap(sb.toString());
//防止进行bean复制时,日期为null时报错
ConvertUtils.register(new DateConverter(null), Date.class);
WeixinPayResult weixinPayResult = new WeixinPayResult();
BeanUtils.copyProperties(weixinPayResult, mapResult);
return weixinPayService.callbackPay(weixinPayResult);//这行代码是调用业务层的付款成功后的处理逻辑
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "服务器异常");
}
}
注意:最后提醒一下,上面这个回调方法的url,一定要记得在你的权限框架中放行。
下一章会介绍【微信支付----- 微信红包和企业付款到微信用户零钱】