Roc 8 лет назад
Родитель
Сommit
cb7d1f3198

+ 17 - 3
README.MD

@@ -3,15 +3,29 @@
 <p>微信支付:<a href="https://pay.weixin.qq.com/wiki/doc/api/index.html" target="_blank">开发文档</a>、<a href="http://wxpay.wxutil.com/qa/index.php" target="_blank">问答中心</a>、<a href="http://kf.qq.com/product/wechatpaymentmerchant.html" target="_blank">帮助中心</a></p>
 <p>QQ钱包:<a href="https://qpay.qq.com/qpaywiki.shtml" target="_blank">开发文档</a>、<a href="http://kf.qq.com/product/qq_enterprise.html" target="_blank">帮助中心</a></p>
 <p>京东支付:<a href="http://payapi.jd.com/" target="_blank">开发文档</a></p>
-<h3>*参数配置(3选1,推荐使用3):</h3>
+<h3>*添加依赖注入:</h3>
+<p>
+    services.AddAlipay();<br />
+    services.AddWeChatPay();<br />
+    services.AddQPay();<br />
+    services.AddJdPay();
+</p>
+<h3>*注册绑定配置(参数配置3):</h3>
+<p>
+    services.Configure<AlipayOptions>(Configuration.GetSection("Alipay"));<br />
+    services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"));<br />
+    services.Configure<QPayOptions>(Configuration.GetSection("QPay"));<br />
+    services.Configure<JdPayOptions>(Configuration.GetSection("JdPay"));
+</p>
+<h3>*参数配置方式(3选1,推荐使用3):</h3>
 <p>1.使用代码配置如:services.AddAlipay(Options => { Options.AppId = ""; });</p>
 <p>2.使用<a href="https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration?tabs=basicconfiguration" target="_blank">"配置文件"</a>的方式,可在appsetting.json、appsettings.Development.json设置参数</p>
 <p>3.使用<a href="https://docs.microsoft.com/zh-cn/aspnet/core/security/app-secrets?tabs=visual-studio" target="_blank">"用户机密"</a>的方式,可在VS中右键项目->管理用户机密,再设置参数(与2相似)。</p>
 <p>*参数详情可见Startup.cs文件的ConfigureServices方法下的注释代码"配置参数"。</p>
-<p>*WeChatPay,QPay中的Certificate参数为证书文件转成的Base64字符串(方便配置存储)。</p>
+<p>*WeChatPay,QPay中的Certificate参数可以是文件名或者Base64字符串(将证书文件转成Base64,方便配置存储)。</p>
 <h3>*注意:</h3>
 <p>1.示例开发环境:Windows10、VS2017 15.4.4、.Net Core 2.0.3</p>
 <p>2.支持渠道:支付宝、微信支付、QQ钱包、京东支付(仅扫码支付)。</p>
 <p>3.示例使用了依赖注入与用户机密(见Startup.cs文件的ConfigureServices方法),需要自行配置(可以参考上方"参数配置")。当然你不使用依赖注入方式,自己new AlipayClient(...,...)/new WeChatPayClient(...,...)再调用也可以。</p>
 <p>4.部分API未做示例,可根据现有示例与官网API参数文档自行调用(除京东支付外其他支付的API基本齐全了)。</p>
-<p>5.接收支付渠道通知(NotifyController.cs文件)需要公网环境运行(另外记得修改notify_url参数)。</p>
+<p>5.接收支付渠道通知(NotifyController.cs文件)需要公网环境运行(另外记得修改notify_url参数)。</p>

+ 0 - 2
samples/WebApplicationSample/Startup.cs

@@ -53,13 +53,11 @@ namespace WebApplicationSample
             //    "MchId": "xxx",
             //    "Key": "xxx",
             //    "Certificate": "xxx",
-            //    "Password": "xxx"
             //  },
             //  "QPay": {
             //    "MchId": "xxx",
             //    "Key": "xxx",
             //    "Certificate": "xxx",
-            //    "Password": "xxx"
             //  },
             //  "JdPay": {
             //    "Merchant": "xxx",

+ 16 - 1
samples/WebApplicationSample/Views/Home/Index.cshtml

@@ -21,11 +21,26 @@
             <p>微信支付:<a href="https://pay.weixin.qq.com/wiki/doc/api/index.html" target="_blank">开发文档</a>、<a href="http://wxpay.wxutil.com/qa/index.php" target="_blank">问答中心</a>、<a href="http://kf.qq.com/product/wechatpaymentmerchant.html" target="_blank">帮助中心</a></p>
             <p>QQ钱包:<a href="https://qpay.qq.com/qpaywiki.shtml" target="_blank">开发文档</a>、<a href="http://kf.qq.com/product/qq_enterprise.html" target="_blank">帮助中心</a></p>
             <p>京东支付:<a href="http://payapi.jd.com/" target="_blank">开发文档</a></p>
