Payfast API 401授权失败:C#签名生成问题求助
排查Payfast API Ping接口401授权失败的签名问题
核心问题:签名生成的URL编码逻辑错误
你当前代码错误地对整个参数拼接字符串执行URL编码,而Payfast要求的是对每个参数的值单独编码,再按字母顺序拼接成key=encodedValue&key=encodedValue格式的字符串后生成MD5哈希。整体编码会把&和=转义为%26、%3D,导致签名与服务器计算值不匹配,触发401错误。
具体修正步骤
- 单独编码参数值:对
merchantID、passphrase、timestamp、version的每个值分别做URL编码 - 按序拼接字符串:用编码后的值拼接成键值对字符串,无需再次编码
- 生成MD5哈希:基于拼接字符串生成UTF-8编码的MD5哈希,转小写后作为请求头的
signature值
修正后的完整代码
string timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture); // 单独编码每个参数值 var encodedMerchantId = HttpUtility.UrlEncode(merchantID); var encodedPassphrase = HttpUtility.UrlEncode(passphrase); var encodedTimestamp = HttpUtility.UrlEncode(timestamp); var encodedVersion = HttpUtility.UrlEncode(version); // 按字母顺序拼接签名源字符串 var signatureSource = $"merchant-id={encodedMerchantId}&passphrase={encodedPassphrase}×tamp={encodedTimestamp}&version={encodedVersion}"; using (var md5Hash = MD5.Create()) { var sourceBytes = Encoding.UTF8.GetBytes(signatureSource); var hashBytes = md5Hash.ComputeHash(sourceBytes); var hash = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLower(); Console.WriteLine($"Signature source: {signatureSource}"); Console.WriteLine($"Generated signature: {hash}"); var client = new RestClient("https://api.payfast.co.za/ping"); client.Timeout = -1; var request = new RestRequest(Method.GET); request.AddHeader("merchant-id", merchantID); request.AddHeader("version", version); request.AddHeader("signature", hash); request.AddHeader("timestamp", timestamp); IRestResponse response = client.Execute(request); Console.WriteLine(response.Content); }
额外排查点
- 确认
passphrase是Payfast后台配置的API Passphrase,而非登录密码或其他密钥 - 环境匹配:使用测试商户号时,需将API地址替换为沙箱地址
https://sandbox.payfast.co.za/api/ping - 时间格式验证:确保
timestamp是UTC时间的ISO 8601格式(如2024-05-20T14:30:00),无多余转义字符
内容的提问来源于stack exchange,提问作者Donavan John Wallis
相关产品推荐
相关产品推荐

