Closed snowfoxzx closed 7 years ago
这个类是腾讯提供的,我们进行了一些修改,但是这个地方一直没有动,现在已经将Core版本的强制改为UTF8:
public virtual string CreateMd5Sign(string key, string value)
{
StringBuilder sb = new StringBuilder();
ArrayList akeys = new ArrayList(Parameters.Keys);
akeys.Sort();
foreach (string k in akeys)
{
string v = (string)Parameters[k];
if (null != v && "".CompareTo(v) != 0
&& "sign".CompareTo(k) != 0
//&& "sign_type".CompareTo(k) != 0
&& "key".CompareTo(k) != 0)
{
sb.Append(k + "=" + v + "&");
}
}
sb.Append(key + "=" + value);
//string sign = MD5UtilHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
string sign = MD5UtilHelper.GetMD5(sb.ToString(), "UTF-8").ToUpper();
return sign;
}
您看一下这个是不是您要的结果。
或者能不能给一组您那边的数据,方便我们做一个单元测试?
@JeffreySu 这样处理就 OK 了,不过我觉得问题的根源应该是在 GetCharset()
方法中,不知道腾讯这样处理是出于什么考虑
另附一个单元测试,还有,NETCore 下使用 GB2312
、GBK
等编码时需要引用 System.Text.Encoding.CodePages
并注册一下,注释里有写
[TestClass]
public class SenparcTest
{
[TestInitialize]
public void Setup()
{
// .NET Core 下使用 GBK, GB2312 等编码时,
// 必须 NuGet 添加 System.Text.Encoding.CodePages
// 并执行以下语句注册, 否则运行时会报错 `No data is available for encoding xxxx`
// 或 `'xxxx' is not a supported encoding name. `
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
[TestMethod]
public void TestUnifiedorderSign()
{
var appId = "wx0000000000000000";
var mchId = "1234567890";
var body = "微信支付"; // 如果此处改为英文则不会出现 `签名错误`
var billNo = "1234567890_1495442415";
var price = 8866;
var billIp = "127.0.0.1";
var notifyUrl = "http://abc.123.org/wechat";
var payType = TenPayV3Type.JSAPI;
var openId = "oEhblwEDhUTz1Sj5qnPo6p_PbUrc";
var mchKey = "e64fc5e5139d393311b645dc1fceed0c";
var nonceStr = "2271A353370C61225EB2588D3F1DEB14";
var timeStart = new DateTime(2017, 5, 23, 11, 12, 0);
var expectedSign = "A94C30EFE9893844B2EC6D875E2FE413";
var reqData = new TenPayV3UnifiedorderRequestData(appId, mchId, body, billNo, price,
billIp, notifyUrl, payType, openId, mchKey, nonceStr, null, timeStart);
Assert.AreEqual(expectedSign, reqData.Sign, false, "签名错误");
}
}
非常感谢!
腾讯的代码估计是哪里抄的吧,比较通用,他获取的是当前通讯请求过程中的字符编码,我们也疏忽没注意这个问题。。
问题描述
调用统一下单接口时,如果参数中含有
非英文字符
(如body="微信支付"),微信会返回签名错误
。 查看Developer-FullDotNet
分支下Senparc.Weixin.MP.TenPayLibV3.RequestHandler.GetCharset()
方法,估计此方法应该是返回空字符串或 null,导致调用Senparc.Weixin.Helpers.EncryptHelper.GetMD5()
方法时使用了默认的GB2312
编码,而微信官方明确要求字符编码使用UTF-8
不知道 GetCharset() 方法中的逻辑是有什么其它考虑吗?临时解决方法,下单时不要使用非英文字符。。。
发现问题的模块
模块对应的.net版本
开发环境
缓存环境