1.超时未支付订单处理

1.1 需求分析

超过限定时间并未支付的订单,我们需要进行超时订单的处理:先调用微信支付api,查询该订单的支付状态。如果未支付调用关闭订单的api,并修改订单状态为已关闭,并回滚库存数。如果该订单已经支付,则做补偿操作(修改订单状态和记录)。

1.2 实现思路

如何获取超过限定时间的订单?我们可以使用延迟消息队列(死信队列)来实现。所谓延迟消息队列,就是消息的生产者发送的消息并不会立刻被消费,而是在设定的时间之后才可以消费。我们可以在订单创建时发送一个延迟消息,消息为订单号,系统会在限定时间之后取出这个消息,然后查询订单的支付状态,根据结果做出相应的处理。

1.3 rabbitmq延迟消息

使用RabbitMQ来实现延迟消息必须先了解RabbitMQ的两个概念:消息的TTL和死信Exchange,通过这两者的组合来实现上述需求。

1.3.1 消息的TTL(Time To Live)

消息的TTL就是消息的存活时间。RabbitMQ可以对队列和消息分别设置TTL。对队列设置就是队列没有消费者连着的保留时间,也可以对每一个单独的消息做单独的设置。超过了这个时间,我们认为这个消息就死了,称之为死信。

我们创建一个队列queue.temp,在Arguments 中添加x-message-ttl 为5000 (单位是毫秒),那每一个进入这个队列的消息在5秒后会消失。

1.3.2 死信交换器 Dead Letter Exchanges

一个消息在满足如下条件下,会进死信交换机,记住这里是交换机而不是队列,一个交换机可以对应很多队列。

(1) 一个消息被Consumer拒收了,并且reject方法的参数里requeue是false。也就是说不会被再次放在队列里,被其他消费者使用。

(2)上面的消息的TTL到了,消息过期了。

(3)队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信交换机上。

Dead Letter Exchange其实就是一种普通的exchange,和创建其他exchange没有两样。只是在某一个设置Dead Letter Exchange的队列中有消息过期了,会自动触发消息的转发,发送到Dead LetterExchange中去。

我们现在可以测试一下延迟队列。

(1)创建死信交换器 exchange.ordertimeout (fanout)

(2)创建队列queue.ordertimeout

(3)建立死信交换器 exchange.ordertimeout 与队列queue.ordertimeout 之间的绑定

(4)创建队列queue.ordercreate,Arguments添加

x-message-ttl=10000

x-dead-letter-exchange: exchange.ordertimeout

(5)测试:向queue.ordercreate队列添加消息,等待10秒后消息从ueue.ordercreate队列消失。

1.4.1 微信支付-关闭订单

(1)WxPayController新增方法

/**

* 关闭微信订单

* @param orderId

* @return

*/

@PutMapping("/close/{orderId}")

public Result closeOrder(@PathVariable String orderId){

Map map = wxPayService.closeOrder( orderId );

return new Result( true,StatusCode.OK,"",map );

}

(2)changgou_service_pay的WxPayService新增方法定义

/**

* 关闭订单

* @param orderId

* @return

*/

Map closeOrder(String orderId);

(3)changgou_service_pay的 WxPayServiceImpl实现该方法

@Override

public Map closeOrder(String orderId) {

Map map=new HashMap( );

map.put( "out_trade_no",orderId );

try {

return wxPay.closeOrder( map );

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

(4)changgou_service_pay_api的WxPayFeign新增方法

/**

* 关闭微信订单

* @param orderId

* @return

*/

@PutMapping("/wxpay/close/{orderId}")

public Result closeOrder(@PathVariable("orderId") String orderId);

1.4.2 微信支付-查询订单

(1)WxPayController新增方法

/**

* 查询微信订单

* @param orderId

* @return

*/

@GetMapping("/query/{orderId}")

public Result queryOrder(@PathVariable String orderId){

Map map = wxPayService.queryOrder( orderId );

return new Result( true,StatusCode.OK,"",map );

}

(2)WxPayFeign新增方法

/**

* 查询微信订单

* @param orderId

* @return

*/

@GetMapping("/wxpay/query/{orderId}")

public Result queryOrder(@PathVariable("orderId") String orderId);

1.4.3 订单关闭逻辑

如果为未支付,查询微信订单

如果确认为未支付,调用关闭本地订单( 修改订单表的订单状态、记录订单日志、恢复商品表库存)和微信订单的逻辑。

如果为已支付进行状态补偿。

(1)changgou_service_order新增依赖

com.changgougroupId>

changgou_service_pay_apiartifactId>

1.0-SNAPSHOTversion>

dependency>

(2)changgou_service_order的OrderService新增方法定义

/**

* 关闭订单

* @param orderId

*/

void closeOrder(String orderId);

(3)OrderServiceImpl实现该方法

实现逻辑:

1)根据id查询订单信息,判断订单是否存在,订单支付状态是否为未支付

2)基于微信查询订单支付状态

