Пример #1
0
 /// <summary>
 /// 初始化微信支付参数生成器
 /// </summary>
 /// <param name="config">配置</param>
 public WechatPayParameterBuilder(WechatPayConfig config, HttpRequest httpRequest = null)
 {
     config.CheckNull(nameof(config));
     Config  = config;
     Builder = new ParameterBuilder();
     Request = httpRequest;
 }
Пример #2
0
 /// <summary>
 /// 初始化微信支付结果
 /// </summary>
 /// <param name="configProvider">配置提供器</param>
 /// <param name="response">xml响应消息</param>
 public WechatPayResult(WechatPayConfig wechatPayConfig, string response, HttpRequest httpRequest = null)
 {
     wechatPayConfig.CheckNull(nameof(wechatPayConfig));
     _wechatPayConfig = wechatPayConfig;
     Raw     = response;
     Request = httpRequest;
 }
        /// <summary>
        ///  获取最新的公钥信息
        /// </summary>
        /// <param name="payConfig"></param>
        /// <returns></returns>
        internal static async Task <GetCertItemResp> GetLatestCertsByConfig(WechatPayConfig payConfig)
        {
            if (_wechatCertDics.TryGetValue(payConfig.mch_id, out var certDics))
            {
                var item     = certDics.Values.FirstOrDefault();
                var timeLine = DateTime.Now.ToUtcSeconds();
                if (item != null && item.effective_time < timeLine && item.expire_time > timeLine)
                {
                    return(new GetCertItemResp()
                    {
                        item = item
                    });
                }
            }

            var refreshDicRes = await RefreshCertsByConfig(payConfig);

            if (!refreshDicRes.IsSuccess())
            {
                return(refreshDicRes.ToResp <GetCertItemResp>());
            }

            return(new GetCertItemResp()
            {
                item = refreshDicRes.dics.Values.First()
            });
        }
        /// <summary>
        /// 根据微信商户配置,验证结果签名
        /// </summary>
        /// <param name="payConfig">支付配置</param>
        /// <param name="signature">微信返回头信息中的签名</param>
        /// <param name="serialNo">微信返回头信息中的平台证书编号</param>
        /// <param name="nonce">微信返回头信息中的随机串</param>
        /// <param name="timestamp">微信返回头信息中的时间戳</param>
        /// <param name="respBody">微信返回的内容字符串</param>
        /// <returns></returns>
        public static async Task <WechatBaseResp> Verify(WechatPayConfig payConfig, string signature,
                                                         string serialNo, string nonce, long timestamp, string respBody)
        {
            var certRes = await GetCertsByConfigAndSNo(payConfig, serialNo);

            if (!certRes.IsSuccess())
            {
                return(certRes);
            }

            var cert = certRes.item;

            var verContent = $"{timestamp}\n{nonce}\n{respBody}\n";
            var isOk       = cert.cert_public_key.VerifyData(Encoding.UTF8.GetBytes(verContent),
                                                             Convert.FromBase64String(signature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

            if (isOk)
            {
                return(new WechatBaseResp());
            }

            var errRes = new WechatBaseResp()
            {
                code          = RespCodes.ParaSignError.ToString(),
                message       = "验证微信支付签名失败!",
                response_body = respBody
            };

            errRes.ret = (int)RespCodes.ParaSignError;
            return(errRes);
        }
        private static async Task <GetCertItemResp> GetCertsByConfigAndSNo(WechatPayConfig payConfig, string serialNo)
        {
            if (_wechatCertDics.TryGetValue(payConfig.mch_id, out var certDics) &&
                certDics.TryGetValue(serialNo, out var item))
            {
                return new GetCertItemResp()
                       {
                           item = item
                       }
            }
            ;

            var refreshDicRes = await RefreshCertsByConfig(payConfig);

            if (!refreshDicRes.IsSuccess())
            {
                return(refreshDicRes.ToResp <GetCertItemResp>());
            }

            var dics = refreshDicRes.dics;

            if (dics.TryGetValue(serialNo, out item))
            {
                return(new GetCertItemResp()
                {
                    item = item
                });
            }

            return(new GetCertItemResp()
            {
                code = "Unknow", message = $"最新的微信平台公钥证书列表不存在证书(编号{serialNo})", response_body = refreshDicRes.response_body
            });
        }
Пример #6
0
 /// <summary>
 /// 验证
 /// </summary>
 protected void Validate(WechatPayConfig config, TPayParam param)
 {
     config.CheckNull(nameof(config));
     param.CheckNull(nameof(param));
     config.Validate();
     param.Validate();
     ValidateParam(param);
 }
Пример #7
0
        /// <summary>
        /// 请求结果
        /// </summary>
        protected async Task <WechatPayResult <TResponse> > RequstResult <TResponse>(WechatPayConfig config, WechatPayParameterBuilder builder) where TResponse : WechatPayResponse
        {
            var result = await CreateWechatPayResult <TResponse>(config, builder);

            WriteLog(config, builder, result);
            await ValidateResult(result);

            return(result);
        }
Пример #8
0
        /// <summary>
        /// 写日志
        /// </summary>
        protected virtual void WriteLog <TResponse>(WechatPayConfig config, WechatPayParameterBuilder builder, WechatPayResult <TResponse> result) where TResponse : WechatPayResponse
        {
            var logContent = LogContentBuilder.CreateLogContentBuilder()
                             .SetEventId(Guid.NewGuid()).SetMoudle(GetType().FullName).SetTitle("微信支付")
                             .AddContent($"支付方式 : {GetType()}")
                             .AddContent($"支付网关 : {config.GetOrderUrl()}")
                             .AddContent($"原始响应:{result?.Raw}")
                             .Build();

            Logger.LogInfo(logContent);
        }
Пример #9
0
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     _url.CheckNull(nameof(config));
     if (_url.StartsWith("http"))
     {
         return(_url);
     }
     else
     {
         return(config.GetUrl(_url));
     }
 }
        /// <summary>
        /// 获取商户对应的私钥证书信息
        /// </summary>
        /// <param name="payConfig"></param>
        /// <returns></returns>
        internal static MchPrivateCertificate GetMchPrivateCertificate(WechatPayConfig payConfig)
        {
            if (_mchCertDics.TryGetValue(payConfig.mch_id, out var mchPrivateCert))
            {
                return(mchPrivateCert);
            }

            var pCert = GetCertificateInfo(payConfig.mch_id, payConfig.cert_path, payConfig.cert_password);

            _mchCertDics[payConfig.mch_id] = pCert;

            return(pCert);
        }
Пример #11
0
        public static IWechatBuilder AddWechatPay(this IServiceCollection services, WechatPayConfig defaultConfig = null)
        {
            var provider = new WechatPayConfigStorage();

            if (defaultConfig != null)
            {
                //添加默认的配置
                provider.AddWechatPayConfig("default", defaultConfig);
            }
            services.AddSingleton <IWechatPayConfigStorage>(provider);
            services.AddSingleton <IWechatPayConfigFactory, WechatPayConfigFactory>();
            services.AddSingleton <IWehcatPayServiceProvider, WehcatPayServiceProvider>();

            services.AddPayService(typeof(WechatPayExtensions).Assembly, PayOriginType.WechatPay);
            return(new WechatBuilder(services));
        }
Пример #12
0
        /// <summary>
        /// 发送请求
        /// </summary>
        protected async Task <string> Request(WechatPayConfig config, WechatPayParameterBuilder builder)
        {
            //先这样处理把,看看有什么好的优化方案,实在不行通过反射把数据绑定上去,
            //暂时不用IHttpClientFactory
            //var client = HttpClientFactory.CreateClient("wechat");

            var handler = new HttpClientHandler()
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                SslProtocols             = SslProtocols.Tls12,
            };

            if (UseCertificate())
            {
                if (config.CertificateData != null)
                {
                    var certificate = new X509Certificate2(config.CertificateData, config.CertificatePwd, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

                    handler.ClientCertificates.Add(certificate);
                    handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
                    handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
                }
                else
                {
                    throw new Exception($"请求{GetRequestUrl(config)}需要证书");
                }
            }

            var client = new HttpClient(handler);

            if (_extParam != null && _extParam.Any())
            {
                foreach (var item in _extParam)
                {
                    builder.Add(item.Key, item.Value);
                }
            }
            HttpResponseMessage response = await Web.Client(client)
                                           .Post(GetRequestUrl(config))
                                           .Data(BuildHttpContent(builder))
                                           .ResultAsync();

            return(await response?.Content?.ReadAsStringAsync());
        }
        // 刷新获取微信对应的最新公钥信息
        private static async Task <RefreshCertDicResp> RefreshCertsByConfig(WechatPayConfig payConfig)
        {
            var certRes = await(
                WechatPayHelper.WechatPublicCertificateProvider != null
                    ? WechatPayHelper.WechatPublicCertificateProvider.GetCertificates(payConfig)
                    : new WechatCertificateGetReq().SetContextConfig(payConfig).SendAsync()
                );

            if (!certRes.IsSuccess())
            {
                return(certRes.ToResp <RefreshCertDicResp>());
            }

            var dics = certRes.data.Select(wcert =>
            {
                var encryptCertificate = wcert.encrypt_certificate;

                if (encryptCertificate.algorithm != "AEAD_AES_256_GCM")
                {
                    throw new NotSupportedException($"微信支付返回平台加密证书使用了未提供的加解密算法{encryptCertificate.algorithm}!");
                }

                var certBytes = WechatAesGcmHelper.DecryptFromBase64(payConfig.api_v3_key, encryptCertificate.nonce,
                                                                     encryptCertificate.ciphertext, encryptCertificate.associated_data);

                var cert = new WechatCertificateItem
                {
                    serial_no       = wcert.serial_no,
                    effective_time  = DateTime.Parse(wcert.effective_time).ToUtcSeconds(),
                    expire_time     = DateTime.Parse(wcert.expire_time).ToUtcSeconds(),
                    cert_public_key = new X509Certificate2(certBytes).GetRSAPublicKey()
                };
                return(cert);
            }).OrderByDescending(c => c.effective_time).ToDictionary(c => c.serial_no, c => c);

            _wechatCertDics[payConfig.mch_id] = dics ?? new Dictionary <string, WechatCertificateItem>();

            return(new RefreshCertDicResp()
            {
                dics = dics
            });
        }
Пример #14
0
        /// <summary>
        ///   获取js唤起支付的参数信息
        /// </summary>
        /// <param name="payConfig"></param>
        /// <returns></returns>
        public Dictionary <string, string> GetJsPreParas(WechatPayConfig payConfig)
        {
            var timeStamp = DateTime.Now.ToUtcSeconds().ToString();
            var appId     = payConfig.app_id;
            var nonceStr  = NumHelper.RandomNum(8);
            var package   = $"prepay_id={prepay_id}";

            var waitSignData = $"{appId}\n{timeStamp}\n{nonceStr}\n{package}\n";
            var privateCert  = WechatCertificateHelper.GetMchPrivateCertificate(payConfig);
            var signature    = WechatCertificateHelper.Sign(privateCert.private_key, waitSignData);

            return(new Dictionary <string, string>()
            {
                //{"appId", appId},
                { "timeStamp", timeStamp },
                { "nonceStr", nonceStr },
                { "package", package },

                { "signType", "RSA" },
                { "paySign", signature },
            });
        }
Пример #15
0
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetTransfersUrl());
 }
