此次流程预览:
- 跳转二维码页面,用户扫码支付
- 通过内网映射工具EchoSite(通过域名访问),完成微信自动回调 (通知业务系统支付完成。但这个地址必须是互联网可以访问的)
- 3 .推送支付通知 () 支付成功,通过rabbitMQ 加入stomp插件 浏览器监听消息 完成用户支付完成自动跳转支付成功页面
详解:
- 首先,用户,添加了商品到购物车,访问到购物车进行订单的结算,用户点击立即结算会跳转到结算页面,页面会统计用户所选商品的总金额,用户点击提交订单会携带订单的orderId去访问我们web_order服务的add方法,进行远程调用order服务的添加订单的方法,并且同时扣减库存.获取登录人的名称,用工具类从jwt令牌中获取,传入order实体,在service层通过用户名获取redis存储的购物车信息,然后根据购物车中的信息完成订单表的添加,同时扣减库存,然后删除封装到redis的订单信息,返回用户的id.
<a class="sui-btn btn-danger btn-xlarge" href="javascript:void(0)" @click="add()">提交订单</a>
//获取登录人的名称
String username = tokenDecode.getUserInfo().get("username");
- 前端拿到订单的id了之后携带id跳转到选择支付方式页面,我们通过feign的远程调用,拿到总金额,在页面显示各种支付方式图标,我们会给微信图标一个点击事件,点击微信支付,就会去访问请求微信二维码页面.我们会通过feign的远程根据orderid查询订单, 不存在跳转错误页面,根据订单的支付状态判断,如果不是未支付的订单,返回错误页面,如果都不是就去通过用过远程调用统一下单的接口,接口中通过微信支付文档中提供的微信接口去完成统一下单接口的调用,我们会给他一个通知地址,这个地址就是支付成功会自动调用的地址.拿到微信返回的结果后,返回到前端页面,展示微信二维码
这里的code_url是微信返回的页面展示路径
let qrcode = new QRCode(document.getElementById("qrcode"), {
width : 240,
height : 240
});
/* 二维码*/
qrcode.makeCode([[${code_url}]]);
-
为了保证用户一扫码我们就能马上得到消息并且告知用户支付成功的消息,我们采用了RabbitMQ Web STOMP 插件,实现浏览器与服务端的全双工通信
mq.png - 我们先在rabbitmq中安装好插件之后,修改我们的前端页面,去监听paynotify队列 设置mq的地址,接收消息.当用户一旦扫码后,会将消息回调发送到我们指定的地址去.拿到回调的订单id,查询订单,如果微信返回的是成功的,我们就发送流水号到双向通信的队列.
- 一旦监听到队列中有消息,会去获取消息,然后请求跳转支付成功页面,将总金额设置到model中,带到支付成功页面进行展示即可.
前端:
let client = Stomp.client('ws://192.168.200.128:15674/ws');
let on_connect = function(x) {
/* 监听交换机和队列*/
id = client.subscribe("/exchange/paynotify", function(d) {
/*接收队列中的消息*/
alert(d.body);
let orderId = [[${orderId}]]
if(d.body==orderId){
location.href="/api/wxpay/toPaySuccess?payMoney="+[[${payMoney}]]
}
});
};
let on_error = function() {
console.log('error');
};
/*
mq的账号和密码
* */
client.connect('guest', 'guest', on_connect, on_error, '/');
微信自动回调的接口:
@RequestMapping("/notify")
public void notifyLogic(HttpServletRequest request , HttpServletResponse response){
System.out.println("成功");
try {
//输出流转换为字符串 微信给我们返回的
String xml = ConvertUtils.convertToString(request.getInputStream());
System.out.println(xml);
//基于微信发送的通知内容,完成后续的业务逻辑处理
//这个工具类是微信提供给我们的 读取xml文件的
Map<String, String> map = WXPayUtil.xmlToMap(xml);
if ("SUCCESS".equals(map.get("result_code"))) {
//查询订单
Map result = wxPayService.queryOrder(map.get("out_trade_no"));
System.out.println("查询订单结果:" + result);
if ("SUCCESS".equals(result.get("result_code"))){
//将订单的消息发送到mq'
Map message = new HashMap();
message.put("orderId",result.get("out_trade_no"));
message.put("transactionId",result.get("transaction_id"));
//消息的发送
rabbitTemplate.convertAndSend("", RabbitMQConfig.ORDER_PAY, JSON.toJSONString(message));
//完成双向通信
rabbitTemplate.convertAndSend("paynotify", "",result.get("transaction_id"));
}else {
//输出错误原因
System.out.println(map.get("err_code_des"));
}
}else {
//输出错误原因
System.out.println(map.get("err_code_des"));
}
//给微信一个结果通知
response.setContentType("text/xml");
String data="<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
response.getWriter().write(data);
网友评论