C#完成JSAPI支付(二)

微信支付回調通知


一、提要


接上一篇文章,JSAPI支付完成之後,會把相關支付結果及用戶信息通過數據流的形式發送給商戶,商戶需要接收處理,並按文檔規範返回應答。

二、準備資料


  • JSAPI支付中,調用微信統一下單接口中配置了notify_url參數

  •   參考微信文檔【回調通知注意事項】

在微信回調通知注意事項中,微信有以下提示信息:

  1. notify_url需要填寫商戶自己系統的真實地址,不能填寫接口文檔或demo上的示例地址。 
  2. notify_url必須是以https://或http://開頭的完整全路徑地址,並且確保url中的域名和IP是外網可以訪問的,不能填寫localhost、127.0.0.1、192.168.x.x等本地或內網IP。 
  3. notify_url不能攜帶參數。 

   更多注意事項,請參考微信文檔:

   https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_8&index=6

  •   參考微信文檔【支付結果通知】

     注意事項:

  1. 同樣的通知可能會多次發送給商戶系統。商戶系統必須能夠正確處理重複的通知。
  2. 後臺通知交互時,如果微信收到商戶的應答不符合規範或超時,微信會判定本次通知失敗,重新發送通知,直到成功爲止(在通知一直不成功的情況下,微信總共會發起多次通知,通知頻率爲15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 總計 24h4m),但微信不保證通知最終一定能成功。
  3. 在訂單狀態不明或者沒有收到微信支付結果通知的情況下,建議商戶主動調用微信支付【查詢訂單API】確認訂單狀態。

      特別提醒:

  1. 商戶系統對於支付結果通知的內容一定要做簽名驗證,並校驗返回的訂單金額是否與商戶側的訂單金額一致,防止數據泄漏導致出現“假通知”,造成資金損失。
  2. 當收到通知進行處理時,首先檢查對應業務數據的狀態,判斷該通知是否已經處理過,如果沒有處理過再進行處理,如果處理過直接返回結果成功。在對業務數據進行狀態檢查和處理之前,要採用數據鎖進行併發控制,以避免函數重入造成的數據混亂。
  3. 技術人員可登進微信商戶後臺掃描加入接口報警羣,獲取接口告警信息。

     更多參考信息,請參照文檔:

     https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7&index=8

三、代碼開發

   請注意,微信的支付結果通知,由於需要提交數據流,所以請求方式爲:Post。

 //請注意,一定要在方法體頭部加入Post請求標識
 [HttpPost]
 public string SyUnifiedorderUrl()

  接收Xml文件流

string strRecieveBody;
using (System.IO.StreamReader streamReader = new System.IO.StreamReader(Request.Body))
{
     strRecieveBody = streamReader.ReadToEnd();
    //方面我們更好的處理該Xml文件,建議使用日誌打印該文件流結果
 }

 建議將xml轉換爲對象或者Dictionary<string, string>對象以方便我們更好的處理,由於微信通知返回的字段過於繁雜,並且很多字段其實都無關業務數據處理,所以,在此在建議各位將返回結果轉換爲Dictionary<string, string>。

public IDictionary<string, string> FromXml(string xml)
{
     IDictionary<string, string> xmlDic = new Dictionary<string, string>();
     if (string.IsNullOrEmpty(xml))
     {
         return xmlDic;
     }

    XmlDocument xmlDoc = new XmlDocument();
    // 2018/07/06 關於XML解析存在的安全問題指引.Net回調修復
    xmlDoc.XmlResolver = null;
    xmlDoc.LoadXml(xml);
    XmlNode xmlNode = xmlDoc.FirstChild;//獲取到根節點<xml>
    XmlNodeList nodes = xmlNode.ChildNodes;
    foreach (XmlNode xn in nodes)
    {
        XmlElement xe = (XmlElement)xn;
        xmlDic[xe.Name] = xe.InnerText;//獲取xml的鍵值對到WxPayData內部的數據中
    }
    return xmlDic;
}

  針對該返回結果,我們需要着重處理的字段如下:

  return_code:返回狀態碼,SUCCESS/FAIL;交易是否成功需要查看result_code來判斷。

  sign:簽名,我們需要對數字簽名進行驗證,防止數據泄漏導致出現“假通知”,我們可以使用

  out_trade_no:商戶訂單號,我們可根據該字段查詢我們數據庫中的訂單,然後再進行業務處理。

  total_fee:訂單總金額,我們可根據該字段校驗,我們發起支付的金額與用戶實際支付金額是否一致

  等這一切都校驗完成,一整套jsapi支付纔算結束。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章