2.1)如果为success,则修改订单状态

2.2)如果为未支付,则修改订单,新增日志,恢复库存,关闭订单

@Autowired

private WxPayFeign wxPayFeign;

@Override

@Transactional

public void closeOrder(String orderId) {

/**

* 1.根据订单id查询mysql中的订单信息,判断订单是否存在,判断订单的支付状态

* 2. 基于微信查询订单信息(微信)

* 2.1)如果当前订单的支付状态为已支付,则进行数据补偿(mysql)

* 2.2)如果当前订单的支付状态为未支付,则修改mysql中的订单信息,新增订单日志,恢复商品的库存,基于微信关闭订单

*/

System.out.println("关闭订单业务开启:"+orderId);

Order order = orderMapper.selectByPrimaryKey(orderId);

if (order == null){

throw new RuntimeException("订单不存在!");

}

if (!"0".equals(order.getPayStatus())){

System.out.println("当前订单不需要关闭");

return;

}

System.out.println("关闭订单校验通过:"+orderId);

//基于微信查询订单信息

Map wxQueryMap = (Map) payFeign.queryOrder(orderId).getData();

System.out.println("查询微信支付订单:"+wxQueryMap);

//如果订单的支付状态为已支付,进行数据补偿(mysql)

if ("SUCCESS".equals(wxQueryMap.get("trade_state"))){

this.updatePayStatus(orderId,(String) wxQueryMap.get("transaction_id"));

System.out.println("完成数据补偿");

}

//如果订单的支付状态为未支付,则修改mysql中的订单信息,新增订单日志,恢复商品的库存,基于微信关闭订单

if ("NOTPAY".equals(wxQueryMap.get("trade_state"))){

System.out.println("执行关闭");

order.setUpdateTime(new Date());

order.setOrderStatus("4"); //订单已关闭

orderMapper.updateByPrimaryKeySelective(order);

//新增订单日志

OrderLog orderLog = new OrderLog();

orderLog.setId(idWorker.nextId()+"");

orderLog.setOperater("system");

orderLog.setOperateTime(new Date());

orderLog.setOrderStatus("4");

orderLog.setOrderId(order.getId());

orderLogMapper.insert(orderLog);

//恢复商品的库存

OrderItem _orderItem = new OrderItem();

_orderItem.setOrderId(orderId);

List orderItemList = orderItemMapper.select(_orderItem);

for (OrderItem orderItem : orderItemList) {

skuFeign.resumeStockNum(orderItem.getSkuId(),orderItem.getNum());

}

//基于微信关闭订单

payFeign.closeOrder(orderId);

}

}

1.4.4 延迟消息处理

从消息队列queue.ordertimeout 中提取消息

(1)修改OrderServiceImpl的add方法,追加代码,实现mq发送

rabbitTemplate.convertAndSend( "","queue.ordercreate", orderId);

(2)changgou_service_order新建监听类

@Component

public class OrderTimeoutListener {

@Autowired

private OrderService orderService;

/**

* 更新支付状态

* @param orderId

*/

@RabbitListener(queues = "queue.ordertimeout")

public void closeOrder(String orderId){

System.out.println("接收到关闭订单消息:"+orderId);

try {

orderService.closeOrder( orderId );

} catch (Exception e) {

e.printStackTrace();

}

}

}

