支付宝异步通知处理实现原理总结

摘要:
支付宝有一个接口:实现支付请求(应在其中提供订单号)。您有一个接口:实现付款结果通知(通知将包含订单号)。之后很简单2)您的界面:等待支付宝调用的界面通知您订单完成的结果。3) 支付系统的异步通知实际上是通过向给定地址发送请求来实现的,该地址可能没有页面,但有接口地址。4) 通知地址实际上不是页面,而是

支付宝有一个接口:实现支付请求(里面要提供一个订单号)
你有一个接口:实现支付结果的通知(通知里面会包含订单号)

后面就简单了

1)你生成订单 请求调用 支付宝接口 去支付(然后。。然后就没然后了)

2)你的接口:等着呗 支付宝会调用的接口 通知你 那个订单完成的结果

3) 支付系统的异步通知实质上是给给定的地址发送请求实现的,这个地址很可能是不会有页面而是一个接口地址。

4)通知地址实际上不是一个页面,而是一个接收通知的接口地址,上游给这个地址发请求,实际是调用我们的同志接口比如:
我们系统中的接受通道通知处理逻辑的本质是上游通过接口地址来调用接口。比如下面例子中就会通过“http://XXX.XXX.XXX.XXX:XXX/notify/XXXX”来调用接口。

5)支付通知,是用来接收来自银行或者第三方支付平台的订单支付结果通知,分为两种,一种是同步通知(又称前台通知),一种是异步通知(又称后台通知),简单的说,商户支付系统收到支付同步通知并且支付状态为已支付,我们需要将订单支付状态修改为支付确认中,商户支付系统收到支付异步通知并且支付状态为支付成功,我们需要将订单支付状态修改为已支付。再次强调下,商户支付系统要以异步通知的结果为准

    根据完成结果 实现 业务逻辑  

补充:
1、支付成功后 会有通知 但是哪个页面什么都么有 就是这个通知页面要怎么实现
1)支付成功 可以跳转一个页面 ,页面也是你写的 你想怎么写 就怎么写
2)所有的异步实现都可以通过spring的@Async注解调用spring的线程池完成。
举个例子,代码如下---个人处理结算异步通知接口(被回调对象):

  1. /**
  2. * 个人处理结算异步通知
  3. *
  4. * @param dto
  5. * @return
  6. */
  7. @RequestMapping(value = "/notify/{orderId}")
  8. @ResponseBody
  9. public Object personal(HttpServletRequest request, @PathVariable String orderId,HttpServletResponse response){
  10. Map<String, String> result = new HashMap<String, String>();
  11. result.put("respCode", "N");
  12. try {
  13. String content = this.getRequestBody(request);
  14. logger.info("收到结算系统结果回调:{}", content);
  15. WithdrawCallbackDto dto=JSON.parseObject(content, WithdrawCallbackDto.class);
  16. logger.info("个人:收到结算系统结果回调:{}", dto);
  17. if (!checkSmtSign(dto)) {
  18. result.put("respMsg", "验签失败");
  19. return result;
  20. }
  21. //查询个人提现记录流水
  22. WithdrawPersonalFlowEntity entity=withdrawPersonalFlowService.queryPersonalFlowByFlowNo(dto.getOutTradeNo());
  23. if(entity==null){
  24. result.put("respMsg", "操作失败:个人提现流水不存在");
  25. return result;
  26. }
  27. //校验提现流水状态是否支持退款和更新状态操作
  28. if(entity.getStatus()==WithdrawStatusEnum.ACCEPT.getStatus()){
  29. result.put("respCode", "Y");
  30. // 准备个人提现流水更新参数准备
  31. SettlementResponseDto responseDto = personalParametersPrepare(dto);
  32. // 代表结算成功
  33. if (dto.getRespCode().equals("100005")) {
  34. //更新个人提现流水操作
  35. withdrawPersonalFlowService.updateFlowBySmt(responseDto);
  36. }else{// 代表结算失败
  37. //更新个人提现流水操作
  38. withdrawPersonalFlowService.updateFlowBySmt(responseDto);
  39. //个人退还提现本金参数准备
  40. WithdrawRefundDto refundDto=personalRefundOfCommissionCharge(dto);
  41. //个人提现,退还本金处理
  42. withdrawPersonalFlowService.refund(refundDto);
  43. }
  44. result.put("respMsg","验签成功,个人退款成功");
  45. }else{
  46. result.put("respMsg", "操作失败:个人提现流水状态有误");
  47. return result;
  48. }
  49. } catch (PaycoreException e) {
  50. logger.error("个人处理结算系统异步回调失败, {}", e);
  51. result.put("respMsg", e.getErrorMsg());
  52. return result;
  53. } catch(Exception e){
  54. logger.error("个人处理结算系统异步回调失败, {}", e);
  55. result.put("respMsg","系统异常" );
  56. return result;
  57. }
  58. return result;
  59. }