-            <h3>*参数配置(3选1,推荐使用3):</h3>
+            <h3>*添加依赖注入:</h3>
+            <p>
+                services.AddAlipay();<br />
+                services.AddWeChatPay();<br />
+                services.AddQPay();<br />
+                services.AddJdPay();
+            </p>
+            <h3>*注册绑定配置(参数配置3):</h3>
+            <p>
+                services.Configure<AlipayOptions>(Configuration.GetSection("Alipay"));<br />
+                services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"));<br />
+                services.Configure<QPayOptions>(Configuration.GetSection("QPay"));<br />
+                services.Configure<JdPayOptions>(Configuration.GetSection("JdPay"));
+            </p>
+            <h3>*参数配置方式(3选1,推荐使用3):</h3>
             <p>1.使用代码配置如:services.AddAlipay(Options => { Options.AppId = ""; });</p>
             <p>2.使用<a href="https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration?tabs=basicconfiguration" target="_blank">"配置文件"</a>的方式,可在appsetting.json、appsettings.Development.json设置参数</p>
             <p>3.使用<a href="https://docs.microsoft.com/zh-cn/aspnet/core/security/app-secrets?tabs=visual-studio" target="_blank">"用户机密"</a>的方式,可在VS中右键项目->管理用户机密,再设置参数(与2相似)。</p>
             <p>*参数详情可见Startup.cs文件的ConfigureServices方法下的注释代码"配置参数"。</p>
+            <p>*WeChatPay,QPay中的Certificate参数可以是文件名或者Base64字符串(将证书文件转成Base64,方便配置存储)。</p>
             <h3>*注意:</h3>
             <p>1.示例开发环境:Windows10、VS2017 15.4.4、.Net Core 2.0.3</p>
             <p>2.支持渠道:支付宝、微信支付、QQ钱包、京东支付(仅扫码支付)。</p>

+ 8 - 6
src/Essensoft.AspNetCore.Alipay/AlipayNotifyClient.cs

@@ -60,13 +60,15 @@ namespace Essensoft.AspNetCore.Alipay
             }
 
             var sign = parameters["sign"];
-            if (!string.IsNullOrEmpty(sign))
+            if (string.IsNullOrEmpty(sign))
             {
-                var prestr = GetSignContent(parameters);
-                if (!AlipaySignature.RSACheckContent(prestr, sign, alipayPublicKey, signType))
-                {
-                    throw new AlipayException("sign check fail: check Sign and Data Fail JSON also");
-                }
+                throw new AlipayException("sign check fail: sign is Empty!");
+            }
+
+            var prestr = GetSignContent(parameters);
+            if (!AlipaySignature.RSACheckContent(prestr, sign, alipayPublicKey, signType))
+            {
+                throw new AlipayException("sign check fail: check Sign and Data Fail JSON also");
             }
         }
 

+ 7 - 1
src/Essensoft.AspNetCore.QPay/QPayCertificateClient.cs

@@ -6,6 +6,7 @@ using System;
 using System.Net.Http;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading.Tasks;
+using System.IO;
 
 namespace Essensoft.AspNetCore.QPay
 {
@@ -26,7 +27,12 @@ namespace Essensoft.AspNetCore.QPay
         {
             Options = optionsAccessor?.Value ?? new QPayOptions();
             ClientHandler = new HttpClientHandler();
-            ClientHandler.ClientCertificates.Add(new X509Certificate2(Convert.FromBase64String(Options.Certificate), Options.MchId));
+
+            if (File.Exists(Options.Certificate)) // 是文件则以文件名的形式创建,否则以Base64String方式
+                ClientHandler.ClientCertificates.Add(new X509Certificate2(Options.Certificate, Options.MchId));
+            else
+                ClientHandler.ClientCertificates.Add(new X509Certificate2(Convert.FromBase64String(Options.Certificate), Options.MchId));
+
             Client = new HttpClientEx(ClientHandler);
         }
 

+ 8 - 6
src/Essensoft.AspNetCore.QPay/QPayNotifyClient.cs

@@ -41,13 +41,15 @@ namespace Essensoft.AspNetCore.QPay
             }
 
             var sign = response?.Sign;
