Forráskód Böngészése

1.5.0

1.升级项目至 NET Core 2.1 / ASP.NET Core 2.1
2.京东支付加入代付支持
Roc 7 éve
szülő
commit
e9a35f7dc3
59 módosított fájl, 1736 hozzáadás és 143 törlés
  1. 0 39
      .vscode/launch.json
  2. 0 15
      .vscode/tasks.json
  3. 2 2
      README.MD
  4. 69 0
      samples/NewWebApplicationSample/Controllers/JDPayController.cs
  5. 16 0
      samples/NewWebApplicationSample/Controllers/NotifyController.cs
  6. 4 0
      samples/NewWebApplicationSample/Helpers/HMTLHelperExtensions.cs
  7. 113 0
      samples/NewWebApplicationSample/Models/JDPayViewModel.cs
  8. 3 9
      samples/NewWebApplicationSample/NewWebApplicationSample.csproj
  9. 3 4
      samples/NewWebApplicationSample/Program.cs
  10. 13 2
      samples/NewWebApplicationSample/Startup.cs
  11. 113 0
      samples/NewWebApplicationSample/Views/JDPay/DefrayPay.cshtml
  12. 12 0
      samples/NewWebApplicationSample/Views/JDPay/Index.cshtml
  13. 45 0
      samples/NewWebApplicationSample/Views/JDPay/TradeQuery.cshtml
  14. 2 0
      src/Essensoft.AspNetCore.Payment.Alipay/AlipayNotifyClient.cs
  15. 4 4
      src/Essensoft.AspNetCore.Payment.Alipay/Essensoft.AspNetCore.Payment.Alipay.csproj
  16. 4 0
      src/Essensoft.AspNetCore.Payment.Alipay/Parser/AlipayDictionaryParser.cs
  17. 10 0
      src/Essensoft.AspNetCore.Payment.Alipay/Parser/AlipayJsonParser.cs
  18. 4 0
      src/Essensoft.AspNetCore.Payment.Alipay/Parser/AlipayXmlParser.cs
  19. 7 0
      src/Essensoft.AspNetCore.Payment.Alipay/Utility/AlipaySignature.cs
  20. 2 0
      src/Essensoft.AspNetCore.Payment.Alipay/Utility/AlipayUtility.cs
  21. 14 3
      src/Essensoft.AspNetCore.Payment.Alipay/Utility/FileItem.cs
  22. 2 0
      src/Essensoft.AspNetCore.Payment.Alipay/Utility/HttpClientEx.cs
  23. 5 4
      src/Essensoft.AspNetCore.Payment.JDPay/Essensoft.AspNetCore.Payment.JDPay.csproj
  24. 7 1
      src/Essensoft.AspNetCore.Payment.JDPay/IJDPayClient.cs
  25. 21 0
      src/Essensoft.AspNetCore.Payment.JDPay/IJDPayNPP10Request.cs
  26. 51 15
      src/Essensoft.AspNetCore.Payment.JDPay/JDPayClient.cs
  27. 48 9
      src/Essensoft.AspNetCore.Payment.JDPay/JDPayNotifyClient.cs
  28. 35 0
      src/Essensoft.AspNetCore.Payment.JDPay/JDPayOptions.cs
  29. 0 1
      src/Essensoft.AspNetCore.Payment.JDPay/Notify/JDPayAsyncNotifyResponse.cs
  30. 175 0
      src/Essensoft.AspNetCore.Payment.JDPay/Notify/JDPayDefrayPayNotifyResponse.cs
  31. 13 1
      src/Essensoft.AspNetCore.Payment.JDPay/Parser/JDPayDictionaryParser.cs
  32. 4 0
      src/Essensoft.AspNetCore.Payment.JDPay/Parser/JDPayXmlParser.cs
  33. 65 0
      src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayAccountQueryRequest.cs
  34. 203 0
      src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayDefrayPayRequest.cs
  35. 0 1
      src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayRefundRequest.cs
  36. 53 0
      src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayTradeQueryRequest.cs
  37. 73 0
      src/Essensoft.AspNetCore.Payment.JDPay/Response/JDPayAccountQueryResponse.cs
  38. 79 0
      src/Essensoft.AspNetCore.Payment.JDPay/Response/JDPayDefrayPayResponse.cs
  39. 187 0
      src/Essensoft.AspNetCore.Payment.JDPay/Response/JDPayTradeQueryResponse.cs
  40. 18 0
      src/Essensoft.AspNetCore.Payment.JDPay/Utility/Contants.cs
  41. 2 3
      src/Essensoft.AspNetCore.Payment.JDPay/Utility/HttpClientEx.cs
  42. 168 10
      src/Essensoft.AspNetCore.Payment.JDPay/Utility/JDPaySecurity.cs
  43. 14 1
      src/Essensoft.AspNetCore.Payment.JDPay/Utility/JDPayUtility.cs
  44. 4 4
      src/Essensoft.AspNetCore.Payment.LianLianPay/Essensoft.AspNetCore.Payment.LianLianPay.csproj
  45. 4 0
      src/Essensoft.AspNetCore.Payment.LianLianPay/Parser/LianLianPayDictionaryParser.cs
  46. 2 0
      src/Essensoft.AspNetCore.Payment.LianLianPay/Parser/LianLianPayJsonParser.cs
  47. 2 0
      src/Essensoft.AspNetCore.Payment.LianLianPay/Utility/LianLianPaySecurity.cs
  48. 4 4
      src/Essensoft.AspNetCore.Payment.QPay/Essensoft.AspNetCore.Payment.QPay.csproj
  49. 4 0
      src/Essensoft.AspNetCore.Payment.QPay/Parser/QPayXmlParser.cs
  50. 2 0
      src/Essensoft.AspNetCore.Payment.QPay/Utility/QPaySignature.cs
  51. 3 3
      src/Essensoft.AspNetCore.Payment.Security/Essensoft.AspNetCore.Payment.Security.csproj
  52. 4 4
      src/Essensoft.AspNetCore.Payment.UnionPay/Essensoft.AspNetCore.Payment.UnionPay.csproj
  53. 4 0
      src/Essensoft.AspNetCore.Payment.UnionPay/Parser/UnionPayDictionaryParser.cs
  54. 3 0
      src/Essensoft.AspNetCore.Payment.UnionPay/UnionPayClient.cs
  55. 6 0
      src/Essensoft.AspNetCore.Payment.UnionPay/Utility/UnionPaySignature.cs
  56. 13 0
      src/Essensoft.AspNetCore.Payment.UnionPay/Utility/UnionPayUtils.cs
  57. 4 4
      src/Essensoft.AspNetCore.Payment.WeChatPay/Essensoft.AspNetCore.Payment.WeChatPay.csproj
  58. 10 0
      src/Essensoft.AspNetCore.Payment.WeChatPay/Parser/WeChatPayXmlParser.cs
  59. 4 0
      src/Essensoft.AspNetCore.Payment.WeChatPay/Utility/WeChatPaySignature.cs

+ 0 - 39
.vscode/launch.json

@@ -1,39 +0,0 @@
-{
-    // 使用 IntelliSense 了解相关属性。 
-    // 悬停以查看现有属性的描述。
-    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
-    "version": "0.2.0",
-    "configurations": [
-        {
-            "name": "NewWebApplicationSample",
-            "type": "coreclr",
-            "request": "launch",
-            "preLaunchTask": "build",
-            "program": "${workspaceFolder}/samples/NewWebApplicationSample/bin/Debug/netcoreapp2.0/NewWebApplicationSample.dll",
-            "args": [],
-            "cwd": "${workspaceFolder}/samples/NewWebApplicationSample",
-            "stopAtEntry": false,
-            "internalConsoleOptions": "openOnSessionStart",
-            "launchBrowser": {
-                "enabled": true,
-                "args": "${auto-detect-url}",
-                "windows": {
-                    "command": "cmd.exe",
-                    "args": "/C start ${auto-detect-url}"
-                },
-                "osx": {
-                    "command": "open"
-                },
-                "linux": {
-                    "command": "xdg-open"
-                }
-            },
-            "env": {
-                "ASPNETCORE_ENVIRONMENT": "Development"
-            },
-            "sourceFileMap": {
-                "/Views": "${workspaceFolder}/Views"
-            }
-        }
-    ]
-}

+ 0 - 15
.vscode/tasks.json

@@ -1,15 +0,0 @@
-{
-    "version": "2.0.0",
-    "tasks": [
-        {
-            "label": "build",
-            "command": "dotnet",
-            "type": "process",
-            "args": [
-                "build",
-                "${workspaceFolder}/samples/NewWebApplicationSample/NewWebApplicationSample.csproj"
-            ],
-            "problemMatcher": "$msCompile"
-        }
-    ]
-}

+ 2 - 2
README.MD

@@ -2,7 +2,7 @@
 
 ## 简介
 
-Payment 是基于 .NET Core 2.0 / ASP.NET Core 2.0 开发的支付SDK集。
+Payment 是基于 .NET Core 2.1 / ASP.NET Core 2.1 开发的跨平台支付SDK集。
 简化了API调用及相关通知的处理流程。
 
 ## Package
@@ -34,7 +34,7 @@ Essensoft.AspNetCore.Payment.UnionPay       | [![NuGet](https://img.shields.io/n
 * 付款码支付、扫码支付、公众号支付、APP支付
 
 ### 京东支付
-* 网页支付、APP支付、扫一扫、付款码
+* 网页支付、APP支付、扫一扫、付款码、代付
 
 ### 连连支付
 * 快捷支付、 网银支付、认证支付、实时付款

+ 69 - 0
samples/NewWebApplicationSample/Controllers/JDPayController.cs

@@ -167,6 +167,75 @@ namespace NewWebApplicationSample.Controllers
             return View();
         }
 
+        [HttpGet]
+        public IActionResult DefrayPay()
+        {
+            return View();
+        }
+
+        [HttpPost]
+        public async Task<IActionResult> DefrayPay(JDPayDefrayPayViewModel viewModel)
+        {
+            var request = new JDPayDefrayPayRequest()
+            {
+                RequestDatetime = viewModel.RequestDatetime,
+                OutTradeNo = viewModel.OutTradeNo,
+                BizTradeNo = viewModel.BizTradeNo,
+                OutTradeDate = viewModel.OutTradeDate,
+                TradeAmount = viewModel.TradeAmount,
+                TradeCurrency = viewModel.TradeCurrency,
+                SellerInfo = viewModel.SellerInfo,
+                TradeSubject = viewModel.TradeSubject,
+                CategoryCode = viewModel.CategoryCode,
+                PayTool = viewModel.PayTool,
+                TradeSource = viewModel.TradeSource,
+                PayeeBankCode = viewModel.PayeeBankCode,
+                PayeeBankAssociatedCode = viewModel.PayeeBankAssociatedCode,
+                PayeeBankFullname = viewModel.PayeeBankFullname,
+                PayeeBankCountryCode = viewModel.PayeeBankCountryCode,
+                PayeeBankProvinceCode = viewModel.PayeeBankProvinceCode,
+                PayeeBankCityCode = viewModel.PayeeBankCityCode,
+                PayeeCardType = viewModel.PayeeCardType,
+                PayeeAccountType = viewModel.PayeeAccountType,
+                PayeeAccountNo = viewModel.PayeeAccountNo,
+                PayeeAccountName = viewModel.PayeeAccountName,
+                PayeeIdType = viewModel.PayeeIdType,
+                PayeeIdNo = viewModel.PayeeIdNo,
+                PayeeMobile = viewModel.PayeeMobile,
+                NotifyUrl = viewModel.NotifyUrl,
+                ReturnParams = viewModel.ReturnParams,
+                ExtendParams = viewModel.ExtendParams,
+                BankCardInfoType = viewModel.BankCardInfoType,
+                BankCardId = viewModel.BankCardId,
+            };
+
+            var response = await _client.ExecuteAsync(request);
+            ViewData["response"] = response.Body;
+            return View();
+        }
+
+        [HttpGet]
+        public IActionResult TradeQuery()
+        {
+            return View();
+        }
+
+        [HttpPost]
+        public async Task<IActionResult> TradeQuery(JDPayTradeQueryViewModel viewModel)
+        {
+            var request = new JDPayTradeQueryRequest()
+            {
+                RequestDatetime = viewModel.RequestDatetime,
+                OutTradeNo = viewModel.OutTradeNo,
+                TradeNo = viewModel.TradeNo,
+                TradeType = viewModel.TradeType,
+            };
+
+            var response = await _client.ExecuteAsync(request);
+            ViewData["response"] = response.Body;
+            return View();
+        }
+
         [HttpGet]  // h5 get
         [HttpPost] // pc post
         public async Task<IActionResult> Return()

+ 16 - 0
samples/NewWebApplicationSample/Controllers/NotifyController.cs

@@ -312,6 +312,22 @@ namespace NewWebApplicationSample.Controllers
                 return NoContent();
             }
         }
+
+        [Route("defraypay")]
+        [HttpPost]
+        public async Task<IActionResult> DefrayPay()
+        {
+            try
+            {
+                var notify = await _client.ExecuteAsync<JDPayDefrayPayNotifyResponse>(Request);
+                Console.WriteLine("trade_no: " + notify.TradeNo + " trade_amount :" + notify.TradeAmount);
+                return JDPayNotifyResult.Success;
+            }
+            catch
+            {
+                return NoContent();
+            }
+        }
     }
 
     #endregion

+ 4 - 0
samples/NewWebApplicationSample/Helpers/HMTLHelperExtensions.cs

@@ -10,10 +10,14 @@ namespace NewWebApplicationSample
             var actualController = (string)html.ViewContext.RouteData.Values["controller"];
 
             if (string.IsNullOrEmpty(controller))
+            {
                 controller = actualController;
+            }
 
             if (string.IsNullOrEmpty(action))
+            {
                 action = actualAction;
+            }
 
             return (controller == actualController && action == actualAction) ? activeClass : string.Empty;
         }

+ 113 - 0
samples/NewWebApplicationSample/Models/JDPayViewModel.cs

@@ -125,4 +125,117 @@ namespace NewWebApplicationSample.Models
         [Display(Name = "tradeType")]
         public string TradeType { get; set; }
     }
