微信扫码支付手把手教学
专栏: 220908-小班辅导 标签: 微信支付 扫码支付
2022-10-15 08:31:42 1424浏览
官网api在线文档
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
1.需要提前准备的几个重要参数
微信支付必须是注册商家才行,得有营业执照。下面的参数登陆你的企业微信公众号后台去获取,

2.新建一个WXPayConfig实现类
由于我们要做的是扫码支付,而扫码支付不需要验证证书,所以下面的方法里getCertStream可以直接返回null,但getWXPayDomain必须自定义写哦。
package com.github.wxpay.sdk;
import com.github.wxpay.sdk.config.WXpayConfig;
import java.io.*;
public class WXPayConfigImpl extends WXPayConfig {
private byte[] certData;
// public WXPayConfigImpl() throws IOException {
// String certPath = "D:/apiclient_cert.p12";
// File file = new File(certPath);
// InputStream certStream = new FileInputStream(file);
// this.certData = new byte[(int) file.length()];
// certStream.read(this.certData);
// certStream.close();
// }
@Override
public String getAppID() {
return WXpayConfig.getProperties("appid");
}
@Override
public String getMchID() {
return WXpayConfig.getProperties("mch_id");
}
@Override
public String getKey() {
return WXpayConfig.getProperties("mchKey");
}
public String getTradeType(){
return WXpayConfig.getProperties("trade_type");
}
@Override
InputStream getCertStream() {
/*ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;*/
return null;
}
@Override
IWXPayDomain getWXPayDomain() {
IWXPayDomain iwxPayDomain = new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return iwxPayDomain;
}
}
3. 写一个统一下单接口返回二维码到前端
@WebServlet("/order")
public class OrderServlet extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
try {
WXPayConfigImpl config = new WXPayConfigImpl();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
data.put("appid", config.getAppID());
data.put("mch_id", config.getMchID());
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("body", req.getParameter("orderName"));
data.put("out_trade_no", req.getParameter("orderNo"));
data.put("total_fee", "1");
data.put("spbill_create_ip", "123.12.12.123");
data.put("notify_url", "http://tf5i8v.natappfree.cc/wxpay_sdk/OrderNotify");
data.put("trade_type", config.getTradeType());/** wxPay.unifiedOrder 这个方法中调用微信统一下单接口 */
String sign = WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.HMACSHA256); /* 签名*/
data.put("sign", sign);
Map<String, String> respData = wxpay.unifiedOrder(data);
System.out.println("**************wx qr pay***********************************");
System.out.println(respData);
if (respData.get("return_code").equals("SUCCESS") && respData.get("return_msg").equals("OK")){
Map<String,String> codeurlMap = new HashMap<>();
codeurlMap.put("code_url",respData.get("code_url"));
res.getWriter().write(JSON.toJSONString(codeurlMap));/*返回二维码的支付参数*/
res.getWriter().flush();
res.getWriter().close();
}else{
res.getWriter().write("");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}4.支付回调接口
@WebServlet("/OrderNotify")
public class OrderNotify extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream in = req.getInputStream();
BufferedReader br = new BufferedReader( new InputStreamReader( in, "UTF-8" ) );
StringBuffer result = new StringBuffer();
String line = "";
while ( (line = br.readLine())!= null )
{
result.append(line);
}
in.close();
br.close();
try {
Map<String, String> map = WXPayUtil.xmlToMap( result.toString() );
System.out.println("===问答=微信扫码支付回调=购买金币=====================================");
String mch_id=map.get("mch_id");
String appid=map.get("appid");
boolean flag = WXPayUtil.isSignatureValid(map, WXpayConfig.getProperties("mchKey"),HMACSHA256);
if(flag){
if(map.get("result_code").equals("SUCCESS")) {
//修改订单状态啥的。
String orderNo = map.get("out_trade_no");//商户订单
String transaction_id = map.get("transaction_id");//交易订单号
//告诉微信这边已经收到通知了'
Map<String,String> returnMap = new HashMap<>();
returnMap.put("return_code","SUCCESS");
returnMap.put("return_msg","OK");
String xml = WXPayUtil.generateSignedXml(returnMap, WXpayConfig.getProperties("mchKey"), HMACSHA256);
resp.getWriter().write(xml);
resp.getWriter().flush();
resp.getWriter().close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}5.注意事项
- 注意这个xml安全机制
微信支付的安全机制:所有请求参数通过ASSIC排序后(abcde的顺序),在末尾添加微信支付秘钥(key),然后把封装好的字符串通过MD5或SHA256方式加密。微信接收到请求信息之后会先把你传递过来的参数重新排序,加密,然后拿2个加密后的字符串做对比,如果匹配证明数据无误,此时的秘钥只有你知,微信知,不能透露给其他无关用户。
- 支付回调验签总是失败
原因是:下单的时候默认是用HMACSHA256的加密方式,而验签的时候默认是MD5加密方式,所以我这里的加密方式全部改成了HMACSHA256就可以了。

- 支付回调重复调用的问题
已经告诉微信这边进回调了,但微信还是一直发请求过来,原因是给微信返回的必须是xml格式的数据,而且还必须加签加密后再传。


4,主要的参考文档:
好博客就要一起分享哦!分享海报

新业务
springboot学习
ssm框架课
vue学习
【带小白】java基础速成