这里只介绍了微信支付中的Native支付,并只介绍了如何生成二维码,即时序图中的第2步到第4步
官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1
一、时序图
二、参数
官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
1. 请求参数
必填的都得填,将请求参数放到map集合中,这里说一下几个需要注意的地方:
- total_fee:标价金额,参数类型为Int,要求传递的金额为整数,单位为分
- nonce_str:随机字符串,随机字符串,长度要求在32位以内。使用微信SDK中的
WXPayUtil.generateNonceStr()
方法生成 - sign:签名,根据前面的所有参数,通过签名算法计算得出的签名值,
WXPayUtil.generateSignature(req请求参数map集合, key)
- 请求参数以 xml 的格式发送。
WXPayUtil.mapToXml(请求参数map集合)
2. 响应参数
- code_url:Native 支付时有返回,此url用于生成支付二维码,然后提供给用户进行扫码支付。
- 响应参数以 xml 格式返回,微信SDK提供了方法将 xml 字符串转换为 map 集合:
WXPayUtil.xmlToMap(xml字符串);
三、实现
1. 获取url
@RequestMapping("/api/wxpay")
@ResponseBody
public Object wxpay(String body,
String out_trade_no,
String total_feer) throws Exception {
//请求参数map
Map<String, String> reqParamMap = new HashMap<>();
reqParamMap.put("appid", "自己指定");
reqParamMap.put("mch_id", "自己指定");
reqParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
reqParamMap.put("body", body);
reqParamMap.put("out_trade_no", out_trade_no);
BigDecimal bigDecimal = new BigDecimal(total_feer);
BigDecimal multiply = bigDecimal.multiply(new BigDecimal(100));
reqParamMap.put("total_fee", multiply.toBigInteger().toString());
reqParamMap.put("spbill_create_ip", "127.0.0.1");
reqParamMap.put("notify_url", "http://localhost:9090/pay/api/wxpayNotity");
reqParamMap.put("trade_type","NATIVE");
reqParamMap.put("product_id", out_trade_no);
String sign = WXPayUtil.generateSignature(reqParamMap, "指定自己的key");
reqParamMap.put("sign", sign);
String requestDataXml = WXPayUtil.mapToXml(reqParamMap);
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
String result = "";
try {
//创建httpClient实例
httpClient = HttpClients.createDefault();
//创建httpPost远程连接实例
HttpPost httpPost = new HttpPost(url);
//配置请求参数实例
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(35000)//设置连接主机服务超时时间
.setConnectionRequestTimeout(35000)//设置连接请求超时时间
.setSocketTimeout(60000)//设置读取数据连接超时时间
.build();
//为httpPost实例设置配置
httpPost.setConfig(requestConfig);
//设置请求参数
httpPost.setEntity(new StringEntity(requestDataXml, "UTF-8"));
//设置请求头内容
httpPost.addHeader("Content-Type", "text/xml");
//执行post请求得到返回对象
response = httpClient.execute(httpPost);
//通过返回对象获取数据
HttpEntity entity = response.getEntity();
//将返回的数据转换为字符串
result = EntityUtils.toString(entity);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭资源
if (null != response) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Map<String, String> respParamMap = WXPayUtil.xmlToMap(result);
return respParamMap;
}
2. 生成二维码
这里使用的是google生成二维码的jar包,相关依赖:
注意:编译器要在1.6以上,默认为1.5
<dependencys>
<!-- google生成二维码依赖 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
</dependencys>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
代码实现:
@RequestMapping("/loan/gererateQRCode")
public void generateQRCode(HttpServletRequest request, HttpServletResponse response,
String out_trade_no,
String total_amount) throws Exception {
Map<String ,Object> map = new HashMap<>();
map.put("out_trade_no", out_trade_no);
map.put("total_feer", total_amount);
map.put("body", "微信支付");
//这里调用上面1中的方法,获取json字符串,HttpClientUtils是我封装的一个工具类,只要知道这句话是调用上面3.1中的方法即可
String jsonStr = HttpClientUtils.doPost("http://localhost:9094/pay/api/wxpay", map);
//解析JSON字符串
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
String return_code = jsonObject.getString("return_code");
if (!StringUtils.equals(return_code, "SUCCESS")) {
//响应不成功相应的处理
}
String result_code = jsonObject.getString("result_code");
if (!StringUtils.equals(result_code, "SUCCESS")) {
//请求不成功相应的处理
}
//获取url
String code_url = jsonObject.getString("code_url");
//生成二维码
//map中存放的是生成二维码的参数
Map<EncodeHintType,Object> map2 = new HashMap<EncodeHintType, Object>();
map2.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//生成二维码,参数依次是:二维码内容,二维码编码方式,长,宽,参数
BitMatrix encode = new MultiFormatWriter().encode(code_url, BarcodeFormat.QR_CODE, 200, 200, map2);
//获取输出流,响应到前台
OutputStream out = response.getOutputStream();
MatrixToImageWriter.writeToStream(encode,"jpg",out);
out.flush();
out.close();
}