首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

微信支付 Java V3 回調簽名驗證完整實現

     編輯:Java 相關知識

微信支付 V3 版回調通知的數據驗證流程:從原始輸入流讀取 XML、Dom4j 解析為有序 Map、按規範重新計算簽名並與微信傳來的 sign 比對。掌握此流程可有效防偽造回調、保障資金安全。

1. 讀取原始回調數據

InputStream in = request.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}
String xml = new String(out.toByteArray(), StandardCharsets.UTF_8);
// xml 即為微信回調的原始 XML 字符串

2. Dom4j 解析 XML 為有序 Map

public static SortedMap<String, String> parseXml(String xml) throws DocumentException {
    SortedMap<String, String> map = new TreeMap<>(); // 必須有序,簽名依賴鍵排序
    Document doc = DocumentHelper.parseText(xml);
    Element root = doc.getRootElement();
    for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
        Element e = it.next();
        map.put(e.getName(), e.getText()); // 僅解析第一層元素
    }
    return map;
}

3. 簽名驗證核心邏輯

public static boolean verifySign(SortedMap<String, String> params, String apiKey) {
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String, String> entry : params.entrySet()) {
        String k = entry.getKey();
        String v = entry.getValue();
        // 排除 sign、key 字段及空值
        if (!"sign".equals(k) && !"key".equals(k) && v != null && !v.isEmpty()) {
            sb.append(k).append('=').append(v).append('&');
        }
    }
    sb.append("key=").append(apiKey); // 最後拼接商戶 API Key
    
    String calculatedSign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
    String wxSign = params.get("sign").toUpperCase();
    
    return calculatedSign.equals(wxSign);
}

最佳實踐建議

  1. 先驗證業務狀態碼:在簽名驗證前,優先檢查 return_code 與 result_code 均為 SUCCESS,減少無效計算
  2. 使用 TreeMap 保證有序:微信簽名規範要求參數按 ASCII 碼升序排列
  3. 防重放攻擊:驗签通過後,需根據 out_trade_no 檢查訂單是否已處理,防止重複回調導致多次發貨
  4. 異常處理:解析失敗、驗签失敗均需記錄日誌並返回 FAIL,讓微信重試

響應微信格式

<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
</xml>

此驗證流程為支付回調處理的基石,建議封裝為通用工具類,所有支付相關 Controller 復用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved