微信扫码登录
1.准备工作
1.需要appid
商户号
app秘钥
key 发送给微信官方对参数进行校验的key
回调地址
4大基础配置
2.申请开通微信扫码支付
2.大体流程
1.拿着组装好的参数去微信发送请求,拿到返回的code_url(就是二维码中的链接)
2.用谷歌的工具生成的二维码响应给前端
3.回调函数中处理业务逻辑,支付以后修改状态等
4.前端查询支付结果,拿着生成订单的订单号轮询访问接口,获取他的状态,根据状态修改对应的逻辑
5.微信的金额为分,建议数据库存储分
6.微信回调函数中,该方法头上必须为 @RequestMapping("/xyNavicatCallback")
3.代码实现
1.微信扫码统一下单请求
private String unfiedOrder(XyOrder order,HttpServletRequest request,String goodBodyName) throws Exception {
BigDecimal ordPrice = order.getOrderPrice();
SortedMap<String,String> PARAMS = new TreeMap<>();
PARAMS.put("appid", ConfigUtil.APPID);
PARAMS.put("mch_id",ConfigUtil.MCH_ID);
PARAMS.put("nonce_str", CommonUtilsYpl.generateUUID());
PARAMS.put("body",goodBodyName);
PARAMS.put("out_trade_no",order.getOrderNumber());
PARAMS.put("total_fee","1");
String ip = IpUtils.getIpAddr(request);
log.info("我是ip地址"+ip);
PARAMS.put("spbill_create_ip",ip);
PARAMS.put("notify_url",ConfigUtil.NOTIFY_URL);
PARAMS.put("trade_type", "NATIVE");
PARAMS.put("attach", ip);
String sign = WXPayUtil.createSign(PARAMS,ConfigUtil.API_KEY);
PARAMS.put("sign",sign);
String payXml = WXPayUtil.mapToXml(PARAMS);
System.out.println("我是发送的xml"+payXml);
String orderStr = HttpUtilsYpl.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder",payXml,4000);
String s2 = new String(orderStr.getBytes(ISO_8859_1),"utf-8");
log.info("我是微信返回的数据"+s2);
if(null == orderStr){
return null;
}
Map<String,String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
System.out.println("我是xml转换成map的返回值:"+unifiedOrderMap);
if (unifiedOrderMap!=null){
return unifiedOrderMap.get("code_url");
}
return null;
}
2.微信回调结果
@RequestMapping("/xyNavicatCallback")
public Object xyCallBack(HttpServletResponse response, HttpServletRequest request) throws Exception {
InputStream inputStream = request.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
StringBuffer sb = new StringBuffer();
String line;
while ((line = in.readLine())!=null){
sb.append(line);
}
in.close();
inputStream.close();
Map<String,String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
log.info("我是转换后的数据" +callbackMap.toString());
SortedMap<String, String> sortedMap = WXPayUtil.getSortedMap(callbackMap);
if (WXPayUtil.isCorrectSign(sortedMap,ConfigUtil.API_KEY)){
if ("SUCCESS".equals(sortedMap.get("result_code"))){
String outTradeNo = sortedMap.get("out_trade_no");
String ip = sortedMap.get("attach");
String payNum = sortedMap.get("transaction_id");
log.info("走回调了");
List<XyOrder> list = xyOrderService.selectXyOrderByOrderNo(outTradeNo);
if (!list.isEmpty())
{
int row = 0;
for (XyOrder order : list)
{
if(order!=null && order.getStatus() ==0){
order.setIp(ip);
order.setPayNum(payNum);
order.setOpenId(sortedMap.get("openid"));
order.setStatus(1);
order.setPayTime(new Date());
row = xyOrderService.updateXyOrder(order);
}
}
if (row >=1){
response.setContentType("text/html");
response.getWriter().print("success");
return null;
}
}
}
}
response.setContentType("text/html");
response.getWriter().print("fail");
return null;
}
3.生成前端需要扫码的二维码
@GetMapping("/add")
public void order(Long orderId, String goodBodyName, HttpServletResponse response, HttpServletRequest request) throws Exception {
XyOrder order = xyOrderService.selectXyOrderById(orderId);
String code_url = unfiedOrder(order,request,goodBodyName);
if (code_url == null){
throw new LogicException("没有拿微信的code_url");
}
try{
Map<EncodeHintType,Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter()
.encode(code_url,
BarcodeFormat.QR_CODE,400,400,hints);
OutputStream outputStream = response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,"png",outputStream);
}catch (Exception e){
e.printStackTrace();
}
}
4.前端轮询查询支付结果的接口
@GetMapping("/selectByStatus")
public Object selectByStatus(String orderNumber){
List<XyOrder> xyOrders = xyOrderService.selectByStatus(orderNumber);
return xyOrders.get(0).getStatus();
}