• C# 数字证书加载 X509Certificate2


    /*说明:

    iisweb应用使用X509Certificate2加载证书时需要设置应用程序池的“允许加载用户配置文件”为True,切记!

    证书的商户中文名采用正则表达式截取

    */

    /// <summary>
    /// 微信退款申请
    /// </summary>
    /// <param name="enterpriseId">企业id</param>
    /// <param name="mchId">商户号</param>
    /// <param name="refundXmlStr">退款请求的xml实体</param>
    /// <returns></returns>
    public OperationResult Refund(string enterpriseId, string mchId, string refundXmlStr)
    {
    OperationResult response = new OperationResult
    {
    Code = OperationResultType.Error
    };
    try
    {
    //string certificationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "Certification", "WeiXin", enterpriseId);
    string certificationPath = $"D:\Certification\WeiXin\{enterpriseId}";
    LogHelper.Info($"certificationPath={ certificationPath}");
    if (!Directory.Exists(certificationPath))
    {
    response.Message = $"不存在企业{enterpriseId}的有效证书";
    return response;
    }
    var files = Directory.GetFiles(certificationPath, "*.p12");
    if (files.Length <= 0)
    {
    response.Message = $"不存在企业{enterpriseId}的有效证书";
    return response;
    }
    certificationPath = files[0];
    //, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet
    X509Certificate2 certificate = new X509Certificate2(certificationPath, mchId);

    X509Store store1 = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store1.Open(OpenFlags.ReadWrite);
    store1.Add(certificate);
    if (string.IsNullOrWhiteSpace(certificate.SubjectName.Name) || !certificate.SubjectName.Name.Contains("CN"))
    {
    LogHelper.Error($"企业{enterpriseId}证书无效:{certificate.SubjectName.Name}", "WxRefundDomain", "Refund");
    }
    Regex rg = new Regex("(?<=(CN=))[.\s\S]*?(?=(,))", RegexOptions.Multiline | RegexOptions.Singleline);
    var subjectName = rg.Match(certificate.SubjectName.Name).Value;
    store1.Close();

    HttpWebResponse webreponse;
    //系统必须已经导入cert指向的证书
    string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
    X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, subjectName,
    false);
    if (certs.Count > 0)
    {
    X509Certificate2 cert = certs[0];

    HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);

    webrequest.ClientCertificates.Add(cert);
    webrequest.Method = "post";
    webrequest.KeepAlive = true;

    byte[] bdata = Encoding.UTF8.GetBytes(refundXmlStr);
    webrequest.ContentType = "application/xml;charset=utf-8";
    webrequest.ContentLength = bdata.Length;
    Stream streamOut = webrequest.GetRequestStream();
    streamOut.Write(bdata, 0, bdata.Length);
    streamOut.Close();

    webreponse = (HttpWebResponse)webrequest.GetResponse();
    Stream stream = webreponse.GetResponseStream();
    string resp = string.Empty;
    using (StreamReader reader = new StreamReader(stream))
    {
    resp = reader.ReadToEnd();
    }
    if (!string.IsNullOrWhiteSpace(resp))
    {
    LogHelper.Info($"微信退款返回:{resp}", "WxRefundDomain", "Refund");
    try
    {
    var res = WxXmlHelper.DESerializer<WxRefundResponse>(resp);
    //签名校验

    if (res.return_code.Equals("SUCCESS"))//接口响应成功
    {
    if (res.result_code.Equals("SUCCESS"))//申请成功
    {
    response.Code = OperationResultType.Success;
    response.Message = res.return_msg;
    return response;
    }
    //申请失败
    response.Code = OperationResultType.IllegalOperation;
    response.Message = res.err_code_des;
    return response;
    }
    //接口异常
    response.Message = res.return_msg;
    LogHelper.Error($"微信退款失败:{resp}", "WxRefundDomain", "Refund");
    return response;
    }
    catch (Exception)
    {
    throw;
    }
    }
    }
    }
    catch (Exception ex)
    {
    response.Message = ex.Message;
    LogHelper.Error("微信退款失败", ex, "WxRefundDomain", "Refund");
    }
    return response;

  • 相关阅读:
    vue中@事件处理函数的柯里化
    一个例子生动理解js的原型_js的原型prototype和__protopy__区别
    vue3自定义v-model
    js初始化一个特定值的array
    dom的clientHeight、scrollHeight以及offsetHeight
    ts踩坑记录
    常见问题1
    资料share
    几种开放源码的TCPIP协议栈
    阻塞与非阻塞,同步与异步
  • 原文地址:https://www.cnblogs.com/zlj-rechio/p/9953634.html
Copyright © 2020-2023  润新知