+
+    public class JDPayDefrayPayViewModel
+    {
+        [Required]
+        [Display(Name = "request_datetime")]
+        public string RequestDatetime { get; set; }
+
+        [Required]
+        [Display(Name = "out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        [Display(Name = "biz_trade_no")]
+        public string BizTradeNo { get; set; }
+
+        [Display(Name = "out_trade_date")]
+        public string OutTradeDate { get; set; }
+
+        [Required]
+        [Display(Name = "trade_amount")]
+        public string TradeAmount { get; set; }
+
+        [Required]
+        [Display(Name = "trade_currency")]
+        public string TradeCurrency { get; set; }
+
+        [Display(Name = "seller_info")]
+        public string SellerInfo { get; set; }
+
+        [Required]
+        [Display(Name = "trade_subject")]
+        public string TradeSubject { get; set; }
+
+        [Display(Name = "category_code")]
+        public string CategoryCode { get; set; }
+
+        [Required]
+        [Display(Name = "pay_tool")]
+        public string PayTool { get; set; }
+
+        [Display(Name = "trade_source")]
+        public string TradeSource { get; set; }
+
+        [Display(Name = "payee_bank_code")]
+        public string PayeeBankCode { get; set; }
+
+        [Display(Name = "payee_bank_associated_code")]
+        public string PayeeBankAssociatedCode { get; set; }
+
+        [Display(Name = "payee_bank_fullname")]
+        public string PayeeBankFullname { get; set; }
+
+        [Display(Name = "payee_bank_country_code")]
+        public string PayeeBankCountryCode { get; set; }
+
+        [Display(Name = "payee_bank_province_code")]
+        public string PayeeBankProvinceCode { get; set; }
+
+        [Display(Name = "payee_bank_city_code")]
+        public string PayeeBankCityCode { get; set; }
+
+        [Display(Name = "payee_card_type")]
+        public string PayeeCardType { get; set; }
+
+        [Display(Name = "payee_account_type")]
+        public string PayeeAccountType { get; set; }
+
+        [Display(Name = "payee_account_no")]
+        public string PayeeAccountNo { get; set; }
+
+        [Display(Name = "payee_account_name")]
+        public string PayeeAccountName { get; set; }
+
+        [Display(Name = "payee_id_type")]
+        public string PayeeIdType { get; set; }
+
+        [Display(Name = "payee_id_no")]
+        public string PayeeIdNo { get; set; }
+
+        [Display(Name = "payee_mobile")]
+        public string PayeeMobile { get; set; }
+
+        [Display(Name = "notify_url")]
+        public string NotifyUrl { get; set; }
+
+        [Display(Name = "return_params")]
+        public string ReturnParams { get; set; }
+
+        [Display(Name = "extend_params")]
+        public string ExtendParams { get; set; }
+
+        [Display(Name = "bank_card_info_type")]
+        public string BankCardInfoType { get; set; }
+
+        [Display(Name = "bank_card_id")]
+        public string BankCardId { get; set; }
+    }
+
+    public class JDPayTradeQueryViewModel
+    {
+        [Required]
+        [Display(Name = "request_datetime")]
+        public string RequestDatetime { get; set; }
+
+        [Display(Name = "out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        [Display(Name = "trade_no")]
+        public string TradeNo { get; set; }
+
+        [Required]
+        [Display(Name = "trade_type")]
+        public string TradeType { get; set; }
+    }
 }

+ 3 - 9
samples/NewWebApplicationSample/NewWebApplicationSample.csproj

@@ -1,18 +1,14 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp2.0</TargetFramework>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
     <UserSecretsId>a59ca38e-9b52-44fe-b3d2-8cb5a1641623</UserSecretsId>
     <Version>1.0.0</Version>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.8" />
-    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.4" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
+    <PackageReference Include="Microsoft.AspNetCore.App" />
+    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.0" />
   </ItemGroup>
 
   <ItemGroup>
@@ -24,6 +20,4 @@
     <ProjectReference Include="..\..\src\Essensoft.AspNetCore.Payment.WeChatPay\Essensoft.AspNetCore.Payment.WeChatPay.csproj" />
   </ItemGroup>
 
-  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JSONSchema="" /></VisualStudio></ProjectExtensions>
-  
 </Project>

+ 3 - 4
samples/NewWebApplicationSample/Program.cs

@@ -7,13 +7,12 @@ namespace NewWebApplicationSample
     {
         public static void Main(string[] args)
         {
-            BuildWebHost(args).Run();
+            CreateWebHostBuilder(args).Build().Run();
         }
 
-        public static IWebHost BuildWebHost(string[] args) =>
+        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
             WebHost.CreateDefaultBuilder(args)
-                .UseStartup<Startup>()
                 .UseUrls("http://*:5000")
-                .Build();
+                .UseStartup<Startup>();
     }
 }

+ 13 - 2
samples/NewWebApplicationSample/Startup.cs

@@ -6,6 +6,8 @@ using Essensoft.AspNetCore.Payment.UnionPay;
 using Essensoft.AspNetCore.Payment.WeChatPay;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
@@ -26,7 +28,14 @@ namespace NewWebApplicationSample
         // This method gets called by the runtime. Use this method to add services to the container.
         public void ConfigureServices(IServiceCollection services)
         {
-            services.AddMvc();
+            services.Configure<CookiePolicyOptions>(options =>
+            {
+                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
+                options.CheckConsentNeeded = context => true;
+                options.MinimumSameSitePolicy = SameSiteMode.None;
+            });
+
+            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 
             services.AddAlipay();
             services.AddJDPay();
@@ -53,16 +62,18 @@ namespace NewWebApplicationSample
         {
             if (env.IsDevelopment())
             {
-                app.UseBrowserLink();
                 app.UseDeveloperExceptionPage();
             }
             else
             {
                 app.UseExceptionHandler("/Home/Error");
+                app.UseHsts();
             }
 
             app.UseStaticFiles();
 
+            app.UseCookiePolicy();
+
             app.UseMvc(routes =>
             {
                 routes.MapRoute(

+ 113 - 0
samples/NewWebApplicationSample/Views/JDPay/DefrayPay.cshtml

@@ -0,0 +1,113 @@
+@model JDPayDefrayPayViewModel
+@{
+    ViewData["Title"] = "代付交易请求";
+}
+<nav aria-label="breadcrumb">
+    <ol class="breadcrumb">
+        <li class="breadcrumb-item"><a asp-controller="JDPay" asp-action="Index">京东支付</a></li>
+        <li class="breadcrumb-item active" aria-current="page">@ViewData["Title"]</li>
+    </ol>
+</nav>
+<br />
+<div class="card">
+    <div class="card-body">
+        <form asp-controller="JDPay" asp-action="DefrayPay">
+            <div asp-validation-summary="All" class="text-danger"></div>
+            <div class="form-group">
+                <label asp-for="PayeeBankCode"></label>
+                <input type="text" class="form-control" asp-for="PayeeBankCode" value="ABC" />
+            </div>
+            <div class="form-group">
+                <label asp-for="ExtendParams"></label>
+                <input type="text" class="form-control" asp-for="ExtendParams" value="{'ssss':'ssss'}" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayeeAccountType"></label>
+                <input type="text" class="form-control" asp-for="PayeeAccountType" value="P" />
+            </div>
+            <div class="form-group">
+                <label asp-for="ReturnParams"></label>
+                <input type="text" class="form-control" asp-for="ReturnParams" value="1234ssddffgghhj" />
+            </div>
+            <div class="form-group">
+                <label asp-for="TradeCurrency"></label>
+                <input type="text" class="form-control" asp-for="TradeCurrency" value="CNY" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayTool"></label>
+                <input type="text" class="form-control" asp-for="PayTool" value="TRAN" />
+            </div>
+            <div class="form-group">
+                <label asp-for="CategoryCode"></label>
+                <input type="text" class="form-control" asp-for="CategoryCode" value="20jd222" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayeeAccountNo"></label>
+                <input type="text" class="form-control" asp-for="PayeeAccountNo" value="6222600210011817312" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayeeAccountName"></label>
+                <input type="text" class="form-control" asp-for="PayeeAccountName" value="张米克" />
+            </div>
+            <div class="form-group">
+                <label asp-for="TradeSource"></label>
+                <input type="text" class="form-control" asp-for="TradeSource" value="testetst" />
+            </div>
+            <div class="form-group">
+                <label asp-for="NotifyUrl"></label>
+                <input type="text" class="form-control" asp-for="NotifyUrl" value="http://*/notify/jdpay/defraypay" />
+            </div>
+            <div class="form-group">
+                <label asp-for="BizTradeNo"></label>
+                <input type="text" class="form-control" asp-for="BizTradeNo" value="@DateTime.Now.ToString("yyyyMMddHHmmssfff")" />
+            </div>
+            <div class="form-group">
+                <label asp-for="OutTradeNo"></label>
+                <input type="text" class="form-control" asp-for="OutTradeNo" value="@DateTime.Now.ToString("yyyyMMddHHmmssfff")" />
+            </div>
+            <div class="form-group">
+                <label asp-for="SellerInfo"></label>
+                <input type="text" class="form-control" asp-for="SellerInfo" value="{'customer_code':'360080002191800017','customer_type':'CUSTOMER_NO'}" />
+            </div>
+            <div class="form-group">
+                <label asp-for="OutTradeDate"></label>
+                <input type="text" class="form-control" asp-for="OutTradeDate" value="@DateTime.Now.ToString("yyyyMMddHHmmss")" />
+            </div>
+            <div class="form-group">
+                <label asp-for="TradeAmount"></label>
+                <input type="text" class="form-control" asp-for="TradeAmount" value="1" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayeeBankFullname"></label>
+                <input type="text" class="form-control" asp-for="PayeeBankFullname" value="农业银行" />
+            </div>
+            <div class="form-group">
+                <label asp-for="RequestDatetime"></label>
+                <input type="text" class="form-control" asp-for="RequestDatetime" value="@DateTime.Now.ToString("yyyyMMddHHmmss")" />
+            </div>
+            <div class="form-group">
+                <label asp-for="TradeSubject"></label>
+                <input type="text" class="form-control" asp-for="TradeSubject" value="test代付" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayeeCardType"></label>
+                <input type="text" class="form-control" asp-for="PayeeCardType" value="DE" />
+            </div>
+            <div class="form-group">
+                <label asp-for="PayeeMobile"></label>
+                <input type="text" class="form-control" asp-for="PayeeMobile" value="1333333333" />
+            </div>
+            <button type="submit" class="btn btn-primary">提交请求</button>
+        </form>
+        <hr />
+        <form class="form-horizontal">
+            <div class="form-group">
+                <label>Response:</label>
+                <textarea class="form-control" rows="10">@ViewData["response"]</textarea>
+            </div>
+        </form>
+    </div>
+</div>
+@section Scripts {
+    @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

+ 12 - 0
samples/NewWebApplicationSample/Views/JDPay/Index.cshtml

@@ -54,5 +54,17 @@
             <td><a href="https://payapi.jd.com/interface/queryRefund.html" target="_blank">https://paygate.jd.com/service/queryRefund</a></td>
             <td><a asp-controller="JDPay" asp-action="QueryRefund">立即测试</a></td>
         </tr>
+        <tr>
+            <th scope="row">7</th>
+            <td>代付交易</td>
+            <td></td>
+            <td><a asp-controller="JDPay" asp-action="DefrayPay">立即测试</a></td>
+        </tr>
+        <tr>
+            <th scope="row">8</th>
+            <td>代付交易查询</td>
+            <td></td>
+            <td><a asp-controller="JDPay" asp-action="TradeQuery">立即测试</a></td>
+        </tr>
     </tbody>
 </table>

+ 45 - 0
samples/NewWebApplicationSample/Views/JDPay/TradeQuery.cshtml

@@ -0,0 +1,45 @@
+@model JDPayTradeQueryViewModel
+@{
+    ViewData["Title"] = "代付交易查询";
+}
+<nav aria-label="breadcrumb">
+    <ol class="breadcrumb">
+        <li class="breadcrumb-item"><a asp-controller="JDPay" asp-action="Index">京东支付</a></li>
+        <li class="breadcrumb-item active" aria-current="page">@ViewData["Title"]</li>
+    </ol>
+</nav>
+<br />
+<div class="card">
+    <div class="card-body">
+        <form asp-controller="JDPay" asp-action="TradeQuery">
+            <div asp-validation-summary="All" class="text-danger"></div>
+            <div class="form-group">
+                <label asp-for="RequestDatetime"></label>
+                <input type="text" class="form-control" asp-for="RequestDatetime" value="@DateTime.Now.ToString("yyyyMMddHHmmss")" />
+            </div>
+            <div class="form-group">
+                <label asp-for="OutTradeNo"></label>
+                <input type="text" class="form-control" asp-for="OutTradeNo" />
+            </div>
+            <div class="form-group">
+                <label asp-for="TradeNo"></label>
+                <input type="text" class="form-control" asp-for="TradeNo" />
+            </div>
+            <div class="form-group">
+                <label asp-for="TradeType"></label>
+                <input type="text" class="form-control" asp-for="TradeType" value="T_AGD" />
+            </div>
+            <button type="submit" class="btn btn-primary">提交请求</button>
+        </form>
+        <hr />
+        <form class="form-horizontal">
+            <div class="form-group">
+                <label>Response:</label>
+                <textarea class="form-control" rows="10">@ViewData["response"]</textarea>
+            </div>
+        </form>
+    </div>
+</div>
+@section Scripts {
+    @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

+ 2 - 0
src/Essensoft.AspNetCore.Payment.Alipay/AlipayNotifyClient.cs

@@ -112,7 +112,9 @@ namespace Essensoft.AspNetCore.Payment.Alipay
             foreach (var iter in parameters)
             {
                 if (!string.IsNullOrEmpty(iter.Value) && iter.Key != "sign" && iter.Key != "sign_type")
+                {
                     sb.Append(iter.Key).Append("=").Append(iter.Value).Append("&");
+                }
             }
             return sb.Remove(sb.Length - 1, 1).ToString();
         }

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

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for Alipay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" />
     <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
   </ItemGroup>
 

+ 4 - 0
src/Essensoft.AspNetCore.Payment.Alipay/Parser/AlipayDictionaryParser.cs

@@ -9,7 +9,9 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Parser
         public T Parse(IDictionary parameters)
         {
             if (parameters == null || parameters.Count == 0)
+            {
                 throw new ArgumentNullException(nameof(parameters));
+            }
 
             T rsp = null;
 
@@ -21,7 +23,9 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             return rsp;
         }

+ 10 - 0
src/Essensoft.AspNetCore.Payment.Alipay/Parser/AlipayJsonParser.cs

@@ -33,17 +33,23 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Parser
                     {
                         rsp = JsonConvert.DeserializeObject<T>(json[key].ToString());
                         if (rsp != null)
+                        {
                             break;
+                        }
                     }
                 }
             }
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
+            {
                 rsp.Body = body;
+            }
 
             return rsp;
         }
@@ -81,9 +87,13 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Parser
 
             string result = null;
             if (indexOfRootNode > 0)
+            {
                 result = ParseSignSourceData(body, rootNode, indexOfRootNode);
+            }
             else if (indexOfErrorRoot > 0)
+            {
                 result = ParseSignSourceData(body, errorRootNode, indexOfErrorRoot);
+            }
 
             return result;
         }

+ 4 - 0
src/Essensoft.AspNetCore.Payment.Alipay/Parser/AlipayXmlParser.cs

@@ -51,10 +51,14 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Parser
             { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
+            {
                 rsp.Body = body;
+            }
 
             return rsp;
         }

+ 7 - 0
src/Essensoft.AspNetCore.Payment.Alipay/Utility/AlipaySignature.cs

@@ -12,14 +12,18 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Utility
         public static string GetSignContent(IDictionary<string, string> para)
         {
             if (para == null || para.Count == 0)
+            {
                 return string.Empty;
+            }
 
             var sortPara = new SortedDictionary<string, string>(para);
             var sb = new StringBuilder();
             foreach (var iter in sortPara)
             {
                 if (!string.IsNullOrEmpty(iter.Value))
+                {
                     sb.Append(iter.Key).Append("=").Append(iter.Value).Append("&");
+                }
             }
 
             return sb.Remove(sb.Length - 1, 1).ToString();
@@ -49,7 +53,10 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Utility
         {
             var iv = new byte[blockSize];
             for (var i = 0; i < blockSize; i++)
+            {
                 iv[i] = 0x0;
+            }
+
             return iv;
         }
     }

+ 2 - 0
src/Essensoft.AspNetCore.Payment.Alipay/Utility/AlipayUtility.cs

@@ -19,7 +19,9 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Utility
             foreach (var dem in dict)
             {
                 if (dem.Value != null)
+                {
                     newDict.Add(dem.Key, dem.Value);
+                }
             }
             return newDict;
         }

+ 14 - 3
src/Essensoft.AspNetCore.Payment.Alipay/Utility/FileItem.cs

@@ -45,8 +45,15 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Utility
         /// <param name="content">文件字节流</param>
         public FileItem(string fileName, byte[] content)
         {
-            if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName");
-            if (content == null || content.Length == 0) throw new ArgumentNullException("content");
+            if (string.IsNullOrEmpty(fileName))
+            {
+                throw new ArgumentNullException("fileName");
+            }
+
+            if (content == null || content.Length == 0)
+            {
+                throw new ArgumentNullException("content");
+            }
 
             this.fileName = fileName;
             this.content = content;
@@ -61,7 +68,11 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Utility
         public FileItem(string fileName, byte[] content, string mimeType)
             : this(fileName, content)
         {
-            if (string.IsNullOrEmpty(mimeType)) throw new ArgumentNullException("mimeType");
+            if (string.IsNullOrEmpty(mimeType))
+            {
+                throw new ArgumentNullException("mimeType");
+            }
+
             this.mimeType = mimeType;
         }
 

+ 2 - 0
src/Essensoft.AspNetCore.Payment.Alipay/Utility/HttpClientEx.cs

@@ -142,7 +142,9 @@ namespace Essensoft.AspNetCore.Payment.Alipay.Utility
         public static string BuildQuery(IDictionary<string, string> parameters)
         {
             if (parameters == null || parameters.Count == 0)
+            {
                 throw new ArgumentNullException(nameof(parameters));
+            }
 
             var content = new StringBuilder();
             foreach (var iter in parameters)

+ 5 - 4
src/Essensoft.AspNetCore.Payment.JDPay/Essensoft.AspNetCore.Payment.JDPay.csproj

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for JDPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
@@ -18,7 +18,8 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" />
+    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
   </ItemGroup>
   
   <ItemGroup>

+ 7 - 1
src/Essensoft.AspNetCore.Payment.JDPay/IJDPayClient.cs

@@ -13,7 +13,6 @@ namespace Essensoft.AspNetCore.Payment.JDPay
         /// <returns>领域对象</returns>
         Task<T> ExecuteAsync<T>(IJDPayRequest<T> request) where T : JDPayResponse;
 
-
         /// <summary>
         /// 执行JDPay API请求。
         /// </summary>
@@ -21,5 +20,12 @@ namespace Essensoft.AspNetCore.Payment.JDPay
         /// <param name="request">具体的JDPay API请求</param>
         /// <returns></returns>
         Task<T> PageExecuteAsync<T>(IJDPayRequest<T> request) where T : JDPayResponse;
+
+        /// <summary>
+        /// 执行JDPay API请求。
+        /// </summary>
+        /// <param name="request">具体的JDPay API请求</param>
+        /// <returns>领域对象</returns>
+        Task<T> ExecuteAsync<T>(IJDPayNPP10Request<T> request) where T : JDPayResponse;
     }
 }

+ 21 - 0
src/Essensoft.AspNetCore.Payment.JDPay/IJDPayNPP10Request.cs

@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+
+namespace Essensoft.AspNetCore.Payment.JDPay
+{
+    public interface IJDPayNPP10Request<T> where T : JDPayResponse
+    {
+        /// <summary>
+        /// API接口地址
+        /// </summary>
+        /// <returns></returns>
+        string GetRequestUrl();
+
+        /// <summary>
+        /// 获取所有的Key-Value形式的文本请求参数字典。其中:
+        /// Key: 请求参数名
+        /// Value: 请求参数文本值
+        /// </summary>
+        /// <returns>文本请求参数字典</returns>
+        IDictionary<string, string> GetParameters();
+    }
+}

+ 51 - 15
src/Essensoft.AspNetCore.Payment.JDPay/JDPayClient.cs

@@ -1,8 +1,10 @@
 using Essensoft.AspNetCore.Payment.JDPay.Parser;
+using Essensoft.AspNetCore.Payment.JDPay.Request;
 using Essensoft.AspNetCore.Payment.JDPay.Utility;
 using Essensoft.AspNetCore.Payment.Security;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
 using Org.BouncyCastle.Crypto;
 using System;
 using System.Collections.Generic;
@@ -14,13 +16,6 @@ namespace Essensoft.AspNetCore.Payment.JDPay
 {
     public class JDPayClient : IJDPayClient
     {
-        private const string VERSION = "version";
-        private const string MERCHANT = "merchant";
-        private const string SIGN = "sign";
-        private const string ENCRYPT = "encrypt";
-        private const string RESULT = "result";
-        private const string BODY = "body";
-
         private readonly AsymmetricKeyParameter PrivateKey;
         private readonly AsymmetricKeyParameter PublicKey;
         private readonly byte[] DesKey;
@@ -151,6 +146,47 @@ namespace Essensoft.AspNetCore.Payment.JDPay
 
         #endregion
 
+        #region IJDPayClient Members
+
+        public async Task<T> ExecuteAsync<T>(IJDPayNPP10Request<T> request) where T : JDPayResponse
+        {
+            var sortedTxtParams = new JDPayDictionary(request.GetParameters())
+            {
+                { Contants.CUSTOMER_NO, Options.CustomerNo },
+                { Contants.SIGN_TYPE, Options.SignType }
+            };
+
+            var isEncrypt = false;
+
+            if (request is JDPayDefrayPayRequest)
+            {
+                isEncrypt = true;
+            }
+
+            var encryptDic = JDPaySecurity.EncryptData(Options.PrivateCret, Options.Password, Options.PublicCert, sortedTxtParams, Options.SingKey, Options.EncryptType, isEncrypt);
+
+            var content = HttpClientEx.BuildQuery(encryptDic);
+            Logger?.LogTrace(0, "Request:{content}", content);
+
+            var body = await Client.DoPostAsync(request.GetRequestUrl(), content, "application/x-www-form-urlencoded");
+            Logger?.LogTrace(1, "Response:{content}", body);
+
+            var rsp = JsonConvert.DeserializeObject<T>(body);
+
+            // 验签
+            var dic = JsonConvert.DeserializeObject<JDPayDictionary>(body);
+
+            if (!JDPaySecurity.VerifySign(dic, Options.SingKey))
+            {
+                throw new Exception("sign check fail: check Sign and Data Fail!");
+            }
+
+            rsp.Body = body;
+            return rsp;
+        }
+
+        #endregion
+
         #region Common Method
 
         private string BuildEncryptXml<T>(IJDPayRequest<T> request, JDPayDictionary dic) where T : JDPayResponse
@@ -165,9 +201,9 @@ namespace Essensoft.AspNetCore.Payment.JDPay
             // 字典排序
             var reqdic = new JDPayDictionary
             {
-                { VERSION, request.GetApiVersion() },
-                { MERCHANT, Options.Merchant },
-                { ENCRYPT, Convert.ToBase64String(Encoding.UTF8.GetBytes(encrypt)) }
+                { Contants.VERSION, request.GetApiVersion() },
+                { Contants.MERCHANT, Options.Merchant },
+                { Contants.ENCRYPT, Convert.ToBase64String(Encoding.UTF8.GetBytes(encrypt)) }
             };
 
             return JDPayUtility.SortedDictionary2XmlStr(reqdic);
@@ -177,8 +213,8 @@ namespace Essensoft.AspNetCore.Payment.JDPay
         {
             var signDic = new JDPayDictionary(parameters)
             {
-                { VERSION, request.GetApiVersion() },
-                { MERCHANT, Options.Merchant },
+                { Contants.VERSION, request.GetApiVersion() },
+                { Contants.MERCHANT, Options.Merchant },
             };
 
             var signContent = JDPaySecurity.GetSignContent(signDic);
@@ -186,9 +222,9 @@ namespace Essensoft.AspNetCore.Payment.JDPay
 
             var encyptDic = new JDPayDictionary
             {
-                { VERSION, request.GetApiVersion() },
-                { MERCHANT, Options.Merchant },
-                { SIGN, sign }
+                { Contants.VERSION, request.GetApiVersion() },
+                { Contants.MERCHANT, Options.Merchant },
+                { Contants.SIGN, sign }
             };
 
             foreach (var iter in parameters)

+ 48 - 9
src/Essensoft.AspNetCore.Payment.JDPay/JDPayNotifyClient.cs

@@ -1,4 +1,6 @@
-using Essensoft.AspNetCore.Payment.JDPay.Parser;
+using Essensoft.AspNetCore.Payment.JDPay.Notify;
+using Essensoft.AspNetCore.Payment.JDPay.Parser;
+using Essensoft.AspNetCore.Payment.JDPay.Response;
 using Essensoft.AspNetCore.Payment.JDPay.Utility;
 using Essensoft.AspNetCore.Payment.Security;
 using Microsoft.AspNetCore.Http;
@@ -71,7 +73,9 @@ namespace Essensoft.AspNetCore.Payment.JDPay
         {
             if (request.HasFormContentType || request.Method == "GET")
             {
-                var parameters = await GetParametersAsync(request);
+                var rspInstance = Activator.CreateInstance<T>();
+
+                var parameters = GetParameters(request, !(rspInstance is JDPayDefrayPayNotifyResponse));
 
                 var query = HttpClientEx.BuildQuery(parameters);
                 Logger?.LogTrace(0, "Request:{query}", query);
@@ -79,7 +83,15 @@ namespace Essensoft.AspNetCore.Payment.JDPay
                 var parser = new JDPayDictionaryParser<T>();
                 var rsp = parser.Parse(parameters);
 
-                CheckNotifySign(rsp.Parameters);
+                if (rsp is JDPayDefrayPayNotifyResponse)
+                {
+                    CheckNotifyDefrayPaySign(rsp.Parameters);
+                }
+                else
+                {
+                    CheckNotifySign(rsp.Parameters);
+                }
+
                 return rsp;
             }
             else if (request.HasTextXmlContentType())
@@ -139,18 +151,22 @@ namespace Essensoft.AspNetCore.Payment.JDPay
 
         #region Common Method
 
-        private async Task<JDPayDictionary> GetParametersAsync(HttpRequest request)
+        private JDPayDictionary GetParameters(HttpRequest request, bool isDecrypt = true)
         {
             var parameters = new JDPayDictionary();
 
             if (request.Method == "POST")
             {
-                var form = await request.ReadFormAsync();
-                foreach (var iter in form)
+                foreach (var iter in request.Form)
                 {
                     if (!string.IsNullOrEmpty(iter.Value))
                     {
-                        parameters.Add(iter.Key, iter.Key == SIGN ? iter.Value.ToString() : JDPaySecurity.DecryptECB(iter.Value, DesKey));
+                        var value = iter.Value.ToString();
+                        if (isDecrypt)
+                        {
+                            value = iter.Key == SIGN ? iter.Value.ToString() : JDPaySecurity.DecryptECB(iter.Value, DesKey);
+                        }
+                        parameters.Add(iter.Key, value);
                     }
                 }
             }
@@ -160,7 +176,12 @@ namespace Essensoft.AspNetCore.Payment.JDPay
                 {
                     if (!string.IsNullOrEmpty(iter.Value))
                     {
-                        parameters.Add(iter.Key, iter.Key == SIGN ? iter.Value.ToString() : JDPaySecurity.DecryptECB(iter.Value, DesKey));
+                        var value = iter.Value.ToString();
+                        if (isDecrypt)
+                        {
+                            value = iter.Key == SIGN ? iter.Value.ToString() : JDPaySecurity.DecryptECB(iter.Value, DesKey);
+                        }
+                        parameters.Add(iter.Key, value);
                     }
                 }
             }
@@ -174,7 +195,7 @@ namespace Essensoft.AspNetCore.Payment.JDPay
                 throw new Exception("sign check fail: parameters is Empty!");
             }
 
-            if (!parameters.TryGetValue("sign", out var sign))
+            if (!parameters.TryGetValue(Contants.SIGN, out var sign))
             {
                 throw new Exception("sign check fail: sign is Empty!");
             }
@@ -186,6 +207,24 @@ namespace Essensoft.AspNetCore.Payment.JDPay
             }
         }
 
+        private void CheckNotifyDefrayPaySign(JDPayDictionary parameters)
+        {
+            if (parameters.Count == 0)
+            {
+                throw new Exception("sign check fail: parameters is Empty!");
+            }
+
+            if (!parameters.TryGetValue(Contants.SIGN_DATA, out var sign_data))
+            {
+                throw new Exception("sign check fail: sign is Empty!");
+            }
+
+            if (!JDPaySecurity.VerifySign(parameters, Options.SingKey))
+            {
+                throw new Exception("sign check fail: check Sign and Data Fail!");
+            }
+        }
+
         #endregion
     }
 }

+ 35 - 0
src/Essensoft.AspNetCore.Payment.JDPay/JDPayOptions.cs

@@ -21,5 +21,40 @@
         /// 商户RSA私钥
         /// </summary>
         public string RsaPrivateKey { get; set; }
+
+        /// <summary>
+        /// 京东代付 提交者会员号
+        /// </summary>
+        public string CustomerNo { get; set; }
+
+        /// <summary>
+        /// 京东代付 签名Key
+        /// </summary>
+        public string SingKey { get; set; }
+
+        /// <summary>
+        /// 京东代付 密钥文件密码
+        /// </summary>
+        public string Password { get; set; }
+
+        /// <summary>
+        /// 京东代付 密钥证书文件
+        /// </summary>
+        public string PrivateCret { get; set; }
+
+        /// <summary>
+        /// 京东代付 代付证书文件
+        /// </summary>
+        public string PublicCert { get; set; }
+
+        /// <summary>
+        /// 京东代付 加密类型 RSA
+        /// </summary>
+        public string EncryptType { get; set; } = "RSA";
+
+        /// <summary>
+        /// 京东代付 签名类型 SHA-256
+        /// </summary>
+        public string SignType { get; set; } = "SHA-256";
     }
 }