回调验签

  1. private boolean checkSmtSign(WithdrawCallbackDto dto){
  2. String[] exceptParams = {"signCode", "signType"};
  3. return SignatureUtil.callBackVerify(dto, exceptParams);
  4. }
xml 配置
  1. <bean id="signUtil" class="com.qbao.signature.sign.client.CuratorZookeeperClient"
  2. init-method="init" lazy-init="false">
  3. <property name="connectString" value="${zk.hosts}" />
  4. <property name="needsAll" value="true" />
  5. </bean>
  6. <bean id="verifyUtil" class="com.qbao.signature.verify.client.CuratorZookeeperClient"
  7. init-method="init" lazy-init="false">
  8. <property name="connectString" value="${zk.hosts}"/>
  9. </bean>




2018-11-24更新

1、支付系统中异步通知的验签分两种情况

(1)第一种,会将我的通知地址(其实就是我们自己异步通知接口url)和和下单参数原样返回给我们,我们按照订单的签名针对订单重新对比签名是否相等。

(2)第二种,上游会将我们参数在异步通知中再次封装,然后验签的时候跟订单数据没有关系,直接做通知验签,比如:微信H5就是直接在返回结果中移除sign以后按照签名算法进行验签即可。

免责声明:文章转载自《支付宝异步通知处理实现原理总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇12个强大的Web服务测试工具python找出字典中value最大值的几种方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python---硬件序列号

安装wmi : pip install wmi -i https://pypi.douban.com/simple 还要安装  pip install pywin32  import wmi c = wmi.WMI() zuban=c.Win32_BaseBoard()[0].SerialNumber.strip() #获取主板序列号 #BSN...

微信小程序 wx.getUserProfile 接口获取用户信息

为优化用户的使用体验,平台将进行以下调整: 1、2021年2月23日起,若小程序已在微信开放平台进行绑定,则通过 wx.login 接口获取的登录凭证可直接换取 unionID 。 2、2021年4月13日后发布的小程序新版本,无法通过 wx.getUserInfo 与 <button open-type="getUserInfo"/> 获取用...

路由协议之OSPF

目录 OSPF协议 OSPF的七种状态 OSPF的11种LSA Stub和Nssa OSPF中的防环机制 OSPF中的路由汇总和路由过滤 OSPF中的虚拟链路 虚拟链路有两种存在的意义 OSPF中的认证 华为模拟器中的配置 OSPF协议OSPF(Open Shortest Path First开放式最短路径优先)是一个内部网关协议IGP,用于在单一自治系...

交换机安全学习笔记 第二章 MAC地址泛洪攻击

本文为书中相关知识的摘要,由于书中以思科设备为配置依据,所以笔记中补充了华为、H3C设备的相关配置。华为设备配置参考华为S2352EI 产品版本:V100R005C01文档版本:02。  H3C配置参考S7600系列文档(资料版本:6W102-20130226 产品版本:S7600系列—Release 6701及以上版本  S7600-X系列 —Relea...

08_linux下安装chrome

首先下载chrome,需要改hosts哦(o(^▽^)o,别告诉我你不会,可以问度娘、谷哥哦) 下载地址:https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 安装依赖包 [root@localhost ~]# yum install pax* [roo...

iOS APP上架被拒3.1.1支付问题解决方案

Guideline 3.1.1 - Business - Payments - In-App PurchaseWe noticed that your app uses in-app purchase products to purchase credits or currencies that are not consumed within the a...