下订单成功后,发送mq消息到死信队列,消息过期后根据死信的路由key重新路由到交换机,交换机根据消息的路由key把消息路由到普通队列上,消费者监听队列并消费。
问题,现在提交订单信息调用支付宝的支付页面,支付成功,支付宝异步回调给用户消息,此时处理支付宝支付成功后的回执信息,并产生流水单实体,再修改订单的状态,表示客户端收到支付宝支付成功的消息,并将订单状态修改为已支付,在处理这两个业务的时候必须确定支付宝回调的的数据是真实有效的没有被串改,这就用到了阿里的sdk的验证签名的api,将回调的参数进行公钥验证,通过再生成流水号单以及修改订单的状态。
上为了实现分布式事务,避免使用seat带来的高并发的新能问题,选择使用mq的延迟队列解决订单超时或远程扣库存存在的事务无法一致控制问题,解决方式是柔性+最终一致性保证,而不是实时一致性,如果要用就使用seat。在这里如果订单超时订单就会被取消,库存也会在一定的时间内释放,此时再去支付订单发现任然能支付成功。解决
设置支付宝在支付回调页支付期间超时等待,原因是在支付页面会点击发起支付宝的支付调用请求会分装当前订单的信息成请求客户端,构建请求设置请求的属性等并填写两个回调的url,把请求发送到支付宝网关,网关返回支付页面,当这个页面停留一定时间将取消支付,参考的时间是客户端建立并请求到支付页面的时间,在这个过程中超时都会触发支付失败信息。
支付宝收到那指的是当订单信息提交支付到支付页面时,在这个过程中超出客户端设置的时间就会触发支付失败回调。
理解支付宝的收单操作,当支付成功没有收到回调消息的时候可以在指定的时间点来对账,可以使用一个定时器来跑哪些已经超时的订单,看他们是否在支付宝中已经支付成功,如果成功设置订单状态已经支付,再把回滚的库库存扣减上,完成数据的最终一致性。(问题有很多需要理解这样的逻辑最好的方式是登陆京东淘宝店pc端理解实现过程,对比学过的内容理解,不然很难吃透,但在这些中没有后台管理系统可以参考)
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"timeout_express\":\""+timeout+"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
timeout_express请求属性,约定第一次去支付订单时,由唯一的订单信息去请求获取支付页到支付的超时时间内没有完成支付,后续的时间支付失败,这是支付宝的收单功能,并且在下次在点击此订单到支付页也无法支付,支付宝对该提交的订单号返回的支付页始终会处在订单过期状态,自动收单的时间应该设置成可配置的,用一个变量接收默认30m(分钟)。
订单支付成功,在支付宝回调的时候正好订单过期,并把库存解锁,此时就会发生超时支付成功;解决在订单解锁的地方(用户没有支付前)就调用收单的关单操作那么在接下来时间在支付就无法成功(这是手动收单功能与上面自动收单功能选择任意一个,自动收单后订单交易就结束)。
可能支付了客户没有收到通知(网络),订单被释放,库存被解锁,解决某个时间点去核实释放的订单在支付宝服务当中是否已经支付,如果支付就状态改回来并扣减库存,操作方式拿订单号或者交易号在交易服务中查询订单的状态(晚上进行)