.NET接入微信支付(四)平台证书
电脑版发表于:2023/2/23 17:05
/// <summary>
/// 平台证书类
/// </summary>
public class WxPayPlateformCertificate
{
public string serial_no { get; set; }
public DateTimeOffset effective_time { get; set; }
public DateTimeOffset expire_time { get; set; }
public EncryptInfo encrypt_certificate { get; set; }
InMemoryCertificateManager certificateManager = InMemoryCertificateManager.Instance;
/// <summary>
/// 获取平台证书
/// </summary>
/// <param name="serialNo"></param>
/// <param name="options"></param>
/// <returns></returns>
public X509Certificate2 GetPlatformCertificate(string url, string serialNo, string secretKey)
{
var certificate = certificateManager.GetCertificate(serialNo);
if (certificate != null)
{
return certificate;
}
Logger loger = LogManager.GetCurrentClassLogger();
loger.Info("更新平台证书:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
var response = HttpService.Execute("", url, "GET");
if (string.IsNullOrWhiteSpace(response) || response.Length == 0)
{
throw new Exception("GET PLATFORM CERTIFICATE FAILED! 获取平台证书失败!");
}
JObject jObject = JObject.Parse(response);
string resultStr = jObject["data"].ToString();
List<WxPayPlateformCertificate> platformCertificates = resultStr.FromJsonObj<List<WxPayPlateformCertificate>>();
foreach (var item in platformCertificates)
{
switch (item.encrypt_certificate.algorithm)
{
case "AEAD_AES_256_GCM":
{
serialNo = item.serial_no;
certificateManager.SetCertificate(item.serial_no, new X509Certificate2(WxPayDecrypt.Decrypt(secretKey, item.encrypt_certificate)));
}
break;
default:
throw new Exception("Unsupported Encrypt Algorithm!");
}
}
return certificateManager.GetCertificate(serialNo);
}
}
/// <summary>
/// 微信商户平台证书管理器接口。
/// </summary>
public abstract class CertificateManager
{
/// <summary>
/// 根据证书序列号获取证书(cer 格式)。
/// </summary>
/// <param name="serialNumber"></param>
/// <returns></returns>
public abstract X509Certificate2 GetCertificate(string serialNumber);
/// <summary>
/// 设置证书序列号与证书(cer 格式)的映射关系。
/// </summary>
/// <param name="serialNumber"></param>
/// <param name="certificate"></param>
public abstract void SetCertificate(string serialNumber, X509Certificate2 certificate);
}
/// <summary>
/// 一个基于内存实现的 <see cref="CertificateManager"/>。
/// </summary>
public class InMemoryCertificateManager : CertificateManager
{
private IDictionary<string, X509Certificate2> _dict;
private static object lockObject = new object();
static InMemoryCertificateManager _;
public static InMemoryCertificateManager Instance
{
get
{
if (_ == null)
{
lock (lockObject)
{
if (_ == null)
_ = new InMemoryCertificateManager();
}
}
return _;
}
}
private InMemoryCertificateManager()
{
_dict = new ConcurrentDictionary<string, X509Certificate2>();
}
public override X509Certificate2 GetCertificate(string serialNumber)
{
if (serialNumber == null) throw new ArgumentNullException(nameof(serialNumber));
return _dict[serialNumber];
}
public override void SetCertificate(string serialNumber, X509Certificate2 certificate)
{
if (serialNumber == null) throw new ArgumentNullException(nameof(serialNumber));
if (certificate == null) throw new ArgumentNullException(nameof(certificate));
_dict[serialNumber] = certificate;
}
}