mysql支付成功订单数超过10_1.超时未支付订单处理相关推荐

  1. 12123两小时没付款怎么办_【12123超过2小时未支付资讯】12123超过2小时未支付足球知识与常识 - 足球百科 - 599比分...

    12123交罚款的编号超过两个小时没缴罚款失效了怎么办? 编号它是不会失效的,交通违处理分两个步骤,一个是处理违法的步骤,就是点击违法记录,产生处罚决定书,确定后,才出来一个处罚决定书,这个上面有编号 ...

  2. 1.超时未支付订单处理

    1.超时未支付订单处理 1.1 需求分析 超过限定时间并未支付的订单,我们需要进行超时订单的处理:先调用微信支付api,查询该订单的支付状态.如果未支付调用关闭订单的api,并修改订单状态为已关闭,并 ...

  3. Java秒杀系统实战系列~RabbitMQ死信队列处理超时未支付的订单(转)

    转自: https://juejin.cn/post/6844903903130042376 文末有源代码,非常棒 摘要: 本篇博文是"Java秒杀系统实战系列文章"的第十篇,本篇 ...

  4. 订单超时未支付的解决方案

    订单超时未支付的解决方案 定时任务实现 被动取消 JDK的延迟队列 代码演示 时间轮算法 代码演示 Redis zset 实现延迟任务 代码演示 MQ 延时消息 代码演示 写在最后 在前面的文章 第三 ...

  5. B2C电商项目(第十三天、超时未支付订单处理、订单批量发货、确认收货与自动收货)

    订单处理 课程内容: 通过 rabbitmq的延迟消息完成超时订单处理 完成批量发货功能,了解第三方物流系统 完成自动收货功能 一.超时未支付订单处理 1.1 需求分析 超过限定时间并未支付的订单,我 ...

  6. TP5.1 实现超时未支付订单自动关闭

    对于这个需求,我以前写过Laravel版本的.今天想在TP5.1中实现这个功能,但是网上基本没什么教程可供参考,所以写篇文章仅供大家学习. 一.前台 1.先来加载订单确认页面 当下单成功后,通过 js ...

  7. Java秒杀系统实战系列~定时任务补充处理超时未支付的订单

    摘要: 本篇博文是"Java秒杀系统实战系列文章"的第十一篇,本篇博文我们将借助定时任务调度组件来辅助"失效超时未支付的订单记录"的处理,用以解决上篇博文中采用 ...

  8. 订单超时未支付自动关闭的几种实现方案

    做电商,就会遇到订单超时问题,而且还经常被拿来面试提问! 今天,周末放假,抽时间给大家总结了几种订单超时未支付自动关闭的实现方案.同时,我手机还有几套电商类从零架构到实现的视频教程,如有需要,可以加我 ...

  9. 拼夕夕订单超时未支付自动关闭实现方案!

    " 在开发中,往往会遇到一些关于延时任务的需求.例如:生成订单 30 分钟未支付,则自动取消:生成订单 60 秒后,给用户发短信. 对上述的任务,我们给一个专业的名字来形容,那就是延时任务. ...

  10. 订单超时未支付自动取消5种实现方案

    大家好,我是宝哥! 前言 在开发中,往往会遇到一些关于延时任务的需求.比如最近大家都在忙抢回家的火车票,当你下了一个订单没有支付时,会有一个倒计时,提示你半小时之内支付,否则会自动取消.这样的场景是如 ...

最新文章

  1. Error: no such column
  2. 浙江大学 计算机学院 秦青青,我院研究生在乒乓球大赛中喜获佳绩
  3. Maven-dependencyManagement与import
  4. ArcGIS Maritime Server 开发教程(八)ArcGIS Bathymetry 扩展模块
  5. 数据库设计说明书(GB8567——88) (转)
  6. 电路基本原理的那些事儿之 分压原理
  7. c语言常用英语带音标,C语言常见英语单词,带音标
  8. 腾讯云推出“版权音乐助手”让音乐版权使用“按量付费“
  9. 中铁建工集团安装公司基于BIM物资施工运维系统由橄榄山软件研发完成
  10. druid emitter 监控模块
  11. 数学建模 MATLAB绘制心形线
  12. word常用技巧教程
  13. 网易云亮相GITC,聚合多样化通信与视频云平台
  14. 讨论IOS开发以及自己的经验
  15. java窗体中添加图片_在java窗体程序中添加图片的方法
  16. Jmeter介绍与使用
  17. Springboot+基于微信小程序的电器商城系统的设计与实现 毕业设计-附源码251453
  18. 网站被百度网址安全中心 警告 该怎么取消拦截提示
  19. NEERC 2014, Eastern subregional contest(汇总)
  20. 树莓派 ubuntu gpio_树莓派自动温控风扇

热门文章

  1. [面试题] 从抽屉找东西的概率学问题
  2. ECSHOP V2.7.3文件目录结构
  3. Elasticsearch 搜索引擎开发实战
  4. 新南威尔士 计算机硕士,新南威尔士大学计算机硕士申请条件及案例
  5. 大一新生计算机强化训练小结,大一新生军训个人小结
  6. LODOP打印,首次打印时,图片加载不出来、加载不完全问题
  7. Day17——整数矩阵及其运算
  8. 服务器装系统就蓝屏怎么办,安装系统出现蓝屏,怎么办?
  9. 服务器装系统03系统,服务器系统安装windows2003教程
  10. 微信OAuth2.0 登录流程以及安全性分析