+ 0 - 1
src/Essensoft.AspNetCore.Payment.JDPay/Notify/JDPayAsyncNotifyResponse.cs

@@ -93,6 +93,5 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Notify
         /// </summary>
         [XmlElement("tradeTime")]
         public string TradeTime { get; set; }
-
     }
 }

+ 175 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Notify/JDPayDefrayPayNotifyResponse.cs

@@ -0,0 +1,175 @@
+using System.Xml.Serialization;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Notify
+{
+    public class JDPayDefrayPayNotifyResponse : JDPayNotifyResponse
+    {
+        /// <summary>
+        /// 提交者会员号
+        /// </summary>
+        [XmlElement("customer_no")]
+        public string CustomerNo { get; set; }
+
+        /// <summary>
+        /// 商户账户号
+        /// </summary>
+        [XmlElement("merchant_no")]
+        public string MerchantNo { get; set; }
+
+        /// <summary>
+        /// 签名方式
+        /// </summary>
+        [XmlElement("sign_type")]
+        public string SignType { get; set; }
+
+        /// <summary>
+        /// 签名数据
+        /// </summary>
+        [XmlElement("sign_data")]
+        public string SignData { get; set; }
+
+        /// <summary>
+        /// 商户订单流水号
+        /// </summary>
+        [XmlElement("out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 业务订单流水号
+        /// </summary>
+        [XmlElement("biz_trade_no")]
+        public string BizTradeNo { get; set; }
+
+        /// <summary>
+        /// 外部交易日
+        /// </summary>
+        [XmlElement("out_trade_date")]
+        public string OutTradeDate { get; set; }
+
+        /// <summary>
+        /// 交易类别
+        /// </summary>
+        [XmlElement("trade_class")]
+        public string TradeClass { get; set; }
+
+        /// <summary>
+        /// 订单摘要
+        /// </summary>
+        [XmlElement("trade_subject")]
+        public string TradeSubject { get; set; }
+
+        /// <summary>
+        /// 交易号
+        /// </summary>
+        [XmlElement("trade_no")]
+        public string TradeNo { get; set; }
+
+        /// <summary>
+        /// 卖方信息
+        /// </summary>
+        [XmlElement("seller_info")]
+        public string SellerInfo { get; set; }
+
+        /// <summary>
+        /// 买方信息
+        /// </summary>
+        [XmlElement("buyer_info")]
+        public string BuyerInfo { get; set; }
+
+        /// <summary>
+        /// 订单交易金额
+        /// </summary>
+        [XmlElement("trade_amount")]
+        public string TradeAmount { get; set; }
+
+        /// <summary>
+        /// 订单交易币种
+        /// </summary>
+        [XmlElement("trade_currency")]
+        public string TradeCurrency { get; set; }
+
+        /// <summary>
+        /// 已退款金额
+        /// </summary>
+        [XmlElement("refund_amount")]
+        public string RefundAmount { get; set; }
+
+        /// <summary>
+        /// 商户售卖的商品分类码
+        /// </summary>
+        [XmlElement("category_code")]
+        public string CategoryCode { get; set; }
+
+        /// <summary>
+        /// 已确认金额
+        /// </summary>
+        [XmlElement("confirm_amount")]
+        public string ConfirmAmount { get; set; }
+
+        /// <summary>
+        /// 交易响应码
+        /// </summary>
+        [XmlElement("trade_respcode")]
+        public string TradeRespcode { get; set; }
+
+        /// <summary>
+        /// 交易响应描述
+        /// </summary>
+        [XmlElement("trade_respmsg")]
+        public string TradeRespmsg { get; set; }
+
+        /// <summary>
+        /// 交易状态
+        /// </summary>
+        [XmlElement("trade_status")]
+        public string TradeStatus { get; set; }
+
+        /// <summary>
+        /// 支付完成日
+        /// </summary>
+        [XmlElement("trade_pay_date")]
+        public string TradePayDate { get; set; }
+
+        /// <summary>
+        /// 支付完时间
+        /// </summary>
+        [XmlElement("trade_pay_time")]
+        public string TradePayTime { get; set; }
+
+        /// <summary>
+        /// 支付工具
+        /// </summary>
+        [XmlElement("pay_tool")]
+        public string PayTool { get; set; }
+
+        /// <summary>
+        /// 支付银行
+        /// </summary>
+        [XmlElement("bank_code")]
+        public string BankCode { get; set; }
+
+        /// <summary>
+        /// 支付卡种
+        /// </summary>
+        [XmlElement("card_type")]
+        public string CardType { get; set; }
+
+        /// <summary>
+        /// 交易完成日
+        /// </summary>
+        [XmlElement("trade_finish_date")]
+        public string TradeFinishDate { get; set; }
+
+        /// <summary>
+        /// 交易完时间
+        /// </summary>
+        [XmlElement("trade_finish_time")]
+        public string TradeFinishTime { get; set; }
+
+        /// <summary>
+        /// 订单返回信息
+        /// </summary>
+        [XmlElement("return_params")]
+        public string ReturnParams { get; set; }
+    }
+}

+ 13 - 1
src/Essensoft.AspNetCore.Payment.JDPay/Parser/JDPayDictionaryParser.cs

@@ -14,9 +14,14 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Parser
         public T Parse(JDPayDictionary dic)
         {
             if (dic == null || dic.Count == 0)
+            {
                 throw new ArgumentNullException(nameof(dic));
+            }
 
-            if (!DicProperties.ContainsKey(typeof(T))) DicProperties[typeof(T)] = GetPropertiesMap(typeof(T));
+            if (!DicProperties.ContainsKey(typeof(T)))
+            {
+                DicProperties[typeof(T)] = GetPropertiesMap(typeof(T));
+            }
 
             var propertiesMap = DicProperties[typeof(T)];
 
@@ -25,7 +30,9 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Parser
             foreach (var item in dic)
             {
                 if (propertiesMap.ContainsKey(item.Key))
+                {
                     propertiesMap[item.Key].SetValue(rsp, item.Value.TryTo(propertiesMap[item.Key].PropertyType));
+                }
             }
 
             if (rsp != null)
@@ -39,13 +46,18 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Parser
         private Dictionary<string, PropertyInfo> GetPropertiesMap(Type type)
         {
             if (type == null)
+            {
                 throw new ArgumentNullException(nameof(type));
+            }
+
             var propertiesMap = new Dictionary<string, PropertyInfo>();
             var query = from e in typeof(T).GetProperties()
                         where e.CanWrite && e.GetCustomAttributes(typeof(XmlElementAttribute), true).Any()
                         select new { Property = e, Element = e.GetCustomAttributes(typeof(XmlElementAttribute), true).OfType<XmlElementAttribute>().First() };
             foreach (var item in query)
+            {
                 propertiesMap.Add(item.Element.ElementName, item.Property);
+            }
 
             return propertiesMap;
         }

+ 4 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Parser/JDPayXmlParser.cs

@@ -22,10 +22,14 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Parser
             { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
+            {
                 rsp.Body = body;
+            }
 
             return rsp;
         }

+ 65 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayAccountQueryRequest.cs

@@ -0,0 +1,65 @@
+using Essensoft.AspNetCore.Payment.JDPay.Response;
+using System.Collections.Generic;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Request
+{
+    /// <summary>
+    /// 余额查询接口
+    /// </summary>
+    public class JDPayAccountQueryRequest : IJDPayNPP10Request<JDPayAccountQueryResponse>
+    {
+        /// <summary>
+        /// 请求时间
+        /// </summary>
+        public string RequestDatetime { get; set; }
+
+        /// <summary>
+        /// 商户订单流水号
+        /// </summary>
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 外部订单日
+        /// </summary>
+        public string OutTradeDate { get; set; }
+
+        /// <summary>
+        /// 会员信息
+        /// </summary>
+        public string BuyerInfo { get; set; }
+
+        /// <summary>
+        /// 查询类型
+        /// </summary>
+        public string QueryType { get; set; }
+
+        /// <summary>
+        /// 账户类型码
+        /// </summary>
+        public string LedgerType { get; set; }
+
+        #region IJDPayNPP10Request
+
+        public IDictionary<string, string> GetParameters()
+        {
+            var parameters = new JDPayDictionary()
+            {
+                { "request_datetime", RequestDatetime },
+                { "out_trade_no",  OutTradeNo },
+                { "out_trade_date", OutTradeDate },
+                { "buyer_info", BuyerInfo },
+                { "query_type", QueryType },
+                { "ledger_type", LedgerType },
+            };
+
+            return parameters;
+        }
+
+        public string GetRequestUrl()
+        {
+            return "https://mapi.jdpay.com/npp10/account_query";
+        }
+
+        #endregion
+    }
+}

+ 203 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayDefrayPayRequest.cs

@@ -0,0 +1,203 @@
+using Essensoft.AspNetCore.Payment.JDPay.Response;
+using System.Collections.Generic;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Request
+{
+    /// <summary>
+    /// 代付交易请求接口
+    /// </summary>
+    public class JDPayDefrayPayRequest : IJDPayNPP10Request<JDPayDefrayPayResponse>
+    {
+        /// <summary>
+        /// 请求时间
+        /// </summary>
+        public string RequestDatetime { get; set; }
+
+        /// <summary>
+        /// 商户订单流水号
+        /// </summary>
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 业务订单流水号
+        /// </summary>
+        public string BizTradeNo { get; set; }
+
+        /// <summary>
+        /// 外部订单日
+        /// </summary>
+        public string OutTradeDate { get; set; }
+
+        /// <summary>
+        /// 订单交易金额
+        /// </summary>
+        public string TradeAmount { get; set; }
+
+        /// <summary>
+        /// 币种
+        /// </summary>
+        public string TradeCurrency { get; set; }
+
+        /// <summary>
+        /// 卖方信息
+        /// </summary>
+        public string SellerInfo { get; set; }
+
+        /// <summary>
+        /// 订单摘要
+        /// </summary>
+        public string TradeSubject { get; set; }
+
+        /// <summary>
+        /// 商户售卖的商品分类码
+        /// </summary>
+        public string CategoryCode { get; set; }
+
+        /// <summary>
+        /// 支付工具
+        /// </summary>
+        public string PayTool { get; set; }
+
+        /// <summary>
+        /// 提交业务渠道
+        /// </summary>
+        public string TradeSource { get; set; }
+
+        /// <summary>
+        /// 收款银行编码
+        /// </summary>
+        public string PayeeBankCode { get; set; }
+
+        /// <summary>
+        /// 收款联行号
+        /// </summary>
+        public string PayeeBankAssociatedCode { get; set; }
+
+        /// <summary>
+        /// 收款银行全称
+        /// </summary>
+        public string PayeeBankFullname { get; set; }
+
+        /// <summary>
+        /// 收款行所在国家地区码
+        /// </summary>
+        public string PayeeBankCountryCode { get; set; }
+
+        /// <summary>
+        /// 收款行所在省编码
+        /// </summary>
+        public string PayeeBankProvinceCode { get; set; }
+
+        /// <summary>
+        /// 收款行所在市编码
+        /// </summary>
+        public string PayeeBankCityCode { get; set; }
+
+        /// <summary>
+        /// 收款卡种
+        /// </summary>
+        public string PayeeCardType { get; set; }
+
+        /// <summary>
+        /// 收款账户类型
+        /// </summary>
+        public string PayeeAccountType { get; set; }
+
+        /// <summary>
+        /// 收款账户号
+        /// </summary>
+        public string PayeeAccountNo { get; set; }
+
+        /// <summary>
+        /// 收款账户名称
+        /// </summary>
+        public string PayeeAccountName { get; set; }
+
+        /// <summary>
+        /// 持卡人证件类型
+        /// </summary>
+        public string PayeeIdType { get; set; }
+
+        /// <summary>
+        /// 持卡人证件号
+        /// </summary>
+        public string PayeeIdNo { get; set; }
+
+        /// <summary>
+        /// 持卡人手机
+        /// </summary>
+        public string PayeeMobile { get; set; }
+
+        /// <summary>
+        /// 服务器通知地址
+        /// </summary>
+        public string NotifyUrl { get; set; }
+
+        /// <summary>
+        /// 交易回传参数
+        /// </summary>
+        public string ReturnParams { get; set; }
+
+        /// <summary>
+        /// 扩展参数
+        /// </summary>
+        public string ExtendParams { get; set; }
+
+        /// <summary>
+        /// 银行卡信息类型
+        /// </summary>
+        public string BankCardInfoType { get; set; }
+
+        /// <summary>
+        /// 卡ID
+        /// </summary>
+        public string BankCardId { get; set; }
+
+        #region IJDPayNPP10Request
+
+        public IDictionary<string, string> GetParameters()
+        {
+            var parameters = new JDPayDictionary()
+            {
+                { "request_datetime", RequestDatetime },
+                { "out_trade_no",  OutTradeNo },
+                { "biz_trade_no", BizTradeNo },
+                { "out_trade_date", OutTradeDate },
+                { "trade_amount", TradeAmount },
+                { "trade_currency", TradeCurrency },
+                { "seller_info", SellerInfo },
+                { "trade_subject", TradeSubject },
+                { "category_code", CategoryCode },
+                { "pay_tool", PayTool },
+                { "trade_source", TradeSource },
+                { "payee_bank_code", PayeeBankCode },
+                { "payee_bank_associated_code", PayeeBankAssociatedCode },
+                { "payee_bank_fullname", PayeeBankFullname },
+                { "payee_bank_country_code", PayeeBankCountryCode },
+                { "payee_bank_province_code", PayeeBankProvinceCode },
+                { "payee_bank_city_code", PayeeBankCityCode },
+                { "payee_card_type", PayeeCardType },
+                { "payee_account_type", PayeeAccountType },
+                { "payee_account_no", PayeeAccountNo },
+                { "payee_account_name", PayeeAccountName },
+                { "payee_id_type", PayeeIdType },
+                { "payee_id_no", PayeeIdNo },
+                { "payee_mobile", PayeeMobile },
+                { "notify_url", NotifyUrl },
+                { "return_params", ReturnParams },
+                { "extend_params", ExtendParams },
+                { "bank_card_info_type", BankCardInfoType },
+                { "bank_card_id", BankCardId },
+            };
+
+            return parameters;
+        }
+
+        public string GetRequestUrl()
+        {
+            return "https://mapi.jdpay.com/npp10/defray_pay";
+        }
+
+        #endregion
+    }
+}

+ 0 - 1
src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayRefundRequest.cs

@@ -53,7 +53,6 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Request
         /// </summary>
         public string TermInfoId { get; set; }
 
-
         #region IJDPayRequest Members
 
         private string ApiVersion = "V2.0";

+ 53 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Request/JDPayTradeQueryRequest.cs

@@ -0,0 +1,53 @@
+using Essensoft.AspNetCore.Payment.JDPay.Response;
+using System.Collections.Generic;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Request
+{
+    /// <summary>
+    /// 交易查询接口
+    /// </summary>
+    public class JDPayTradeQueryRequest : IJDPayNPP10Request<JDPayTradeQueryResponse>
+    {
+        /// <summary>
+        /// 请求时间
+        /// </summary>
+        public string RequestDatetime { get; set; }
+
+        /// <summary>
+        /// 商户订单流水号
+        /// </summary>
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 交易号
+        /// </summary>
+        public string TradeNo { get; set; }
+
+        /// <summary>
+        /// 查询类型
+        /// </summary>
+        public string TradeType { get; set; }
+
+        #region IJDPayNPP10Request
+
+        public IDictionary<string, string> GetParameters()
+        {
+            var parameters = new JDPayDictionary()
+            {
+                { "request_datetime", RequestDatetime },
+                { "out_trade_no",  OutTradeNo },
+                { "trade_no", TradeNo },
+                { "trade_type", TradeType },
+            };
+
+            return parameters;
+        }
+
+        public string GetRequestUrl()
+        {
+            return "https://mapi.jdpay.com/npp10/trade_query";
+        }
+
+        #endregion
+    }
+}

+ 73 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Response/JDPayAccountQueryResponse.cs

@@ -0,0 +1,73 @@
+using Newtonsoft.Json;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Response
+{
+    public class JDPayAccountQueryResponse : JDPayResponse
+    {
+        /// <summary>
+        /// 提交者会员号
+        /// </summary>
+        [JsonProperty("customer_no")]
+        public string CustomerNo { get; set; }
+
+        /// <summary>
+        /// 响应时间
+        /// </summary>
+        [JsonProperty("response_datetime")]
+        public string ResponseDatetime { get; set; }
+
+        /// <summary>
+        /// 响应编码
+        /// </summary>
+        [JsonProperty("response_code")]
+        public string ResponseCode { get; set; }
+
+        /// <summary>
+        /// 响应描述
+        /// </summary>
+        [JsonProperty("response_message")]
+        public string ResponseMessage { get; set; }
+
+        /// <summary>
+        /// 签名方式
+        /// </summary>
+        [JsonProperty("sign_type")]
+        public string SignType { get; set; }
+
+        /// <summary>
+        /// 签名数据
+        /// </summary>
+        [JsonProperty("sign_data")]
+        public string SignData { get; set; }
+
+        /// <summary>
+        /// 会员信息
+        /// </summary>
+        [JsonProperty("buyer_info")]
+        public string BuyerInfo { get; set; }
+
+        /// <summary>
+        /// 账户总金额
+        /// </summary>
+        [JsonProperty("account_amount")]
+        public string AccountAmount { get; set; }
+
+        /// <summary>
+        /// 冻结总余额
+        /// </summary>
+        [JsonProperty("frozen_amount")]
+        public string FrozenAmount { get; set; }
+
+        /// <summary>
+        /// 账户余额币种
+        /// </summary>
+        [JsonProperty("account_currency")]
+        public string AccountCurrency { get; set; }
+
+        /// <summary>
+        /// 商户请求流水号
+        /// </summary>
+        [JsonProperty("out_trade_no")]
+        public string OutTradeNo { get; set; }
+    }
+}

+ 79 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Response/JDPayDefrayPayResponse.cs

@@ -0,0 +1,79 @@
+using Newtonsoft.Json;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Response
+{
+    public class JDPayDefrayPayResponse : JDPayResponse
+    {
+        /// <summary>
+        /// 提交者会员号
+        /// </summary>
+        [JsonProperty("customer_no")]
+        public string CustomerNo { get; set; }
+
+        /// <summary>
+        /// 响应时间
+        /// </summary>
+        [JsonProperty("response_datetime")]
+        public string ResponseDatetime { get; set; }
+
+        /// <summary>
+        /// 签名方式
+        /// </summary>
+        [JsonProperty("sign_type")]
+        public string SignType { get; set; }
+
+        /// <summary>
+        /// 签名数据
+        /// </summary>
+        [JsonProperty("sign_data")]
+        public string SignData { get; set; }
+
+        /// <summary>
+        /// 响应编码
+        /// </summary>
+        [JsonProperty("response_code")]
+        public string ResponseCode { get; set; }
+
+        /// <summary>
+        /// 响应描述
+        /// </summary>
+        [JsonProperty("response_message")]
+        public string ResponseMessage { get; set; }
+
+        /// <summary>
+        /// 商户订单流水号
+        /// </summary>
+        [JsonProperty("out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 交易号
+        /// </summary>
+        [JsonProperty("trade_no")]
+        public string TradeNo { get; set; }
+
+        /// <summary>
+        /// 交易状态
+        /// </summary>
+        [JsonProperty("trade_status")]
+        public string TradeStatus { get; set; }
+
+        /// <summary>
+        /// 订单交易金额
+        /// </summary>
+        [JsonProperty("trade_amount")]
+        public string TradeAmount { get; set; }
+
+        /// <summary>
+        /// 币种
+        /// </summary>
+        [JsonProperty("trade_currency")]
+        public string TradeCurrency { get; set; }
+
+        /// <summary>
+        /// 交易回传参数
+        /// </summary>
+        [JsonProperty("return_params")]
+        public string ReturnParams { get; set; }
+    }
+}

+ 187 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Response/JDPayTradeQueryResponse.cs

@@ -0,0 +1,187 @@
+using Newtonsoft.Json;
+
+namespace Essensoft.AspNetCore.Payment.JDPay.Response
+{
+    public class JDPayTradeQueryResponse : JDPayResponse
+    {
+        /// <summary>
+        /// 提交者会员号
+        /// </summary>
+        [JsonProperty("customer_no")]
+        public string CustomerNo { get; set; }
+
+        /// <summary>
+        /// 响应时间
+        /// </summary>
+        [JsonProperty("response_datetime")]
+        public string ResponseDatetime { get; set; }
+
+        /// <summary>
+        /// 响应编码
+        /// </summary>
+        [JsonProperty("response_code")]
+        public string ResponseCode { get; set; }
+
+        /// <summary>
+        /// 响应描述
+        /// </summary>
+        [JsonProperty("response_message")]
+        public string ResponseMessage { get; set; }
+
+        /// <summary>
+        /// 签名方式
+        /// </summary>
+        [JsonProperty("sign_type")]
+        public string SignType { get; set; }
+
+        /// <summary>
+        /// 签名数据
+        /// </summary>
+        [JsonProperty("sign_data")]
+        public string SignData { get; set; }
+
+        /// <summary>
+        /// 商户订单流水号
+        /// </summary>
+        [JsonProperty("out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 业务订单流水号
+        /// </summary>
+        [JsonProperty("biz_trade_no")]
+        public string BizTradeNo { get; set; }
+
+        /// <summary>
+        /// 外部交易日
+        /// </summary>
+        [JsonProperty("out_trade_date")]
+        public string OutTradeDate { get; set; }
+
+        /// <summary>
+        /// 交易类别
+        /// </summary>
+        [JsonProperty("trade_class")]
+        public string TradeClass { get; set; }
+
+        /// <summary>
+        /// 订单摘要
+        /// </summary>
+        [JsonProperty("trade_subject")]
+        public string TradeSubject { get; set; }
+
+        /// <summary>
+        /// 交易号
+        /// </summary>
+        [JsonProperty("trade_no")]
+        public string TradeNo { get; set; }
+
+        /// <summary>
+        /// 卖方信息
+        /// </summary>
+        [JsonProperty("seller_info")]
+        public string SellerInfo { get; set; }
+
+        /// <summary>
+        /// 买方信息
+        /// </summary>
+        [JsonProperty("buyer_info")]
+        public string BuyerInfo { get; set; }
+
+        /// <summary>
+        /// 订单交易金额
+        /// </summary>
+        [JsonProperty("trade_amount")]
+        public string TradeAmount { get; set; }
+
+        /// <summary>
+        /// 订单交易币种
+        /// </summary>
+        [JsonProperty("trade_currency")]
+        public string TradeCurrency { get; set; }
+
+        /// <summary>
+        /// 已退款金额
+        /// </summary>
+        [JsonProperty("refund_amount")]
+        public string RefundAmount { get; set; }
+
+        /// <summary>
+        /// 商户售卖的商品分类码
+        /// </summary>
+        [JsonProperty("category_code")]
+        public string CategoryCode { get; set; }
+
+        /// <summary>
+        /// 已确认金额
+        /// </summary>
+        [JsonProperty("confirm_amount")]
+        public string ConfirmAmount { get; set; }
+
+        /// <summary>
+        /// 交易响应码
+        /// </summary>
+        [JsonProperty("trade_respcode")]
+        public string TradeRespcode { get; set; }
+
+        /// <summary>
+        /// 交易响应描述
+        /// </summary>
+        [JsonProperty("trade_respmsg")]
+        public string TradeRespmsg { get; set; }
+
+        /// <summary>
+        /// 交易状态
+        /// </summary>
+        [JsonProperty("trade_status")]
+        public string TradeStatus { get; set; }
+
+        /// <summary>
+        /// 支付完成日
+        /// </summary>
+        [JsonProperty("trade_pay_date")]
+        public string TradePayDate { get; set; }
+
+        /// <summary>
+        /// 支付完时间
+        /// </summary>
+        [JsonProperty("trade_pay_time")]
+        public string TradePayTime { get; set; }
+
+        /// <summary>
+        /// 支付工具
+        /// </summary>
+        [JsonProperty("pay_tool")]
+        public string PayTool { get; set; }
+
+        /// <summary>
+        /// 支付银行
+        /// </summary>
+        [JsonProperty("bank_code")]
+        public string BankCode { get; set; }
+
+        /// <summary>
+        /// 支付卡种
+        /// </summary>
+        [JsonProperty("card_type")]
+        public string CardType { get; set; }
+
+        /// <summary>
+        /// 交易完成日
+        /// </summary>
+        [JsonProperty("trade_finish_date")]
+        public string TradeFinishDate { get; set; }
+
+        /// <summary>
+        /// 交易完时间
+        /// </summary>
+        [JsonProperty("trade_finish_time")]
+        public string TradeFinishTime { get; set; }
+
+        /// <summary>
+        /// 订单返回信息
+        /// </summary>
+        [JsonProperty("return_params")]
+        public string ReturnParams { get; set; }
+    }
+}

+ 18 - 0
src/Essensoft.AspNetCore.Payment.JDPay/Utility/Contants.cs

@@ -0,0 +1,18 @@
+namespace Essensoft.AspNetCore.Payment.JDPay.Utility
+{
+    public class Contants
+    {
+        public const string VERSION = "version";
+        public const string MERCHANT = "merchant";
+        public const string SIGN = "sign";
+        public const string ENCRYPT = "encrypt";
+        public const string RESULT = "result";
+        public const string BODY = "body";
+
+        public const string CUSTOMER_NO = "customer_no";
+        public const string SIGN_TYPE = "sign_type";
+        public const string SIGN_DATA = "sign_data";
+        public const string ENCRYPT_TYPE = "encrypt_type";
+        public const string ENCRYPT_DATA = "encrypt_data";
+    }
+}

+ 2 - 3
src/Essensoft.AspNetCore.Payment.JDPay/Utility/HttpClientEx.cs

@@ -21,9 +21,9 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
         /// <param name="url">请求地址</param>
         /// <param name="content">请求内容</param>
         /// <returns>HTTP响应</returns>
-        public async Task<string> DoPostAsync(string url, string content)
+        public async Task<string> DoPostAsync(string url, string content, string mediaType = "application/xml")
         {
-            using (var requestContent = new StringContent(content, Encoding.UTF8, "application/xml"))
+            using (var requestContent = new StringContent(content, Encoding.UTF8, mediaType))
             using (var response = await PostAsync(url, requestContent))
             using (var resContent = response.Content)
             {
@@ -31,7 +31,6 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
             }
         }
 
-
         /// <summary>
         /// 组装普通文本请求参数。
         /// </summary>

+ 168 - 10
src/Essensoft.AspNetCore.Payment.JDPay/Utility/JDPaySecurity.cs

@@ -1,7 +1,16 @@
 using Essensoft.AspNetCore.Payment.Security;
+using Org.BouncyCastle.Cms;
 using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.X509.Store;
 using System;
+using System.Collections;
+using System.IO;
+using System.Security.Cryptography.X509Certificates;
 using System.Text;
+using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
 
 namespace Essensoft.AspNetCore.Payment.JDPay.Utility
 {
@@ -13,13 +22,85 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
         public static string GetSignContent(JDPayDictionary para)
         {
             if (para == null || para.Count == 0)
+            {
                 return string.Empty;
+            }
 
             var sb = new StringBuilder();
             foreach (var iter in para)
             {
                 if (!string.IsNullOrEmpty(iter.Value) && iter.Key != "sign")
+                {
+                    sb.Append(iter.Key).Append("=").Append(iter.Value).Append("&");
+                }
+            }
+
+            return sb.Remove(sb.Length - 1, 1).ToString();
+        }
+
+        private static string GetNPP10Sign(JDPayDictionary para, string algorithm, string salt)
+        {
+            if (para == null || para.Count == 0)
+            {
+                return string.Empty;
+            }
+
+            var sb = new StringBuilder();
+            foreach (var iter in para)
+            {
+                if (!string.IsNullOrEmpty(iter.Value) && iter.Key != "sign_type" && iter.Key != "sign_data" && iter.Key != "encrypt_type" && iter.Key != "encrypt_data" && iter.Key != "salt")
+                {
+                    sb.Append(iter.Key).Append("=").Append(iter.Value).Append("&");
+                }
+            }
+
+            var sign = string.Empty;
+            var data = sb.Remove(sb.Length - 1, 1).ToString() + salt;
+
+            if ("SHA" == algorithm)
+            {
+                sign = SHA1.Compute(data).ToUpper();
+            }
+            else if ("SHA-256" == algorithm)
+            {
+                sign = SHA256.Compute(data).ToUpper();
+            }
+
+            return sign;
+        }
+
+        private static string GetNPP10Sign(string content, string algorithm, string salt)
+        {
+            var sign = string.Empty;
+
+            var data = content + salt;
+
+            if ("SHA" == algorithm)
+            {
+                sign = SHA1.Compute(data);
+            }
+            else if ("SHA-256" == algorithm)
+            {
+                sign = SHA256.Compute(data);
+            }
+
+            return sign;
+        }
+
+        private static string GetNPP10SignContentOrEncryptContent(JDPayDictionary para)
+        {
+            if (para == null || para.Count == 0)
+            {
+                return string.Empty;
+            }
+
+            var sb = new StringBuilder();
+            foreach (var iter in para)
+            {
+                if (!string.IsNullOrEmpty(iter.Value) && iter.Key != "sign_type" && iter.Key != "sign_data" && iter.Key != "encrypt_type" && iter.Key != "encrypt_data" && iter.Key != "salt")
+                {
                     sb.Append(iter.Key).Append("=").Append(iter.Value).Append("&");
+                }
             }
 
             return sb.Remove(sb.Length - 1, 1).ToString();
@@ -27,14 +108,14 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
 
         public static string RSASign(string sourceSignString, AsymmetricKeyParameter privateKey)
         {
-            var sha256SourceSignString = Security.SHA256.Compute(sourceSignString);
+            var sha256SourceSignString = SHA256.Compute(sourceSignString);
             var newsks = RSA_ECB_PKCS1Padding.Encrypt(Encoding.UTF8.GetBytes(sha256SourceSignString), privateKey);
             return Convert.ToBase64String(newsks, Base64FormattingOptions.InsertLineBreaks);
         }
 
         public static bool RSACheckContent(string content, string sign, AsymmetricKeyParameter publicKey)
         {
-            var sha256SourceSignString = Security.SHA256.Compute(content);
+            var sha256SourceSignString = SHA256.Compute(content);
             var decryptArr = RSA_ECB_PKCS1Padding.Decrypt(Convert.FromBase64String(sign), publicKey);
             var decrypStr = Encoding.UTF8.GetString(decryptArr);
             return sha256SourceSignString.Equals(decrypStr);
@@ -44,7 +125,7 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
         {
             var resultByte = InitResultByteArray(data);
             var desdata = DES3.Encode(resultByte, key, iv, DESCipherMode.ECB, DESPaddingMode.Zeros);
-            return ByteToHexStr(desdata);
+            return BitConverter.ToString(desdata).Replace("-", "").ToLower();
         }
 
         public static string DecryptECB(string data, byte[] key)
@@ -66,7 +147,7 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
             {
                 tempData[i] = unDesResult[4 + i];
             }
-            var hexStr = ByteToHexStr(tempData);
+            var hexStr = BitConverter.ToString(tempData).Replace("-", "").ToLower();
             var str = Hex2bin(hexStr);
             return str;
         }
@@ -171,17 +252,94 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
             return Encoding.UTF8.GetString(bytes);
         }
 
-        public static string ByteToHexStr(byte[] bytes)
+        public static bool VerifySign(JDPayDictionary dic, string key)
+        {
+            dic.TryGetValue(Contants.SIGN_TYPE, out var algorithm);
+            dic.TryGetValue(Contants.SIGN_DATA, out var sign);
+            dic.Remove(Contants.SIGN_TYPE);
+            dic.Remove(Contants.SIGN_DATA);
+            return Verify(sign, dic, algorithm, key);
+        }
+
+        private static bool Verify(string signStr, JDPayDictionary dic, string algorithm, string salt)
+        {
+            if (string.IsNullOrEmpty(signStr) || null == dic || dic.Count == 0)
+            {
+                return false;
+            }
+            var newsign = GetNPP10Sign(dic, algorithm, salt);
+            return newsign == signStr;
+        }
+
+        public static JDPayDictionary EncryptData(string signCert, string password, string envelopCert, JDPayDictionary dic, string singKey, string encryptType, bool isEncrypt)
         {
-            var returnStr = string.Empty;
-            if (bytes != null)
+            var encryptData = new JDPayDictionary();
+            var data = GetNPP10SignContentOrEncryptContent(dic);
+
+            dic.TryGetValue(Contants.CUSTOMER_NO, out var customerNo);
+            dic.TryGetValue(Contants.SIGN_TYPE, out var signType);
+
+            if (!isEncrypt || string.IsNullOrEmpty(encryptType))
+            {
+                dic.Add(Contants.SIGN_DATA, GetNPP10Sign(data, signType, singKey));
+                encryptData = dic;
+            }
+            else
             {
-                for (var i = 0; i < bytes.Length; i++)
+                encryptData.Add(Contants.SIGN_TYPE, signType);
+                encryptData.Add(Contants.SIGN_DATA, GetNPP10Sign(data, signType, singKey));
+                encryptData.Add(Contants.CUSTOMER_NO, customerNo);
+                encryptData.Add(Contants.ENCRYPT_TYPE, encryptType);
+                if ("RSA" == encryptType)
                 {
-                    returnStr += bytes[i].ToString("X2");
+                    encryptData.Add(Contants.ENCRYPT_DATA, SignEnvelop(signCert, password, envelopCert, data));
+                }
+                else
+                {
+                    throw new Exception("不支持的加密方式");
                 }
             }
-            return returnStr.ToLower();
+
+            return encryptData;
+        }
+
+        private static string SignEnvelop(string signCert, string password, string envelopCert, string orgData)
+        {
+            var pkcs12StoreBuilder = new Pkcs12StoreBuilder();
+            var pkcs12Store = pkcs12StoreBuilder.Build();
+            pkcs12Store.Load(new MemoryStream(Convert.FromBase64String(signCert)), password.ToCharArray());
+
+            var aliases = pkcs12Store.Aliases;
+            var enumerator = aliases.GetEnumerator();
+            enumerator.MoveNext();
+            var alias = enumerator.Current.ToString();
+            var privKey = pkcs12Store.GetKey(alias);
+
+            var x509Cert = pkcs12Store.GetCertificate(alias).Certificate;
+            var sha1Signer = SignerUtilities.GetSigner("SHA1withRSA");
+            sha1Signer.Init(true, privKey.Key);
+
+            var gen = new CmsSignedDataGenerator();
+            gen.AddSignerInfoGenerator(new SignerInfoGeneratorBuilder().Build(new Asn1SignatureFactory("SHA1withRSA", privKey.Key), x509Cert));
+            gen.AddCertificates(X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(new ArrayList { x509Cert })));
+
+            var sigData = gen.Generate(new CmsProcessableByteArray(Encoding.UTF8.GetBytes(orgData)), true);
+            var signData = sigData.GetEncoded();
+
+            var certificate = DotNetUtilities.FromX509Certificate(new X509Certificate2(Convert.FromBase64String(envelopCert)));
+            var rst = Convert.ToBase64String(EncryptEnvelop(certificate, signData));
+            return rst;
+        }
+
+        private static byte[] EncryptEnvelop(X509Certificate certificate, byte[] bsOrgData)
+        {
+            var gen = new CmsEnvelopedDataGenerator();
+            var data = new CmsProcessableByteArray(bsOrgData);
+            gen.AddKeyTransRecipient(certificate);
+
+            var enveloped = gen.Generate(data, CmsEnvelopedGenerator.DesEde3Cbc);
+            var a = enveloped.ContentInfo.ToAsn1Object();
+            return a.GetEncoded();
         }
     }
 }

+ 14 - 1
src/Essensoft.AspNetCore.Payment.JDPay/Utility/JDPayUtility.cs

@@ -37,14 +37,22 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
             try
             {
                 if (Object == null || Convert.IsDBNull(Object))
+                {
                     return GetDefault(destinationType);
+                }
+
                 if ((Object as string) != null)
                 {
                     var ObjectValue = Object as string;
                     if (destinationType.IsEnum)
-                        return System.Enum.Parse(destinationType, ObjectValue, true);
+                    {
+                        return Enum.Parse(destinationType, ObjectValue, true);
+                    }
+
                     if (string.IsNullOrEmpty(ObjectValue))
+                    {
                         return GetDefault(destinationType);
+                    }
                 }
                 if ((Object as IConvertible) != null)
                 {
@@ -54,10 +62,15 @@ namespace Essensoft.AspNetCore.Payment.JDPay.Utility
                     return Convert.ChangeType(Object, destination);
                 }
                 if (destinationType.IsAssignableFrom(Object.GetType()))
+                {
                     return Object;
+                }
+
                 var Converter = TypeDescriptor.GetConverter(Object.GetType());
                 if (Converter.CanConvertTo(destinationType))
+                {
                     return Converter.ConvertTo(Object, destinationType);
+                }
             }
             catch { }
             return GetDefault(destinationType);

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

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for LianLianPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" />
     <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
   </ItemGroup>
 

+ 4 - 0
src/Essensoft.AspNetCore.Payment.LianLianPay/Parser/LianLianPayDictionaryParser.cs

@@ -9,7 +9,9 @@ namespace Essensoft.AspNetCore.Payment.LianLianPay.Parser
         public T Parse(IDictionary dic)
         {
             if (dic == null || dic.Count == 0)
+            {
                 throw new ArgumentNullException(nameof(dic));
+            }
 
             T rsp = null;
 
@@ -21,7 +23,9 @@ namespace Essensoft.AspNetCore.Payment.LianLianPay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             return rsp;
         }

+ 2 - 0
src/Essensoft.AspNetCore.Payment.LianLianPay/Parser/LianLianPayJsonParser.cs

@@ -27,7 +27,9 @@ namespace Essensoft.AspNetCore.Payment.LianLianPay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
             {

+ 2 - 0
src/Essensoft.AspNetCore.Payment.LianLianPay/Utility/LianLianPaySecurity.cs

@@ -11,7 +11,9 @@ namespace Essensoft.AspNetCore.Payment.LianLianPay.Utility
         public static string GetSignContent(LianLianPayDictionary para, List<string> exclude = null)
         {
             if (para == null || para.Count == 0)
+            {
                 return string.Empty;
+            }
 
             var sb = new StringBuilder();
             foreach (var iter in para)

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

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for QPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" />
   </ItemGroup>
 
   <ItemGroup>

+ 4 - 0
src/Essensoft.AspNetCore.Payment.QPay/Parser/QPayXmlParser.cs

@@ -10,7 +10,9 @@ namespace Essensoft.AspNetCore.Payment.QPay.Parser
         public T Parse(string body)
         {
             if (string.IsNullOrEmpty(body))
+            {
                 throw new ArgumentNullException(nameof(body));
+            }
 
             T rsp = null;
             var parameters = new QPayDictionary();
@@ -32,7 +34,9 @@ namespace Essensoft.AspNetCore.Payment.QPay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
             {

+ 2 - 0
src/Essensoft.AspNetCore.Payment.QPay/Utility/QPaySignature.cs

@@ -12,7 +12,9 @@ namespace Essensoft.AspNetCore.Payment.QPay.Utility
             foreach (var iter in parameters)
             {
                 if (!string.IsNullOrEmpty(iter.Value) && iter.Key != "sign" && (excludeSignType ? iter.Key != "sign_type" : true))
+                {
                     content.Append(iter.Key).Append('=').Append(iter.Value).Append("&");
+                }
             }
             var signContent = content.Append("key=").Append(key).ToString();
             return MD5.Compute(signContent).ToUpper();

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

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for Security.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>

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

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for UnionPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" />
     <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
   </ItemGroup>
 

+ 4 - 0
src/Essensoft.AspNetCore.Payment.UnionPay/Parser/UnionPayDictionaryParser.cs

@@ -9,7 +9,9 @@ namespace Essensoft.AspNetCore.Payment.UnionPay.Parser
         public T Parse(IDictionary dic)
         {
             if (dic == null || dic.Count == 0)
+            {
                 throw new ArgumentNullException(nameof(dic));
+            }
 
             T rsp = null;
 
@@ -21,7 +23,9 @@ namespace Essensoft.AspNetCore.Payment.UnionPay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             return rsp;
         }

+ 3 - 0
src/Essensoft.AspNetCore.Payment.UnionPay/UnionPayClient.cs

@@ -276,7 +276,10 @@ namespace Essensoft.AspNetCore.Payment.UnionPay
                 }
             }
             if (key != null)
+            {
                 PutKeyValueToDictionary(sb, isKey, key, Dictionary);
+            }
+
             return Dictionary;
         }
 

+ 6 - 0
src/Essensoft.AspNetCore.Payment.UnionPay/Utility/UnionPaySignature.cs

@@ -141,12 +141,16 @@ namespace Essensoft.AspNetCore.Payment.UnionPay.Utility
         public static string GetSignContent(Dictionary<string, string> para, bool sort, bool encode)
         {
             if (para == null || para.Count == 0)
+            {
                 return string.Empty;
+            }
 
             var list = new List<string>(para.Keys);
 
             if (sort)
+            {
                 list.Sort(StringComparer.Ordinal);
+            }
 
             var sb = new StringBuilder();
             foreach (var key in list)
@@ -329,7 +333,9 @@ namespace Essensoft.AspNetCore.Payment.UnionPay.Utility
                 var tSplitStr = tDN.Substring(tDN.IndexOf("CN=")).Split("@".ToCharArray());
                 if (tSplitStr != null && tSplitStr.Length > 2
                         && tSplitStr[2] != null)
+                {
                     tPart = tSplitStr[2];
+                }
             }
             return tPart;
         }

+ 13 - 0
src/Essensoft.AspNetCore.Payment.UnionPay/Utility/UnionPayUtils.cs

@@ -24,14 +24,22 @@ namespace Essensoft.AspNetCore.Payment.UnionPay.Utility
             try
             {
                 if (Object == null || Convert.IsDBNull(Object))
+                {
                     return GetDefault(destinationType);
+                }
+
                 if ((Object as string) != null)
                 {
                     var ObjectValue = Object as string;
                     if (destinationType.IsEnum)
+                    {
                         return System.Enum.Parse(destinationType, ObjectValue, true);
+                    }
+
                     if (string.IsNullOrEmpty(ObjectValue))
+                    {
                         return GetDefault(destinationType);
+                    }
                 }
                 if ((Object as IConvertible) != null)
                 {
@@ -41,10 +49,15 @@ namespace Essensoft.AspNetCore.Payment.UnionPay.Utility
                     return Convert.ChangeType(Object, destination);
                 }
                 if (destinationType.IsAssignableFrom(Object.GetType()))
+                {
                     return Object;
+                }
+
                 var Converter = TypeDescriptor.GetConverter(Object.GetType());
                 if (Converter.CanConvertTo(destinationType))
+                {
                     return Converter.ConvertTo(Object, destinationType);
+                }
             }
             catch { }
             return GetDefault(destinationType);

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

@@ -5,9 +5,9 @@
     <Company>Essensoft</Company>
     <Authors>Roc</Authors>
     <Product>Payment</Product>
-    <Version>1.4.0</Version>
-    <AssemblyVersion>1.4.0.0</AssemblyVersion>
-    <FileVersion>1.4.0.0</FileVersion>
+    <Version>1.5.0</Version>
+    <AssemblyVersion>1.5.0.0</AssemblyVersion>
+    <FileVersion>1.5.0.0</FileVersion>
     <Description>ASP.NET Core Payment for WeChatPay.</Description>
     <Copyright>© Essensoft 2018</Copyright>
     <PackageProjectUrl>https://github.com/Essensoft/Payment</PackageProjectUrl>
@@ -18,7 +18,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" />
   </ItemGroup>
 
   <ItemGroup>

+ 10 - 0
src/Essensoft.AspNetCore.Payment.WeChatPay/Parser/WeChatPayXmlParser.cs

@@ -11,7 +11,9 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay.Parser
         public T Parse(string body)
         {
             if (string.IsNullOrEmpty(body))
+            {
                 throw new ArgumentNullException(nameof(body));
+            }
 
             T rsp = null;
             var parameters = new WeChatPayDictionary();
@@ -33,7 +35,9 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
             {
@@ -50,10 +54,14 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay.Parser
         public T Parse(string body, string data)
         {
             if (string.IsNullOrEmpty(body))
+            {
                 throw new ArgumentNullException(nameof(body));
+            }
 
             if (string.IsNullOrEmpty(data))
+            {
                 throw new ArgumentNullException(nameof(data));
+            }
 
             T rsp = null;
             var parameters = new WeChatPayDictionary();
@@ -84,7 +92,9 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay.Parser
             catch { }
 
             if (rsp == null)
+            {
                 rsp = Activator.CreateInstance<T>();
+            }
 
             if (rsp != null)
             {

+ 4 - 0
src/Essensoft.AspNetCore.Payment.WeChatPay/Utility/WeChatPaySignature.cs

@@ -12,7 +12,9 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay.Utility
             foreach (var iter in parameters)
             {
                 if (!string.IsNullOrEmpty(iter.Value) && iter.Key != "sign" && (excludeSignType ? iter.Key != "sign_type" : true))
+                {
                     sb.Append(iter.Key).Append('=').Append(iter.Value).Append("&");
+                }
             }
             var signContent = sb.Append("key=").Append(key).ToString();
             return signType ? MD5.Compute(signContent).ToUpper() : HMACSHA256.Compute(signContent, key).ToUpper();
@@ -24,7 +26,9 @@ namespace Essensoft.AspNetCore.Payment.WeChatPay.Utility
             foreach (var iter in parameters)
             {
                 if (!string.IsNullOrEmpty(iter.Value) && include.Contains(iter.Key))
+                {
                     sb.Append(iter.Key).Append('=').Append(iter.Value).Append("&");
+                }
             }
             var signContent = sb.Append("secret=").Append(secret).ToString();
             return MD5.Compute(signContent).ToUpper();