-            if (!string.IsNullOrEmpty(sign))
+            if (string.IsNullOrEmpty(sign))
             {
-                var cal_sign = Md5.GetMD5WithKey(response.Parameters, Options.Key);
-                if (cal_sign != sign)
-                {
-                    throw new Exception("sign check fail: check Sign and Data Fail!");
-                }
+                throw new Exception("sign check fail: sign is Empty!");
+            }
+
+            var cal_sign = Md5.GetMD5WithKey(response.Parameters, Options.Key);
+            if (cal_sign != sign)
+            {
+                throw new Exception("sign check fail: check Sign and Data Fail!");
             }
         }
     }

+ 1 - 1
src/Essensoft.AspNetCore.QPay/QPayOptions.cs

@@ -23,7 +23,7 @@
         public string Key { get; set; }
 
         /// <summary>
-        /// API证书 Base64String
+        /// API证书文件 Base64字符串 或着 证书文件名 
         /// </summary>
         public string Certificate { get; set; }
     }

+ 8 - 6
src/Essensoft.AspNetCore.Security/crypto/security/DotNetUtilities.cs

@@ -231,13 +231,15 @@ namespace Essensoft.AspNetCore.Security.Security
 
         private static RSA CreateRSAProvider(RSAParameters rp)
         {
-            CspParameters csp = new CspParameters();
-            csp.KeyContainerName = string.Format("BouncyCastle-{0}", Guid.NewGuid());
-            RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
-            rsaCsp.ImportParameters(rp);
-            return rsaCsp;
+            //CspParameters csp = new CspParameters();
+            //csp.KeyContainerName = string.Format("BouncyCastle-{0}", Guid.NewGuid());
+            //RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
+            //rsaCsp.ImportParameters(rp);
+            var rsa = RSA.Create();
+            rsa.ImportParameters(rp);
+            return rsa;
         }
-	}
+    }
 }
 
 #endif

+ 7 - 1
src/Essensoft.AspNetCore.WeChatPay/WeChatPayCertificateClient.cs

@@ -6,6 +6,7 @@ using System;
 using System.Net.Http;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading.Tasks;
+using System.IO;
 
 namespace Essensoft.AspNetCore.WeChatPay
 {
@@ -31,7 +32,12 @@ namespace Essensoft.AspNetCore.WeChatPay
         {
             Options = optionsAccessor?.Value ?? new WeChatPayOptions();
             ClientHandler = new HttpClientHandler();
-            ClientHandler.ClientCertificates.Add(new X509Certificate2(Convert.FromBase64String(Options.Certificate), Options.MchId));
+
+            if (File.Exists(Options.Certificate)) // 是文件则以文件名的形式创建,否则以Base64String方式
+                ClientHandler.ClientCertificates.Add(new X509Certificate2(Options.Certificate, Options.MchId));
+            else
+                ClientHandler.ClientCertificates.Add(new X509Certificate2(Convert.FromBase64String(Options.Certificate), Options.MchId));
+
             Client = new HttpClientEx(ClientHandler);
         }
 

+ 8 - 6
src/Essensoft.AspNetCore.WeChatPay/WeChatPayNotifyClient.cs

@@ -49,13 +49,15 @@ namespace Essensoft.AspNetCore.WeChatPay
             }
 
             var sign = response?.Sign;
-            if (!response.IsError && !string.IsNullOrEmpty(sign))
+            if (string.IsNullOrEmpty(sign))
             {
-                var cal_sign = Md5.GetMD5WithKey(response.Parameters, Options.Key);
-                if (cal_sign != sign)
-                {
-                    throw new Exception("sign check fail: check Sign and Data Fail!");
-                }
+                throw new Exception("sign check fail: sign is Empty!");
+            }
+
+            var cal_sign = Md5.GetMD5WithKey(response.Parameters, Options.Key);
+            if (cal_sign != sign)
+            {
+                throw new Exception("sign check fail: check Sign and Data Fail!");
             }
         }
     }

+ 2 - 2
src/Essensoft.AspNetCore.WeChatPay/WeChatPayOptions.cs

@@ -23,12 +23,12 @@
         public string Key { get; set; }
 
         /// <summary>
-        /// API证书 Base64String
+        /// API证书文件 Base64字符串 或着 证书文件名
         /// </summary>
         public string Certificate { get; set; }
 
         /// <summary>
-        /// RSA公钥
+        /// RSA公钥 企业付款到银行卡
         /// </summary>
         public string RsaPublicKey { get; set; }
     }