问题:接口返回信息“平台证书序列号Wechatpay-Serial错误”
Wechatpay-Serial字段根据要求也进行了加密,但是一直提示这个错误,也没法校验到底哪出错了。申明一下加密用的是微信支付平台证书序列号,不是商户证书序列号;
请求参数
/// <summary>
/// 添加分账接收方
/// </summary>
/// <param name="account"></param>
/// <param name="name"></param>
/// <param name="relation_type"></param>
/// <returns></returns>
public static string AddReceiver(string account, string name, string relation_type, string public_key)
{
// 敏感信息加密
var enrypt_name = "pUrPcj/7VWvH11fBIE/KcMdt89KEcbnyEEGuVZ74jBGzskgPAaGl9VcF0Eagkx0EcSqWqHSZZy5+D91q2n4yk91jHIrCFEvLk4ZUVfljKvXcyZBZBXZYjjFFba3KoCEOjGFnhCJUHOfqnk0DVCxmqhHKQ6HwhvxhNWPjtrZ8s0PZXn3zrZtCsir3TeqpmqZLTgrIjJRlaJplwFMFl5iYuWJqZT1GTfMAVlRD/QiQTwjuxkPki40PYc/+HHVRiKz+6Jg6r0aHG7KWiM1r/QtUkNyLKKsIfGKMKllo8RJbgce7dz1VDTZah04jMtoxM9DjpnOb5qq6yCqlZjuutrPASQ==";
SortedDictionary<string, object> dic = new SortedDictionary<string, object>();
dic.Add("appid", WeChatConfig.APPID);
dic.Add("type", "MERCHANT_ID");
dic.Add("account", "15333560710");
dic.Add("name", enrypt_name);
dic.Add("relation_type", "PARTNER");
var data = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
var url = "https://api.mch.weixin.qq.com/v3/profitsharing/receivers/add";
var path = System.Environment.CurrentDirectory + "/wwwroot/apiclient_cert.p12";
X509Certificate2 cert = new X509Certificate2(path, WeChatConfig.MCHID, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
var serial_no = cert.SerialNumber;
string result = RequestData(url, data, WeChatConfig.MCHID, serial_no, public_key);
return result;
}
发送请求
/// <summary>
/// 发送请求至微信
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="mchid"></param>
/// <param name="serial_no"></param>
/// <param name="public_key"></param>
/// <returns></returns>
public static string RequestData(string url, string data, string mchid, string serial_no, string public_key)
{
byte[] byte_public_key = Encoding.UTF8.GetBytes(public_key);
var encrypt_serial_no = RSAEncrypt("1D99F55A2525B50D10571B129F274FB801769CBB", byte_public_key);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json;";
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36";
request.Accept = "application/json";
string authorization = GetAuthorization(url, "POST", data, mchid, serial_no);
request.Headers.Add("Authorization", authorization);
request.Headers.Add("Wechatpay-Serial", encrypt_serial_no);
byte[] paramJsonBytes;
paramJsonBytes = Encoding.UTF8.GetBytes(data);
request.ContentLength = paramJsonBytes.Length;
Stream writer;
try
{
writer = request.GetRequestStream();
}
catch (Exception)
{
writer = null;
}
writer.Write(paramJsonBytes, 0, paramJsonBytes.Length);
writer.Close();
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
response = ex.Response as HttpWebResponse;
}
Stream resStream = response.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
string text = reader.ReadToEnd();
return text;
}
加密敏感信息
/// <summary>
/// 加密微信支付平台证书序列号
/// </summary>
/// <param name="text">微信支付平台证书序列号</param>
/// <param name="publicKey">公钥</param>
/// <returns></returns>
public static string RSAEncrypt(string text, byte[] publicKey)
{
var cer = new X509Certificate2(publicKey);
var rsaParam = cer.GetRSAPublicKey().ExportParameters(true);
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParam);
var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), true);
return Convert.ToBase64String(buff);
}
签名
protected static string Sign(string message)
{
var path = System.Environment.CurrentDirectory + "/wwwroot/apiclient_cert.p12";
X509Certificate2 cert = new X509Certificate2(path, WeChatConfig.MCHID, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
var privateKey = cert.PrivateKey.ToXmlString(true);
using (RSACryptoServiceProvider sha256 = new RSACryptoServiceProvider())
{
byte[] dataInBytes = Encoding.UTF8.GetBytes(message);
sha256.FromXmlString(privateKey);
byte[] inArray = sha256.SignData(dataInBytes, CryptoConfig.MapNameToOID("SHA256"));
string sign = Convert.ToBase64String(inArray);
return sign;
}
}
获取签名
/// <summary>
/// 获取签名认证
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="method">请求方法</param>
/// <param name="data">数据对象</param>
/// <param name="mchid">商户ID</param>
/// <param name="serial_no">商户私钥证书对应的序列号</param>
/// <returns></returns>
protected static string GetAuthorization(string url, string method, string data, string mchid, string serial_no)
{
var uri = new Uri(url);
string url_path = uri.PathAndQuery;
string nonce = Guid.NewGuid().ToString();
var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
method = string.IsNullOrEmpty(method) ? "" : method;
string message = string.Format("{0}\n{1}\n{2}\n{3}\n", method, url_path, timestamp, nonce);
if (!string.IsNullOrEmpty(data))
{
message = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n", method, url_path, timestamp, nonce, data);
}
string sign = Sign(message);
// 签名认证格式
string authorization = string.Format("WECHATPAY2-SHA256-RSA2048 mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"",
mchid,
nonce,
timestamp,
serial_no,
sign
);
return authorization;
}
111
请问你这个问题最终解决了吗?我现在也遇到这个问题了,怎么尝试都不行。
你既然说你用的没错,放postman里面去验证,报错说明还是你用的不对