Browse Source

1.2.1

1.修复1.2.0 由手误造成 微信支付响应解析'MchId'被当作'sub_appid'处理.
2.WeChatPayCertificateClient\QPayCertificateClient 功能分别合并至WeChatPayClient \QPayClient.
3.增加微信支付APP服务端部分演示
Roc 7 years ago
parent
commit
cb68bb88f0
22 changed files with 308 additions and 374 deletions
  1. 1 1
      Payment.sln
  2. 2 4
      samples/WebApplicationSample/Controllers/QPayController.cs
  3. 46 10
      samples/WebApplicationSample/Controllers/WeChatPayController.cs
  4. 15 1
      samples/WebApplicationSample/Startup.cs
  5. 58 22
      samples/WebApplicationSample/Views/Home/Index.cshtml
  6. 2 2
      samples/WebApplicationSample/WebApplicationSample.csproj
  7. 4 4
      src/Essensoft.AspNetCore.Payment.Alipay/Essensoft.AspNetCore.Payment.Alipay.csproj
  8. 4 3
      src/Essensoft.AspNetCore.Payment.All/Essensoft.AspNetCore.Payment.All.csproj
  9. 4 4
      src/Essensoft.AspNetCore.Payment.JdPay/Essensoft.AspNetCore.Payment.JdPay.csproj
  10. 4 4
      src/Essensoft.AspNetCore.Payment.QPay/Essensoft.AspNetCore.Payment.QPay.csproj
  11. 0 14
      src/Essensoft.AspNetCore.Payment.QPay/IQPayCertificateClient.cs
  12. 0 100
      src/Essensoft.AspNetCore.Payment.QPay/QPayCertificateClient.cs
  13. 40 0
      src/Essensoft.AspNetCore.Payment.QPay/QPayClient.cs
  14. 0 1
      src/Essensoft.AspNetCore.Payment.QPay/ServiceCollectionExtensions.cs
  15. 4 4
      src/Essensoft.AspNetCore.Payment.Security/Essensoft.AspNetCore.Payment.Security.csproj
  16. 4 3
      src/Essensoft.AspNetCore.Payment.UnionPay/Essensoft.AspNetCore.Payment.UnionPay.csproj
  17. 4 4
      src/Essensoft.AspNetCore.Payment.WeChatPay/Essensoft.AspNetCore.Payment.WeChatPay.csproj
  18. 0 14
      src/Essensoft.AspNetCore.Payment.WeChatPay/IWeChatPayCertificateClient.cs
  19. 0 1
      src/Essensoft.AspNetCore.Payment.WeChatPay/ServiceCollectionExtensions.cs
  20. 0 174
      src/Essensoft.AspNetCore.Payment.WeChatPay/WeChatPayCertificateClient.cs
  21. 115 2
      src/Essensoft.AspNetCore.Payment.WeChatPay/WeChatPayClient.cs
  22. 1 2
      src/Essensoft.AspNetCore.Payment.WeChatPay/WeChatPayResponse.cs

+ 1 - 1
Payment.sln

