目录

像这种微服务B2C模式的,订单业务需要远程调用我们的课程信息+用户信息
依赖:
- <dependency>
- <groupId>com.github.wxpaygroupId>
- <artifactId>wxpay-sdkartifactId>
- <version>0.0.3version>
- dependency>
-
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>fastjsonartifactId>
- dependency>
通过远程调用,order业务调用course+user
1.查询Course课程信息暴露出来的接口+用户信息接口
- @Component
- @FeignClient("service-edu")
- public interface EduClient {
-
- /**
- * 1.远程调用ucenter中根据id获取用户信息的方法
- */
- @GetMapping("/eduservice/indexfront/getCourseInfoOrder/{id}")
- public CourseWebVoOrder getCourseInfoOrder(@PathVariable String id);
-
- }
- @Component
- @FeignClient("service-ucenter")
- public interface UcenterClient {
-
- /**
- * 1.根据课程id查询课程信息
- */
- @GetMapping("/educenter/member/getUserInfoOrder/{id}")
- public UcenterMemberOrder getUserInfoOrder(@PathVariable("id") String id);
- }
2.生成订单的接口+实现类
通过请求头得到token然后给到JWT进行解析得到用户id
- @RestController
- @RequestMapping("/eduorder/order")
- @CrossOrigin
- public class OrderController {
-
- @Autowired
- private OrderService orderService;
-
- /**
- * 1.生成订单的方法
- */
- @GetMapping("createOrder/{courseId}")
- public R saveOrder(@PathVariable String courseId, HttpServletRequest request){
- //1.生成订单号
- String orderNo=orderService.createOrders(courseId,JwtUtils.getMemberIdByJwtToken(request));
- return R.ok().data("orderId",orderNo);
- }
- /**
- *
- * 订单 服务实现类
- *
- *
- * @author testjava
- * @since 2022-07-25
- */
- @Service
- public class OrderServiceImpl extends ServiceImpl
implements OrderService { -
- @Autowired
- private EduClient eduClient;
- @Autowired
- private UcenterClient ucenterClient;
-
- /**
- * 1.生成订单的方法,通过远程调用两个feign方法(课程信息和人物信息)结合到Order中为订单
- * @param courseId
- * @param memberId
- * @return
- */
- @Override
- public String createOrders(String courseId, String memberId) {
- //1.通过远程调用根据用户id获取用户信息
- UcenterMemberOrder userInfoOrder = ucenterClient.getUserInfoOrder(memberId);
-
- //2.通过远程调用根据课程id获取课程信息
- CourseWebVoOrder courseInfoOrder = eduClient.getCourseInfoOrder(courseId);
-
- //3.创建order对象,向order对象里面设置需要的数据
- Order order = new Order();
- order.setOrderNo(OrderNoUtil.getOrderNo());
- order.setCourseId(courseId); //课程id
- order.setCourseTitle(courseInfoOrder.getTitle());
- order.setCourseCover(courseInfoOrder.getCover());
- order.setTeacherName(courseInfoOrder.getTeacherName());
- order.setTotalFee(courseInfoOrder.getPrice());
- order.setMemberId(memberId);
- order.setMobile(userInfoOrder.getMobile());
- order.setNickname(userInfoOrder.getNickname());
-
- order.setStatus(0);//订单状态(0:未支付 1:已支付)
- order.setPayType(1);//支付类型 微信1
- baseMapper.insert(order);//插入
-
- return order.getOrderNo();
- }
- }
返回的CourseWebVoOrder等远程调用的类放在公共模块中
- /**
- * 2.根据订单id查询订单信息
- */
- @GetMapping("getOrderInfo/{orderId}")
- public R getOrderInfo(@PathVariable String orderId){//订单id查询
- QueryWrapper
wrapper = new QueryWrapper<>(); - wrapper.eq("order_no",orderId);
-
- Order order = orderService.getOne(wrapper);
- return R.ok().data("item",order);
- }
准备工作(wxid,商户号,商户key)

1.根据订单号获取订单信息
- /**
- *
- * 支付日志表 前端控制器
- *
- *
- * @author testjava
- * @since 2022-07-25
- */
- @RestController
- @RequestMapping("/eduorder/paylog")
- @CrossOrigin
- public class PayLogController {
-
- @Autowired
- private PayLogService payLogService;
-
- /**
- * 1.生成微信支付的二维码接口
- */
- @GetMapping("createNative/{orderNo}")
- public R createNative(@PathVariable String orderNo) {
- //1.返回信息含有二维码的地址还有其他信息
- Map map = payLogService.createNative(orderNo);
- System.out.println("*****返回二维码map集合****:"+map);
- return R.ok().data(map);
- }
2.1根据订单号获取订单信息——>2.2业务实现类中设置支付参数 ——>2.3将参数请求到我们vx支付的接口地址,回调得到返回集(client.getContent(),利用WXPayUtil将xml转为map集合方便返回到前端)
- @Service
- public class PayLogServiceImpl extends ServiceImpl
implements PayLogService { -
- @Autowired
- private OrderService orderService;
-
- /**
- * 1.返回二维码地址
- * @param orderNo
- * @return
- */
- @Override
- public Map createNative(String orderNo) {
- try {
- //1.根据订单id获取订单信息
- QueryWrapper
wrapper = new QueryWrapper<>(); - wrapper.eq("order_no", orderNo);
- Order order = orderService.getOne(wrapper);
-
- //2.使用map设置二维码需要的参数
- HashMap map = new HashMap();
- map.put("appid","wx74862e0dfcf69954");
- map.put("mch_id", "1558950191");
- map.put("nonce_str", WXPayUtil.generateNonceStr());//随机生成一个二维码
- map.put("body", order.getCourseTitle());
- map.put("out_trade_no", orderNo);//二维码标识订单号
- map.put("total_fee", order.getTotalFee().multiply(new BigDecimal("100")).longValue()+"");//价格
- map.put("spbill_create_ip", "127.0.0.1");
- map.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify\n");
- map.put("trade_type", "NATIVE");
-
- //3.发送httpclient请求,传递参数按照xml格式,微信支付提供固定地址
- HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
-
- //设置参数,我们的商户key会对这些map参数进行加密->将map根据key进行加密并且传送到请求中去
- client.setXmlParam(WXPayUtil.generateSignedXml(map,"T6m9iK73b0kn9g5v426MKfHQH7X8rKwb"));
- client.setHttps(true);
-
- //执行请求发送
- client.post();
-
- //4.得到发送请求返回的结果,返回的内容是xml格式返回的(之前传参数也是xml格式)
- String content = client.getContent();
- //5.再把xml转为map
- Map
resultMap=WXPayUtil.xmlToMap(content); -
- //6.前面的map只是为了给到http生成二维码,需要转为xml格式,现在我们这个结果resultMap就是二维码了
- //还需要一些关于订单的提示信息
- Map res = new HashMap<>();
- res.put("out_trade_no", orderNo);
- res.put("course_id", order.getCourseId());
- res.put("total_fee", order.getTotalFee());
- res.put("result_code", resultMap.get("result_code"));//状态码
- res.put("code_url", resultMap.get("code_url"));//二维码地址
-
- return res;
-
- } catch (Exception e) {
- throw new GuliException(20001,"生成二维码失败");
- }
- }
1.先查订单的支付状态,返回的支付state为成功——>2.然后在支付日志表中添加一条记录,并且更新订单表状态
- /**
- * 2.查询订单状态
- * @param orderNo
- * @return
- */
- @GetMapping("queryPayStatus/{orderNo}")
- public R queryPayStatus(@PathVariable String orderNo){
- Map
map= payLogService.queryPayStatus(orderNo); - System.out.println("返回二维码状态:"+map);
- //1.根据查询出来的订单状态进行判断
- if(map==null){
- return R.error().message("支付出错了...");
- }
-
- //2.如果返回的map不为空,从这里面获取订单状态
- if(map.get("trade_state").equals("SUCCESS")){//支付成功
- //3.添加记录到支付表中,并且更新订单表的状态
- payLogService.updateOrdersStatus(map);
- return R.ok();
- }
- return R.ok().code(25000).message("支付中");
- }
-
- }
业务实现类-根据订单号查询订单状态
- /**
- * 1.查询订单支付状态
- * @param orderNo
- * @return
- */
- @Override
- public Map
queryPayStatus(String orderNo) { - //1.封装参数
- try {
- HashMap map = new HashMap();
- map.put("appid", "wx74862e0dfcf69954");
- map.put("mch_id", "1558950191");
- map.put("out_trade_no", orderNo);
- map.put("nonce_str", WXPayUtil.generateNonceStr());
-
- //2.设置请求,利用xml进行请求
- HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
- client.setXmlParam(WXPayUtil.generateSignedXml(map,"T6m9iK73b0kn9g5v426MKfHQH7X8rKwb"));
- client.setHttps(true);
- client.post();
-
- //3.返回第三方的数据
- String xml = client.getContent();
- Map
resultMap = WXPayUtil.xmlToMap(xml);//将xml转为map数据 -
- return resultMap;
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
业务实现-添加支付记录+更新订单状态
- /**
- * 2.添加支付记录和更新订单状态
- * @param map
- */
- @Override
- public void updateOrdersStatus(Map
map) { - //1.从map中获取订单号
- String orderNo = map.get("out_trade_no");
- //2.根据订单号查询订单信息
- QueryWrapper
wrapper = new QueryWrapper<>(); - wrapper.eq("order_no",orderNo);
- Order order = orderService.getOne(wrapper);
-
- //3.更新订单表的订单状态
- if(order.getStatus().intValue()==1){
- return;//说明支付过了
- }
- order.setStatus(1);
- orderService.updateById(order);
-
- //4.向支付表中添加支付记录
- PayLog payLog = new PayLog();
- payLog.setOrderNo(orderNo);
- payLog.setPayTime(new Date());
- payLog.setPayType(1);//支付类型 1wx
- payLog.setTotalFee(order.getTotalFee());//总金额(分)
- payLog.setTradeState(map.get("trade_state"));//支付状态
- payLog.setTransactionId(map.get("transaction_id"));//账单流水号
- payLog.setAttr(JSONObject.toJSONString(map));
-
- baseMapper.insert(payLog);//插入到支付日志表
- }

当点击商品的去支付就会生成支付的二维码

- methods:{
- //去支付,通过动态路由的方式传递orderNo订单号
- toPay(){
- this.$router.push({path:'/pay/'+this.order.orderNo})
- }
- }
因为oid页面到pid页面点击toPay方法传入订单号,我们这里根据订单号调后台接口createNative生成二维码
mouted()方法:里面定义一个定时器,每3s判断一次订单的状态,如果订单响应状态为success则清除定时器——>跳转到订单详情页去看视频
- import ordersApi from "@/api/order";
-
- export default {
- //1.return除了要return方法还要return成功数据
- asyncData({ params, error }) {
- // 2.名字是pid,那么动态路由的参数就是pid
- return ordersApi.createNative(params.pid).then((response) => {
- return {
- payObj: response.data.data,
- };
- });
- },
-
- data() {
- return {
- tiemer1: "",
- };
- },
-
- //2.定义mouted,意思是页面渲染之后执行,防止没有数据
- mounted() {
- //1.每隔3s调一次查询订单状态方法
- this.tiemer1 = setInterval(() => {
- this.queryOrderStatus(this.payObj.out_trade_no);
- }, 3000);
- },
-
- methods: {
- //3.查询支付状态
- queryOrderStatus(orderNo) {
- ordersApi.queryPayStatus(orderNo).then((response) => {
- console.log("正在查询订单信息.....");
- console.log(response.data);
-
- if(response.data.success){
- console.log("支付成功,清除定时器")
- //1.支付成功清除定时器
- clearInterval(this.tiemer1);
- //2.支付成功提示
- this.$message({
- type: "success",
- message: "支付成功!",
- });
- //3.跳转到课程详情页面观看视频
- this.$router.push({ path: "/course/" + this.payObj.course_id });
- }
- });
- },
- },
- };