Пример #16
0
 /// <summary>
 /// 获取URL
 /// </summary>
 /// <param name="config"></param>
 /// <returns></returns>
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetMicroPayUrl());
 }
Пример #17
0
 /// <summary>
 /// 获取功能Url
 /// </summary>
 /// <returns></returns>
 protected abstract string GetRequestUrl(WechatPayConfig config);
Пример #18
0
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetRefundQueryUrl());
 }
Пример #19
0
        protected async Task <WechatPayResult <TResponse> > CreateWechatPayResult <TResponse>(WechatPayConfig config, WechatPayParameterBuilder builder) where TResponse : WechatPayResponse
        {
            var result = new WechatPayResult <TResponse>(Config, await Request(config, builder));

            await ResoveResult(result);

            return(result);
        }
 public void SetConfig(WechatPayConfig config)
 {
     Config = config;
 }
Пример #21
0
 /// <summary>
 /// 获取功能Url
 /// </summary>
 /// <returns></returns>
 protected override string GetRequestUrl(WechatPayConfig config, WechatPayPayRequestBase param)
 {
     return(config.GetOrderUrl());
 }
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetDownloadFundFlowUrl());
 }
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetBatchQueryCommentUrl());
 }
Пример #24
0
 public override void SetConfig(WechatPayConfig config)
 {
     base.SetConfig(config);
     _wechatPublicKeyService.SetConfig(Config);
 }
 protected virtual string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetBizPayUrl());
 }
Пример #26
0
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetPublicKeyUrl());
 }
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetDeleteContractUrl());
 }
Пример #28
0
 /// <summary>
 /// 获取功能Url
 /// </summary>
 /// <returns></returns>
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetOrderCloseUrl());
 }
Пример #29
0
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetSendGroupredPackUrl());
 }
Пример #30
0
 protected override string GetRequestUrl(WechatPayConfig config)
 {
     return(config.GetH5EntrustWebUrl());
 }