@@ -7,7 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D3871E61-CA4
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DD8CC860-F3E3-40F4-8A8F-20BF66EA051C}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Essensoft.AspNetCore.Payment", "src\Essensoft.AspNetCore.Payment\Essensoft.AspNetCore.Payment.csproj", "{084545C4-FA61-4BF4-913A-59E4C063212D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Essensoft.AspNetCore.Payment.All", "src\Essensoft.AspNetCore.Payment.All\Essensoft.AspNetCore.Payment.All.csproj", "{084545C4-FA61-4BF4-913A-59E4C063212D}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Essensoft.AspNetCore.Payment.Alipay", "src\Essensoft.AspNetCore.Payment.Alipay\Essensoft.AspNetCore.Payment.Alipay.csproj", "{167FAA95-300E-49D5-A29B-EFCFF90A0584}"
 EndProject

+ 2 - 4
samples/WebApplicationSample/Controllers/QPayController.cs

@@ -8,11 +8,9 @@ namespace WebApplicationSample.Controllers
     public class QPayController : Controller
     {
         private readonly QPayClient _client = null;
-        private readonly QPayCertificateClient _certClient = null;
-        public QPayController(QPayClient client, QPayCertificateClient certClient)
+        public QPayController(QPayClient client)
         {
             _client = client;
-            _certClient = certClient;
         }
 
         [HttpPost]
@@ -66,7 +64,7 @@ namespace WebApplicationSample.Controllers
                 OpUserId = op_user_id,
                 OpUserPasswd = op_user_passwd,
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 

+ 46 - 10
samples/WebApplicationSample/Controllers/WeChatPayController.cs

@@ -1,6 +1,8 @@
 using Essensoft.AspNetCore.Payment.WeChatPay;
 using Essensoft.AspNetCore.Payment.WeChatPay.Request;
+using Essensoft.AspNetCore.Payment.WeChatPay.Utility;
 using Microsoft.AspNetCore.Mvc;
+using System;
 using System.Threading.Tasks;
 
 namespace WebApplicationSample.Controllers
@@ -8,11 +10,10 @@ namespace WebApplicationSample.Controllers
     public class WeChatPayController : Controller
     {
         private readonly WeChatPayClient _client = null;
-        private readonly WeChatPayCertificateClient _certClient = null;
-        public WeChatPayController(WeChatPayClient client, WeChatPayCertificateClient certClient)
+
+        public WeChatPayController(WeChatPayClient client)
         {
             _client = client;
-            _certClient = certClient;
         }
 
         [HttpPost]
@@ -32,6 +33,41 @@ namespace WebApplicationSample.Controllers
             return Ok(response.Body);
         }
 
+        [HttpPost]
+        public async Task<IActionResult> AppOrder(string out_trade_no, string body, int total_fee, string spbill_create_ip, string notify_url, string trade_type)
+        {
+            var request = new WeChatPayUnifiedOrderRequest()
+            {
+                OutTradeNo = out_trade_no,
+                Body = body,
+                TotalFee = total_fee,
+                SpbillCreateIp = spbill_create_ip,
+                NotifyUrl = notify_url,
+                TradeType = trade_type,
+            };
+            var response = await _client.ExecuteAsync(request);
+
+            // 组合"调起支付接口"所需参数 :
+
+            var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+            var timeStamp = (long)((DateTime.Now - unixEpoch).TotalSeconds);
+
+            var dic = new WeChatPayDictionary
+            {
+                { "appid", _client.Options.AppId },
+                { "partnerid",_client.Options.MchId  },
+                { "prepayid", response.PrepayId },
+                { "package", "Sign=WXPay" },
+                { "noncestr", Guid.NewGuid().ToString("N") },
+                { "timestamp", timeStamp.ToString() }
+            };
+            // 将这些参数签名
+            dic.Add("sign", WeChatPaySignature.SignWithKey(dic, _client.Options.Key));
+
+            // 将签名后的参数(dic)给 ios/android端 由其去调起微信APP(https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5)
+            return Ok(dic);
+        }
+
         [HttpPost]
         public async Task<IActionResult> OrderQuery(string transaction_id, string out_trade_no)
         {
@@ -68,7 +104,7 @@ namespace WebApplicationSample.Controllers
                 RefundDesc = refund_desc,
                 NotifyUrl = notify_url,
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 
@@ -112,7 +148,7 @@ namespace WebApplicationSample.Controllers
                 Desc = desc,
                 SpbillCreateIp = spbill_create_ip
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 
@@ -123,7 +159,7 @@ namespace WebApplicationSample.Controllers
             {
                 PartnerTradeNo = partner_trade_no,
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 
@@ -131,7 +167,7 @@ namespace WebApplicationSample.Controllers
         public async Task<IActionResult> GetPublicKey()
         {
             var request = new WeChatPayGetPublicKeyRequest();
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 
@@ -147,7 +183,7 @@ namespace WebApplicationSample.Controllers
                 Amount = amount,
                 Desc = desc,
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 
@@ -158,7 +194,7 @@ namespace WebApplicationSample.Controllers
             {
                 PartnerTradeNo = partner_trade_no,
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
 
@@ -171,7 +207,7 @@ namespace WebApplicationSample.Controllers
                 AccountType = account_type,
                 TarType = tar_type,
             };
-            var response = await _certClient.ExecuteAsync(request);
+            var response = await _client.ExecuteAsync(request);
             return Ok(response.Body);
         }
     }

+ 15 - 1
samples/WebApplicationSample/Startup.cs

@@ -35,6 +35,21 @@ namespace WebApplicationSample
             services.AddUnionPay();
             services.AddWeChatPay();
 
+            // 可在添加依赖注入时设置参数
+            // 例如:
+            //services.AddAlipay(opt =>
+            //{
+            //    //一般设置 AppId、RsaPrivateKey、RsaPublicKey,其余默认即可.
+            //    //此处为蚂蚁金服开放平台上创建的APPID,而非老版本的商户号
+            //    opt.AppId = "";
+
+            //    // 这里的公私钥 默认均为支付宝官方推荐使用的RSAWithSHA256.
+            //    // 商户私钥
+            //    opt.RsaPrivateKey = "";
+            //    // 支付宝公钥
+            //    opt.RsaPublicKey = "";
+            //});
+
             // 配置介绍: https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration?tabs=basicconfiguration
             // 用户机密介绍: https://docs.microsoft.com/zh-cn/aspnet/core/security/app-secrets?tabs=visual-studio
 
@@ -81,7 +96,6 @@ namespace WebApplicationSample
             //  },
             //  "WeChatPay": {
             //    "AppId": "xxx",
-            //    "AppSecret": "xxx",
             //    "MchId": "xxx",
             //    "Key": "xxx",
             //    "Certificate": "xxx",

+ 58 - 22
samples/WebApplicationSample/Views/Home/Index.cshtml

@@ -382,17 +382,18 @@
                 <ul>
                     <li><a href="#tabs-purchase-1">扫码支付</a></li>
                     <li><a href="#tabs-purchase-2">公众号支付</a></li>
-                    <li><a href="#tabs-purchase-3">查询订单</a></li>
-                    <li><a href="#tabs-purchase-4">关闭订单</a></li>
-                    <li><a href="#tabs-purchase-5">申请退款</a></li>
-                    <li><a href="#tabs-purchase-6">查询退款</a></li>
-                    <li><a href="#tabs-purchase-7">下载对账单</a></li>
-                    <li><a href="#tabs-purchase-8">企业付款到零钱</a></li>
-                    <li><a href="#tabs-purchase-9">查询付款</a></li>
-                    <li><a href="#tabs-purchase-10">获取RSA加密公钥</a></li>
-                    <li><a href="#tabs-purchase-11">企业付款到银行卡</a></li>
-                    <li><a href="#tabs-purchase-12">查询企业付款银行卡</a></li>
-                    <li><a href="#tabs-purchase-13">下载资金账单</a></li>
+                    <li><a href="#tabs-purchase-3">APP支付</a></li>
+                    <li><a href="#tabs-purchase-4">查询订单</a></li>
+                    <li><a href="#tabs-purchase-5">关闭订单</a></li>
+                    <li><a href="#tabs-purchase-6">申请退款</a></li>
+                    <li><a href="#tabs-purchase-7">查询退款</a></li>
+                    <li><a href="#tabs-purchase-8">下载对账单</a></li>
+                    <li><a href="#tabs-purchase-9">企业付款到零钱</a></li>
+                    <li><a href="#tabs-purchase-10">查询付款</a></li>
+                    <li><a href="#tabs-purchase-11">获取RSA加密公钥</a></li>
+                    <li><a href="#tabs-purchase-12">企业付款到银行卡</a></li>
+                    <li><a href="#tabs-purchase-13">查询企业付款银行卡</a></li>
+                    <li><a href="#tabs-purchase-14">下载资金账单</a></li>
                 </ul>
                 <div id="tabs-purchase-1">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="UnifiedOrder" method="post" target="_blank">
@@ -471,6 +472,42 @@
                     </p>
                 </div>
                 <div id="tabs-purchase-3">
+                    <form class="api-form" asp-controller="WeChatPay" asp-action="AppOrder" method="post" target="_blank">
+                        <p>
+                            <label>out_trade_no:</label>
+                            <input type="text" name="out_trade_no" value="@DateTime.Now.ToString("yyyyMMddHHmmssfff")">
+                        </p>
+                        <p>
+                            <label>body:</label>
+                            <input type="text" name="body" value="微信APP支付支付测试">
+                        </p>
+                        <p>
+                            <label>total_fee:</label>
+                            <input type="text" name="total_fee" value="1" title="单位为分。">
+                        </p>
+                        <p>
+                            <label>spbill_create_ip:</label>
+                            <input type="text" name="spbill_create_ip" value="127.0.0.1">
+                        </p>
+                        <p>
+                            <label>notify_url:</label>
+                            <input type="text" name="notify_url" value="http://www.baidu.com/notify/wechatpay">
+                        </p>
+                        <p>
+                            <label>trade_type:</label>
+                            <input type="text" name="trade_type" value="APP">
+                        </p>
+                        <p>
+                            <label>&nbsp;</label>
+                            <input type="submit" class="button" value="提交">
+                        </p>
+                    </form>
+                    <hr />
+                    <p class="faq">
+                        <a href="https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1" target="_blank">* 查看接口 请求参数、响应参数</a>
+                    </p>
+                </div>
+                <div id="tabs-purchase-4">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="OrderQuery" method="post" target="_blank">
                         <p>
                             <label>transaction_id:</label>
@@ -490,7 +527,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_2" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-4">
+                <div id="tabs-purchase-5">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="CloseOrder" method="post" target="_blank">
                         <p>
                             <label>out_trade_no:</label>
@@ -506,7 +543,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_3" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-5">
+                <div id="tabs-purchase-6">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="Refund" method="post" target="_blank">
                         <p>
                             <label>out_refund_no:</label>
@@ -546,7 +583,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_4" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-6">
+                <div id="tabs-purchase-7">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="RefundQuery" method="post" target="_blank">
                         <p>
                             <label>refund_id:</label>
@@ -574,7 +611,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_5" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-7">
+                <div id="tabs-purchase-8">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="DownloadBill" method="post" target="_blank">
                         <p>
                             <label>bill_date:</label>
@@ -598,7 +635,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_6" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-8">
+                <div id="tabs-purchase-9">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="Transfers" method="post" target="_blank">
                         <p>
                             <label>partner_trade_no:</label>
@@ -638,7 +675,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-9">
+                <div id="tabs-purchase-10">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="GetTransferInfo" method="post" target="_blank">
                         <p>
                             <label>partner_trade_no:</label>
@@ -654,7 +691,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-10">
+                <div id="tabs-purchase-11">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="GetPublicKey" method="post" target="_blank">
                         <p>
                             <label>&nbsp;</label>
@@ -666,7 +703,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-11">
+                <div id="tabs-purchase-12">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="PayBank" method="post" target="_blank">
                         <p>
                             <label>partner_trade_no:</label>
@@ -702,7 +739,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-12">
+                <div id="tabs-purchase-13">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="QueryBank" method="post" target="_blank">
                         <p>
                             <label>partner_trade_no:</label>
@@ -718,7 +755,7 @@
                         <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3" target="_blank">* 查看接口 请求参数、响应参数</a>
                     </p>
                 </div>
-                <div id="tabs-purchase-13">
+                <div id="tabs-purchase-14">
                     <form class="api-form" asp-controller="WeChatPay" asp-action="DownloadFundFlow" method="post" target="_blank">
                         <p>
                             <label>bill_date:</label>
@@ -1650,7 +1687,6 @@
     </div>
 </div>
 
-</div>
 @section Scripts {
     <script src="~/demo.js" asp-append-version="true"></script>
 }

+ 2 - 2
samples/WebApplicationSample/WebApplicationSample.csproj

@@ -3,7 +3,7 @@
   <PropertyGroup>
     <TargetFramework>netcoreapp2.0</TargetFramework>
     <UserSecretsId>a59ca38e-9b52-44fe-b3d2-8cb5a1641623</UserSecretsId>
-    <Version>1.2.0</Version>
+    <Version>1.2.1</Version>
     <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
   </PropertyGroup>
 
@@ -16,7 +16,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\src\Essensoft.AspNetCore.Payment\Essensoft.AspNetCore.Payment.csproj" />
+    <ProjectReference Include="..\..\src\Essensoft.AspNetCore.Payment.All\Essensoft.AspNetCore.Payment.All.csproj" />
   </ItemGroup>
 
 </Project>

+ 4 - 4
src/Essensoft.AspNetCore.Payment.Alipay/Essensoft.AspNetCore.Payment.Alipay.csproj

@@ -6,11 +6,11 @@
     <Authors>Roc</Authors>
     <Company>Essensoft</Company>
     <Product>Payment</Product>
-    <Version>1.2.0</Version>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <Version>1.2.1</Version>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
     <Copyright>© Essensoft 2018</Copyright>
-    <PackageProjectUrl></PackageProjectUrl>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
     <RepositoryType>git</RepositoryType>
     <RepositoryUrl>https://github.com/Essensoft/Payment</RepositoryUrl>

+ 4 - 3
src/Essensoft.AspNetCore.Payment/Essensoft.AspNetCore.Payment.csproj → src/Essensoft.AspNetCore.Payment.All/Essensoft.AspNetCore.Payment.All.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <Version>1.2.0</Version>
+    <Version>1.2.1</Version>
     <Authors>Roc</Authors>
     <Company>Essensoft</Company>
     <Product>Payment</Product>
@@ -11,8 +11,9 @@
     <RepositoryType>git</RepositoryType>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
     <Description>ASP.NET Core Payment</Description>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
   </PropertyGroup>
 
   <ItemGroup>

+ 4 - 4
src/Essensoft.AspNetCore.Payment.JdPay/Essensoft.AspNetCore.Payment.JdPay.csproj

@@ -5,12 +5,12 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.2.0</Version>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <Version>1.2.1</Version>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
     <Description>ASP.NET Core Payment for JdPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
-    <PackageProjectUrl></PackageProjectUrl>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
     <RepositoryUrl>https://github.com/Essensoft/Payment</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>

+ 4 - 4
src/Essensoft.AspNetCore.Payment.QPay/Essensoft.AspNetCore.Payment.QPay.csproj

@@ -5,12 +5,12 @@
     <Authors>Roc</Authors>
     <Company>Essensoft</Company>
     <Product>Payment</Product>
-    <Version>1.2.0</Version>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <Version>1.2.1</Version>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
     <Description>ASP.NET Core Payment for QPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
-    <PackageProjectUrl></PackageProjectUrl>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
     <RepositoryUrl>https://github.com/Essensoft/Payment</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>

+ 0 - 14
src/Essensoft.AspNetCore.Payment.QPay/IQPayCertificateClient.cs

@@ -1,14 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Essensoft.AspNetCore.Payment.QPay
-{
-    public interface IQPayCertificateClient
-    {
-        /// <summary>
-        /// 执行QPay API请求。
-        /// </summary>
-        /// <param name="request">具体的QPay API请求</param>
-        /// <returns>领域对象</returns>
-        Task<T> ExecuteAsync<T>(IQPayCertificateRequest<T> request) where T : QPayResponse;
-    }
-}

+ 0 - 100
src/Essensoft.AspNetCore.Payment.QPay/QPayCertificateClient.cs

@@ -1,100 +0,0 @@
-using Essensoft.AspNetCore.Payment.QPay.Parser;
-using Essensoft.AspNetCore.Payment.QPay.Utility;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using System;
-using System.Net.Http;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading.Tasks;
-
-namespace Essensoft.AspNetCore.Payment.QPay
-{
-    public class QPayCertificateClient : IQPayCertificateClient
-    {
-        private const string APPID = "appid";
-        private const string MCHID = "mch_id";
-        private const string NONCE_STR = "nonce_str";
-        private const string SIGN = "sign";
-
-        public QPayOptions Options { get; set; }
-
-        public virtual ILogger<QPayCertificateClient> Logger { get; set; }
-
-        protected internal HttpClientEx Client { get; set; }
-
-        public QPayCertificateClient(
-            IOptions<QPayOptions> optionsAccessor,
-            ILogger<QPayCertificateClient> logger)
-        {
-            Options = optionsAccessor?.Value ?? new QPayOptions();
-            Logger = logger;
-
-            if (string.IsNullOrEmpty(Options.MchId))
-            {
-                throw new ArgumentNullException(nameof(Options.MchId));
-            }
-
-            if (string.IsNullOrEmpty(Options.Key))
-            {
-                throw new ArgumentNullException(nameof(Options.Key));
-            }
-
-            if (string.IsNullOrEmpty(Options.Certificate))
-            {
-                throw new ArgumentNullException(nameof(Options.Certificate));
-            }
-
-            var clientHandler = new HttpClientHandler();
-            var certificate = Convert.FromBase64String(Options.Certificate);
-            clientHandler.ClientCertificates.Add(new X509Certificate2(certificate, Options.MchId, X509KeyStorageFlags.MachineKeySet));
-            Client = new HttpClientEx(clientHandler);
-        }
-
-        public void SetTimeout(int timeout)
-        {
-            Client.Timeout = new TimeSpan(0, 0, 0, timeout);
-        }
-
-        public async Task<T> ExecuteAsync<T>(IQPayCertificateRequest<T> request) where T : QPayResponse
-        {
-            // 字典排序
-            var sortedTxtParams = new QPayDictionary(request.GetParameters())
-            {
-                { APPID, Options.AppId },
-                { MCHID, Options.MchId },
-                { NONCE_STR, Guid.NewGuid().ToString("N") }
-            };
-
-            sortedTxtParams.Add(SIGN, QPaySignature.SignWithKey(sortedTxtParams, Options.Key));
-            var content = HttpClientEx.BuildContent(sortedTxtParams);
-            Logger.LogInformation(0, "Request Content:{content}", content);
-
-            var rspContent = await Client.DoPostAsync(request.GetRequestUrl(), content);
-            Logger.LogInformation(1, "Response Content:{content}", rspContent);
-
-            var parser = new QPayXmlParser<T>();
-            var rsp = parser.Parse(rspContent);
-            CheckResponseSign(rsp);
-            return rsp;
-        }
-
-        private void CheckResponseSign(QPayResponse response)
-        {
-            if (string.IsNullOrEmpty(response.Body))
-            {
-                throw new Exception("sign check fail: Body is Empty!");
-            }
-
-            var sign = response?.Sign;
-            if (!response.IsError && !string.IsNullOrEmpty(sign))
-            {
-                var cal_sign = QPaySignature.SignWithKey(response.Parameters, Options.Key);
-                if (cal_sign != sign)
-                {
-                    throw new Exception("sign check fail: check Sign and Data Fail!");
-                }
-            }
-        }
-
-    }
-}

+ 40 - 0
src/Essensoft.AspNetCore.Payment.QPay/QPayClient.cs

@@ -3,6 +3,8 @@ using Essensoft.AspNetCore.Payment.QPay.Utility;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
 using System;
+using System.Net.Http;
+using System.Security.Cryptography.X509Certificates;
 using System.Threading.Tasks;
 
 namespace Essensoft.AspNetCore.Payment.QPay
@@ -20,6 +22,8 @@ namespace Essensoft.AspNetCore.Payment.QPay
 
         protected internal HttpClientEx Client { get; set; }
 
+        protected internal HttpClientEx CertificateClient { get; set; }
+
         public QPayClient(
             IOptions<QPayOptions> optionsAccessor,
             ILogger<QPayClient> logger)
@@ -37,11 +41,24 @@ namespace Essensoft.AspNetCore.Payment.QPay
             {
                 throw new ArgumentNullException(nameof(Options.Key));
             }
+
+            if (!string.IsNullOrEmpty(Options.Certificate))
+            {
+                var clientHandler = new HttpClientHandler();
+                var certificate = Convert.FromBase64String(Options.Certificate);
+                clientHandler.ClientCertificates.Add(new X509Certificate2(certificate, Options.MchId, X509KeyStorageFlags.MachineKeySet));
+                CertificateClient = new HttpClientEx(clientHandler);
+            }
         }
 
         public void SetTimeout(int timeout)
         {
             Client.Timeout = new TimeSpan(0, 0, 0, timeout);
+
+            if (CertificateClient != null)
+            {
+                CertificateClient.Timeout = new TimeSpan(0, 0, 0, timeout);
+            }
         }
 
         public async Task<T> ExecuteAsync<T>(IQPayRequest<T> request) where T : QPayResponse
@@ -68,6 +85,29 @@ namespace Essensoft.AspNetCore.Payment.QPay
             return rsp;
         }
 
+        public async Task<T> ExecuteAsync<T>(IQPayCertificateRequest<T> request) where T : QPayResponse
+        {
+            // 字典排序
+            var sortedTxtParams = new QPayDictionary(request.GetParameters())
+            {
+                { APPID, Options.AppId },
+                { MCHID, Options.MchId },
+                { NONCE_STR, Guid.NewGuid().ToString("N") }
+            };
+
+            sortedTxtParams.Add(SIGN, QPaySignature.SignWithKey(sortedTxtParams, Options.Key));
+            var content = HttpClientEx.BuildContent(sortedTxtParams);
+            Logger.LogInformation(0, "Request Content:{content}", content);
+
+            var rspContent = await CertificateClient.DoPostAsync(request.GetRequestUrl(), content);
+            Logger.LogInformation(1, "Response Content:{content}", rspContent);
+
+            var parser = new QPayXmlParser<T>();
+            var rsp = parser.Parse(rspContent);
+            CheckResponseSign(rsp);
+            return rsp;
+        }
+
         private void CheckResponseSign(QPayResponse response)
         {
             if (string.IsNullOrEmpty(response.Body))

+ 0 - 1
src/Essensoft.AspNetCore.Payment.QPay/ServiceCollectionExtensions.cs

@@ -16,7 +16,6 @@ namespace Microsoft.Extensions.DependencyInjection
             Action<QPayOptions> setupAction)
         {
             services.AddSingleton<QPayClient>();
-            services.AddSingleton<QPayCertificateClient>();
             services.AddSingleton<QPayNotifyClient>();
             if (setupAction != null)
             {

+ 4 - 4
src/Essensoft.AspNetCore.Payment.Security/Essensoft.AspNetCore.Payment.Security.csproj

@@ -5,12 +5,12 @@
     <Product>Payment</Product>
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
-    <Version>1.2.0</Version>
+    <Version>1.2.1</Version>
     <Description>ASP.NET Core Payment for Security.</Description>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
     <Copyright>© Essensoft 2018</Copyright>
-    <PackageProjectUrl></PackageProjectUrl>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
     <RepositoryUrl>https://github.com/Essensoft/Payment</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>

+ 4 - 3
src/Essensoft.AspNetCore.Payment.UnionPay/Essensoft.AspNetCore.Payment.UnionPay.csproj

@@ -2,18 +2,19 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <Version>1.2.0</Version>
+    <Version>1.2.1</Version>
     <Authors>Roc</Authors>
     <Company>Essensoft</Company>
     <Product>Payment</Product>
     <Copyright>© Essensoft 2018</Copyright>
     <RepositoryUrl>https://github.com/Essensoft/Payment</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
     <Description>ASP.NET Core Payment for UnionPay.</Description>
     <PackageId>Essensoft.AspNetCore.Payment.UnionPay</PackageId>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
   </PropertyGroup>
 
   <ItemGroup>

+ 4 - 4
src/Essensoft.AspNetCore.Payment.WeChatPay/Essensoft.AspNetCore.Payment.WeChatPay.csproj

@@ -7,12 +7,12 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.2.0</Version>
+    <Version>1.2.1</Version>
     <Description>ASP.NET Core Payment for WeChatPay.</Description>
-    <AssemblyVersion>1.2.0.0</AssemblyVersion>
-    <FileVersion>1.2.0.0</FileVersion>
+    <AssemblyVersion>1.2.1.0</AssemblyVersion>
+    <FileVersion>1.2.1.0</FileVersion>
     <Copyright>© Essensoft 2018</Copyright>
-    <PackageProjectUrl></PackageProjectUrl>
+    <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
     <RepositoryUrl>https://github.com/Essensoft/Payment</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>

+ 0 - 14
src/Essensoft.AspNetCore.Payment.WeChatPay/IWeChatPayCertificateClient.cs

@@ -1,14 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Essensoft.AspNetCore.Payment.WeChatPay
-{
-    public interface IWeChatPayCertificateClient
-    {
-        /// <summary>
-        /// 执行WeChatPay API请求。
-        /// </summary>
-        /// <param name="request">具体的WeChatPay API请求</param>
-        /// <returns>领域对象</returns>
-        Task<T> ExecuteAsync<T>(IWeChatPayCertificateRequest<T> request) where T : WeChatPayResponse;
-    }
-}

+ 0 - 1
src/Essensoft.AspNetCore.Payment.WeChatPay/ServiceCollectionExtensions.cs

@@ -16,7 +16,6 @@ namespace Microsoft.Extensions.DependencyInjection
             Action<WeChatPayOptions> setupAction)
         {
             services.AddSingleton<WeChatPayClient>();
-            services.AddSingleton<WeChatPayCertificateClient>();
             services.AddSingleton<WeChatPayNotifyClient>();
             if (setupAction != null)
             {

+ 0 - 174
src/Essensoft.AspNetCore.Payment.WeChatPay/WeChatPayCertificateClient.cs

@@ -1,174 +0,0 @@
-using Essensoft.AspNetCore.Payment.WeChatPay.Parser;
-using Essensoft.AspNetCore.Payment.WeChatPay.Request;
-using Essensoft.AspNetCore.Payment.WeChatPay.Utility;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Org.BouncyCastle.Crypto;
-using System;
-using System.Net.Http;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading.Tasks;
-
-namespace Essensoft.AspNetCore.Payment.WeChatPay
-{
-    public class WeChatPayCertificateClient : IWeChatPayCertificateClient
-    {
-        private const string APPID = "appid";
-        private const string MCH_ID = "mch_id";
-        private const string MCH_APPID = "mch_appid";
-        private const string MCHID = "mchid";
-        private const string SIGN_TYPE = "sign_type";
-        private const string NONCE_STR = "nonce_str";
-        private const string SIGN = "sign";
-        private const string ENC_BANK_NO = "enc_bank_no";
-        private const string ENC_TRUE_NAME = "enc_true_name";
-
-        private ICipherParameters RsaPublicParameters;
-
-        public WeChatPayOptions Options { get; set; }
-
-        public virtual ILogger<WeChatPayCertificateClient> Logger { get; set; }
-
-        protected internal HttpClientEx Client { get; set; }
-
-        public WeChatPayCertificateClient(
-            IOptions<WeChatPayOptions> optionsAccessor,
-            ILogger<WeChatPayCertificateClient> logger)
-        {
-            Options = optionsAccessor?.Value ?? new WeChatPayOptions();
-            Logger = logger;
-
-            if (string.IsNullOrEmpty(Options.AppId))
-            {
-                throw new ArgumentNullException(nameof(Options.AppId));
-            }
-
-            if (string.IsNullOrEmpty(Options.MchId))
-            {
-                throw new ArgumentNullException(nameof(Options.MchId));
-            }
-
-            if (string.IsNullOrEmpty(Options.Key))
-            {
-                throw new ArgumentNullException(nameof(Options.Key));
-            }
-
-            if (string.IsNullOrEmpty(Options.Certificate))
-            {
-                throw new ArgumentNullException(nameof(Options.Certificate));
-            }
-
-            var clientHandler = new HttpClientHandler();
-            var certificate = Convert.FromBase64String(Options.Certificate);
-            clientHandler.ClientCertificates.Add(new X509Certificate2(certificate, Options.MchId, X509KeyStorageFlags.MachineKeySet));
-            Client = new HttpClientEx(clientHandler);
-
-            if (!string.IsNullOrEmpty(Options.RsaPublicKey))
-            {
-                RsaPublicParameters = WeChatPaySignature.GetPublicKeyParameters(Options.RsaPublicKey);
-            }
-        }
-
-        public void SetTimeout(int timeout)
-        {
-            Client.Timeout = new TimeSpan(0, 0, 0, timeout);
-        }
-
-        public async Task<T> ExecuteAsync<T>(IWeChatPayCertificateRequest<T> request) where T : WeChatPayResponse
-        {
-            var useMD5 = true;
-            var excludeSignType = true;
-
-            // 字典排序
-            var sortedTxtParams = new WeChatPayDictionary(request.GetParameters());
-            if (request is WeChatPayTransfersRequest)
-            {
-                sortedTxtParams.Add(MCH_APPID, Options.AppId);
-                sortedTxtParams.Add(MCHID, Options.MchId);
-            }
-            else if (request is WeChatPayGetPublicKeyRequest)
-            {
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-                sortedTxtParams.Add(SIGN_TYPE, "MD5");
-                excludeSignType = false;
-            }
-            else if (request is WeChatPayPayBankRequest)
-            {
-                if (RsaPublicParameters == null)
-                {
-                    throw new ArgumentNullException(nameof(Options.RsaPublicKey));
-                }
-
-                var no = WeChatPaySignature.Encrypt(sortedTxtParams.GetValue(ENC_BANK_NO), RsaPublicParameters);
-                sortedTxtParams.SetValue(ENC_BANK_NO, no);
-
-                var name = WeChatPaySignature.Encrypt(sortedTxtParams.GetValue(ENC_TRUE_NAME), RsaPublicParameters);
-                sortedTxtParams.SetValue(ENC_TRUE_NAME, name);
-
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-                sortedTxtParams.Add(SIGN_TYPE, "MD5");
-            }
-            else if (request is WeChatPayQueryBankRequest)
-            {
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-                sortedTxtParams.Add(SIGN_TYPE, "MD5");
-            }
-            else if (request is WeChatPayGetTransferInfoRequest)
-            {
-                sortedTxtParams.Add(APPID, Options.AppId);
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-                sortedTxtParams.Add(SIGN_TYPE, "MD5");
-            }
-            else if (request is WeChatPayDownloadFundFlowRequest)
-            {
-                sortedTxtParams.Add(APPID, Options.AppId);
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-                sortedTxtParams.Add(SIGN_TYPE, "HMAC-SHA256");
-                useMD5 = false;
-                excludeSignType = false;
-            }
-            else if(request is WeChatPayRefundRequest)
-            {
-                sortedTxtParams.Add(APPID, Options.AppId);
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-            }
-            else // 其他接口
-            {
-                sortedTxtParams.Add(APPID, Options.AppId);
-                sortedTxtParams.Add(MCH_ID, Options.MchId);
-            }
-
-            sortedTxtParams.Add(NONCE_STR, Guid.NewGuid().ToString("N"));
-            sortedTxtParams.Add(SIGN, WeChatPaySignature.SignWithKey(sortedTxtParams, Options.Key, useMD5, excludeSignType));
-
-            var content = HttpClientEx.BuildContent(sortedTxtParams);
-            Logger.LogInformation(0, "Request Content:{content}", content);
-
-            var rspContent = await Client.DoPostAsync(request.GetRequestUrl(), content);
-            Logger.LogInformation(1, "Response Content:{content}", rspContent);
-
-            var parser = new WeChatPayXmlParser<T>();
-            var rsp = parser.Parse(rspContent);
-            CheckResponseSign(rsp, useMD5, excludeSignType);
-            return rsp;
-        }
-
-        private void CheckResponseSign(WeChatPayResponse response, bool useMD5, bool excludeSignType)
-        {
-            if (string.IsNullOrEmpty(response.Body))
-            {
-                throw new Exception("sign check fail: Body is Empty!");
-            }
-
-            var sign = response?.Sign;
-            if (!response.IsError && !string.IsNullOrEmpty(sign))
-            {
-                var cal_sign = WeChatPaySignature.SignWithKey(response.Parameters, Options.Key, useMD5, excludeSignType);
-                if (cal_sign != sign)
-                {
-                    throw new Exception("sign check fail: check Sign and Data Fail!");
-                }
-            }
-        }
-    }
-}

+ 115 - 2
src/Essensoft.AspNetCore.Payment.WeChatPay/WeChatPayClient.cs

@@ -1,8 +1,12 @@
 using Essensoft.AspNetCore.Payment.WeChatPay.Parser;
+using Essensoft.AspNetCore.Payment.WeChatPay.Request;
 using Essensoft.AspNetCore.Payment.WeChatPay.Utility;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
+using Org.BouncyCastle.Crypto;
 using System;
+using System.Net.Http;
+using System.Security.Cryptography.X509Certificates;
 using System.Threading.Tasks;
 
 namespace Essensoft.AspNetCore.Payment.WeChatPay
@@ -17,12 +21,19 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay
         private const string NONCE_STR = "nonce_str";
         private const string SIGN = "sign";
 
+        private const string ENC_BANK_NO = "enc_bank_no";
+        private const string ENC_TRUE_NAME = "enc_true_name";
+
+        private ICipherParameters RsaPublicParameters;
+
         public WeChatPayOptions Options { get; set; }
 
         public virtual ILogger<WeChatPayClient> Logger { get; set; }
 
         protected internal HttpClientEx Client { get; set; }
 
+        protected internal HttpClientEx CertificateClient { get; set; }
+
         public WeChatPayClient(
             IOptions<WeChatPayOptions> optionsAccessor,
             ILogger<WeChatPayClient> logger)
@@ -45,11 +56,29 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay
             {
                 throw new ArgumentNullException(nameof(Options.Key));
             }
+
+            if (!string.IsNullOrEmpty(Options.Certificate))
+            {
+                var clientHandler = new HttpClientHandler();
+                var certificate = Convert.FromBase64String(Options.Certificate);
+                clientHandler.ClientCertificates.Add(new X509Certificate2(certificate, Options.MchId, X509KeyStorageFlags.MachineKeySet));
+                CertificateClient = new HttpClientEx(clientHandler);
+            }
+
+            if (!string.IsNullOrEmpty(Options.RsaPublicKey))
+            {
+                RsaPublicParameters = WeChatPaySignature.GetPublicKeyParameters(Options.RsaPublicKey);
+            }
         }
 
         public void SetTimeout(int timeout)
         {
             Client.Timeout = new TimeSpan(0, 0, 0, timeout);
+
+            if (CertificateClient != null)
+            {
+                CertificateClient.Timeout = new TimeSpan(0, 0, 0, timeout);
+            }
         }
 
         public async Task<T> ExecuteAsync<T>(IWeChatPayRequest<T> request) where T : WeChatPayResponse
@@ -75,7 +104,91 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay
             return rsp;
         }
 
-        private void CheckResponseSign(WeChatPayResponse response)
+        public async Task<T> ExecuteAsync<T>(IWeChatPayCertificateRequest<T> request) where T : WeChatPayResponse
+        {
+            var useMD5 = true;
+            var excludeSignType = true;
+
+            if (CertificateClient == null)
+            {
+                throw new ArgumentNullException(nameof(Options.Certificate));
+            }
+
+            // 字典排序
+            var sortedTxtParams = new WeChatPayDictionary(request.GetParameters());
+            if (request is WeChatPayTransfersRequest)
+            {
+                sortedTxtParams.Add(MCH_APPID, Options.AppId);
+                sortedTxtParams.Add(MCHID, Options.MchId);
+            }
+            else if (request is WeChatPayGetPublicKeyRequest)
+            {
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+                sortedTxtParams.Add(SIGN_TYPE, "MD5");
+                excludeSignType = false;
+            }
+            else if (request is WeChatPayPayBankRequest)
+            {
+                if (RsaPublicParameters == null)
+                {
+                    throw new ArgumentNullException(nameof(Options.RsaPublicKey));
+                }
+
+                var no = WeChatPaySignature.Encrypt(sortedTxtParams.GetValue(ENC_BANK_NO), RsaPublicParameters);
+                sortedTxtParams.SetValue(ENC_BANK_NO, no);
+
+                var name = WeChatPaySignature.Encrypt(sortedTxtParams.GetValue(ENC_TRUE_NAME), RsaPublicParameters);
+                sortedTxtParams.SetValue(ENC_TRUE_NAME, name);
+
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+                sortedTxtParams.Add(SIGN_TYPE, "MD5");
+            }
+            else if (request is WeChatPayQueryBankRequest)
+            {
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+                sortedTxtParams.Add(SIGN_TYPE, "MD5");
+            }
+            else if (request is WeChatPayGetTransferInfoRequest)
+            {
+                sortedTxtParams.Add(APPID, Options.AppId);
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+                sortedTxtParams.Add(SIGN_TYPE, "MD5");
+            }
+            else if (request is WeChatPayDownloadFundFlowRequest)
+            {
+                sortedTxtParams.Add(APPID, Options.AppId);
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+                sortedTxtParams.Add(SIGN_TYPE, "HMAC-SHA256");
+                useMD5 = false;
+                excludeSignType = false;
+            }
+            else if (request is WeChatPayRefundRequest)
+            {
+                sortedTxtParams.Add(APPID, Options.AppId);
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+            }
+            else // 其他接口
+            {
+                sortedTxtParams.Add(APPID, Options.AppId);
+                sortedTxtParams.Add(MCH_ID, Options.MchId);
+            }
+
+            sortedTxtParams.Add(NONCE_STR, Guid.NewGuid().ToString("N"));
+            sortedTxtParams.Add(SIGN, WeChatPaySignature.SignWithKey(sortedTxtParams, Options.Key, useMD5, excludeSignType));
+
+            var content = HttpClientEx.BuildContent(sortedTxtParams);
+            Logger.LogInformation(0, "Request Content:{content}", content);
+
+            var rspContent = await CertificateClient.DoPostAsync(request.GetRequestUrl(), content);
+            Logger.LogInformation(1, "Response Content:{content}", rspContent);
+
+            var parser = new WeChatPayXmlParser<T>();
+            var rsp = parser.Parse(rspContent);
+            CheckResponseSign(rsp, useMD5, excludeSignType);
+            return rsp;
+        }
+
+        private void CheckResponseSign(WeChatPayResponse response, bool useMD5 = true, bool excludeSignType = true)
         {
             if (string.IsNullOrEmpty(response.Body))
             {
@@ -85,7 +198,7 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay
             var sign = response?.Sign;
             if (!response.IsError && !string.IsNullOrEmpty(sign))
             {
-                var cal_sign = WeChatPaySignature.SignWithKey(response.Parameters, Options.Key);
+                var cal_sign = WeChatPaySignature.SignWithKey(response.Parameters, Options.Key, useMD5, excludeSignType);
                 if (cal_sign != sign)
                 {
                     throw new Exception("sign check fail: check Sign and Data Fail!");

+ 1 - 2
src/Essensoft.AspNetCore.Payment.WeChatPay/WeChatPayResponse.cs

@@ -4,7 +4,6 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay
 {
     public abstract class WeChatPayResponse : WeChatPayObject
     {
-
         /// <summary>
         /// 返回状态码
         /// 此字段是通信标识,非交易标识,
@@ -30,7 +29,7 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay
         /// <summary>
         /// 商户号ID
         /// </summary>
-        [XmlElement("sub_appid")]
+        [XmlElement("MchId")]
         public string MchId { get; set; }
 
         /// <summary>