支付寶異步通知處理實現原理總結


支付寶有一個接口:實現支付請求(里面要提供一個訂單號)
你有一個接口:實現支付結果的通知(通知里面會包含訂單號)

后面就簡單了

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以后按照簽名算法進行驗簽即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM