一、前言
本文介绍了微信发起支付的步骤和代码实例,如有不足的请提出,我会做出改正。
二、SDK下载安装
去微信官网下载sdk https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1,自己进行编译,然后引入依赖
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
三、发起支付
HttpClientTool 是我封装的工具类可自行封装,生成二维码用的谷歌 Google-Zxing
@RequestMapping(value = "/pay", method = RequestMethod.GET)
public void pay(HttpServletResponse response) throws Exception {
Map<String, String> params = new HashMap<>();
params.put("appid", "公众号appid");
params.put("mch_id", "商户号");
params.put("nonce_str", WXPayUtil.generateNonceStr());
params.put("body", "这是一笔测试订单");
params.put("out_trade_no", WXPayUtil.generateNonceStr());
params.put("total_fee", "10");
params.put("spbill_create_ip", "127.0.0.1");
params.put("notify_url", "回调地址");
params.put("trade_type", "NATIVE");
params.put("device_info","WEB");
String sign = WXPayUtil.generateSignature(params, "商户key");
params.put("sign", sign);
//map转xml,请求微信统一下单接口,并获取微信返回结果,进行xml转map 得到codeurl
String payXml = WXPayUtil.mapToXml(params);
String orderStr = HttpClientTool.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", payXml, "UTF-8");
Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
String codeUrl = unifiedOrderMap.get("code_url");
//生成二维码并输出
try{
Map<EncodeHintType,Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE,400,400,hints);
OutputStream out = response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,"png",out);
}catch (Exception e){
e.printStackTrace();
}
}
四、支付回调
在处理业务逻辑的时候,必须能够正确处理重复的通知
@RequestMapping(value = "/pay/callback")
public String orderCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
String fail="<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[FAIL]]></return_msg></xml>";
String success="<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
InputStream inputStream = request.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
StringBuilder sb = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
inputStream.close();
Map<String, String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
boolean signatureValid = WXPayUtil.isSignatureValid(callbackMap, "商户key");
if ("SUCCESS".equals(callbackMap.get("return_code")) && signatureValid == true){
return success;
}
return fail;
}