/// <summary> /// 初始化微信支付参数生成器 /// </summary> /// <param name="config">配置</param> public WechatPayParameterBuilder(WechatPayConfig config, HttpRequest httpRequest = null) { config.CheckNull(nameof(config)); Config = config; Builder = new ParameterBuilder(); Request = httpRequest; }
/// <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 }); }
/// <summary> /// 验证 /// </summary> protected void Validate(WechatPayConfig config, TPayParam param) { config.CheckNull(nameof(config)); param.CheckNull(nameof(param)); config.Validate(); param.Validate(); ValidateParam(param); }
/// <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); }
/// <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); }
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); }
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)); }
/// <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 }); }
/// <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 }, }); }
protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetTransfersUrl()); }
/// <summary> /// 获取URL /// </summary> /// <param name="config"></param> /// <returns></returns> protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetMicroPayUrl()); }
/// <summary> /// 获取功能Url /// </summary> /// <returns></returns> protected abstract string GetRequestUrl(WechatPayConfig config);
protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetRefundQueryUrl()); }
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; }
/// <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()); }
public override void SetConfig(WechatPayConfig config) { base.SetConfig(config); _wechatPublicKeyService.SetConfig(Config); }
protected virtual string GetRequestUrl(WechatPayConfig config) { return(config.GetBizPayUrl()); }
protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetPublicKeyUrl()); }
protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetDeleteContractUrl()); }
/// <summary> /// 获取功能Url /// </summary> /// <returns></returns> protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetOrderCloseUrl()); }
protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetSendGroupredPackUrl()); }
protected override string GetRequestUrl(WechatPayConfig config) { return(config.GetH5EntrustWebUrl()); }