You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何动态域名下MD5哈希计算与支付网关校验不匹配?

动态returnUrl导致MD5校验失败的原因分析

问题背景

对接支付网关时,使用固定returnUrl(https://sampledomain.com/returnlink)时,本地与网关的MD5计算结果一致,校验通过;但改用动态域名拼接形式(var returnUrl = $"https://{dynamicDomain}/returnLink";)后,网关返回哈希计算错误。相关代码如下:

固定returnUrl定义:

var returnUrl = "https://sampledomain.com/returnlink"

参数字典构建代码:

Dictionary<string, string> data = new Dictionary<string, string>
 {
   { "PAYGATE_ID", companyInfo.PayGateId },
   { "REFERENCE", reference },
   { "AMOUNT", $"{pGPayReqDTO.Amount}" },
   { "CURRENCY",  $"{companyInfo.PayGateCurrency}" },
   { "RETURN_URL",returnUrl },
   { "TRANSACTION_DATE", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
   { "LOCALE", "en" },
   { "COUNTRY", $"{companyInfo.PayGateCountryCode}" },
   { "EMAIL", $"{pGPayReqDTO.Email}" },
   { "NOTIFY_URL", $"https://api.libralex.co.za/api/Paygate/Notify"}, 
};

MD5计算代码:

using (MD5 md5Hash = MD5.Create())
{
    string dataString = string.Join("", data.Values) + companyInfo.PayGateSecret;

    byte[] checksumBytes = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(dataString));
    StringBuilder checksumBuilder = new StringBuilder();

    for (int i = 0; i < checksumBytes.Length; i++)
    {
        checksumBuilder.Append(checksumBytes[i].ToString("x2"));
    }

    data.CHECKSUM = checksumBuilder.ToString();

    // return sBuilder.ToString();
}

可能的原因

  • 路径大小写不一致
    固定URL中路径是returnlink(全小写),但动态拼接时写的是returnLink(驼峰格式),这两个字符串属于完全不同的内容。网关端严格按照约定的字符串计算哈希,大小写差异会直接导致拼接后的dataString不同,MD5结果自然不匹配。

  • 动态域名存在格式问题
    动态获取的dynamicDomain可能包含大写字母、前后空格或不可见字符(如换行符、制表符),而网关端使用的是标准小写且无多余字符的域名。比如dynamicDomain是SampleDomain.com(带前后空格和大写),拼接后returnUrl与网关预期的标准URL内容不一致,最终导致哈希计算错误。

  • Dictionary遍历顺序不稳定
    C#的Dictionary<string, string>的Values遍历顺序不固定(由内部哈希码分布决定),如果网关端是按照约定的固定参数顺序拼接字符串计算MD5,而动态场景下Dictionary的Values顺序与固定URL场景不同,就会导致拼接的dataString顺序和网关端不符,MD5结果必然不一致。

  • 编码或特殊字符问题
    若dynamicDomain包含非ASCII字符(如中文、特殊符号),本地使用Encoding.UTF8编码,但网关端可能采用了其他编码格式;或者动态域名未做URL编码,导致returnUrl的字节数组与网关端处理后的内容不一致,最终MD5计算结果不同。

验证与修复建议

  1. 打印动态拼接后的returnUrl,与网关预期的URL逐字符对比,检查大小写、空格、路径拼写是否完全一致。
  2. 打印本地拼接的dataString(即string.Join("", data.Values) + companyInfo.PayGateSecret),和网关端按约定参数顺序拼接的字符串对比,确认内容和顺序是否匹配。
  3. 对dynamicDomain做格式化处理,比如用dynamicDomain.Trim()去除前后空格,统一转为小写:dynamicDomain.Trim().ToLowerInvariant()。
  4. 若网关要求按固定参数顺序拼接,建议改用OrderedDictionary或按约定顺序手动拼接参数值,避免Dictionary的顺序问题。

内容的提问来源于stack exchange,提问作者oceanmanta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:50:18