这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入支付宝-电脑网页支付接口及同步跳转及异步通知功能。
开发环境:Win 10 x64、VS2017 15.6.4、.NET Core SDK 2.1.101、.NET Core Runtime 2.0.6
1.新建”ASP.NET Core Web 应用程序”项目,我将它命名为AlipaySample.
2. 引入安装Nuget包 “Essensoft.AspNetCore.Alipay”. 目前(2018/03/23)版本为 1.1.0
3. 在Startup.cs文件内 添加依赖注入、设置参数(蚂蚁金服开放平台 – 账户管理 – 密钥管理 – 开放平台密钥)
代码:
1 public void ConfigureServices(IServiceCollection services) 2 { 3 services.AddMvc(); 4 5 // 添加支付宝客户端依赖注入 6 services.AddAlipay(); 7 8 // 可在添加依赖注入时设置参数 一般设置 AppId、RsaPrivateKey、RsaPublicKey,其余默认即可. 9 // 如: 10 //services.AddAlipay(opt => 11 //{ 12 // //此处为蚂蚁金服开放平台上创建的APPID,而非老版本的商户号 13 // opt.AppId = ""; 14 15 // // 这里的公私钥 默认均为支付宝官方推荐使用的RSAWithSHA256. 16 // // 商户私钥 17 // opt.RsaPrivateKey = ""; 18 // // 支付宝公钥 19 // opt.RsaPublicKey = ""; 20 //}); 21 22 // 具体参数见 AlipayOptions 23 24 // 注册配置实例 25 services.Configure<AlipayOptions>(Configuration.GetSection("Alipay")); 26 27 // 两种方式设置注册配置实例参数 28 29 // 1.默认配置文件(开发环境/正式环境): 30 // appsettings.Development.json / appsettings.json 31 32 // 2.用户机密配置文件(VS2017 15.6.4 中,右键项目 => 管理用户机密): 33 // Windows: % APPDATA %microsoftUserSecrets< userSecretsId >secrets.json 34 // Linux: ~/.microsoft / usersecrets /< userSecretsId >/ secrets.json 35 // macOS: ~/.microsoft / usersecrets /< userSecretsId >/ secrets.json 36 37 // 配置文件内容如下('...'为省略的项目其他配置内容,若有的情况下 -_-!): 38 39 //{ 40 // ... 41 // ... 42 // 43 // "Alipay": { 44 // "AppId": "", 45 // "RsaPublicKey": "", 46 // "RsaPrivateKey": "" 47 // } 48 //} 49 }
4. 添加一个控制器, 我将其命名为 AlipayController.cs
代码:
1 using Essensoft.AspNetCore.Alipay; 2 using Essensoft.AspNetCore.Alipay.Domain; 3 using Essensoft.AspNetCore.Alipay.Notify; 4 using Essensoft.AspNetCore.Alipay.Request; 5 using Microsoft.AspNetCore.Mvc; 6 using System.Threading.Tasks; 7 8 namespace AlipaySample.Controllers 9 { 10 public class AlipayController : Controller 11 { 12 // 支付宝请求客户端(用于处理请求与其响应) 13 private readonly AlipayClient _client = null; 14 15 // 支付宝通知客户端(用于解析异步通知或同步跳转) 16 private readonly AlipayNotifyClient _notifyClient = null; 17 18 // 赋值依赖注入对象 19 public AlipayController(AlipayClient client, AlipayNotifyClient notifyClient) 20 { 21 _client = client; 22 _notifyClient = notifyClient; 23 } 24 25 [HttpPost] 26 public async Task<IActionResult> PagePay(string out_trade_no, string subject, string total_amount, string body, string product_code, string notify_url, string return_url) 27 { 28 // 组装模型 29 var model = new AlipayTradePagePayModel() 30 { 31 Body = body, 32 Subject = subject, 33 TotalAmount = total_amount, 34 OutTradeNo = out_trade_no, 35 ProductCode = product_code, 36 }; 37 38 var req = new AlipayTradePagePayRequest(); 39 40 // 设置请求参数 41 req.SetBizModel(model); 42 43 // 设置异步通知URL 44 req.SetNotifyUrl(notify_url); 45 46 // 设置同步跳转URL 47 req.SetReturnUrl(return_url); 48 49 // 页面请求处理 传入 'GET' 返回的 response.Body 为 URL, 'POST' 返回的 response.Body 为 HTML. 50 var response = await _client.PageExecuteAsync(req, null, "GET"); 51 52 // 重定向到支付宝电脑网页支付页面. 53 return Redirect(response.Body); 54 } 55 56 /// <summary> 57 /// 电脑网页支付-同步跳转 58 /// 常用于展示订单支付状态页,建议在异步通知统一做业务处理,而不是在此处. 59 /// </summary> 60 /// <returns></returns> 61 [HttpGet] 62 public async Task<IActionResult> PagePayReturn() 63 { 64 try 65 { 66 // 以 AlipayTradePagePayReturnResponse 类型 解析 67 var notify = await _notifyClient.ExecuteAsync<AlipayTradePagePayReturnResponse>(Request); 68 return Content("成功:" + notify.OutTradeNo); 69 } 70 catch 71 { 72 return Content("参数异常/验签失败"); 73 } 74 } 75 76 /// <summary> 77 /// 电脑网页支付-异步通知 78 /// 常用于订单业务处理 79 /// </summary> 80 /// <returns></returns> 81 [HttpPost] 82 public async Task<IActionResult> PagePayNotify() 83 { 84 try 85 { 86 // 以 AlipayTradePagePayNotifyResponse 类型 解析 87 var notify = await _notifyClient.ExecuteAsync<AlipayTradePagePayNotifyResponse>(Request); 88 if ("TRADE_SUCCESS" == notify.TradeStatus) // 订单是否交易完成 89 { 90 // 业务代码 91 // ... 92 // ... 93 94 //返回给支付宝成功内容,停止继续通知 95 return Content("success", "text/plain"); 96 } 97 // 订单其他状态均返回给支付宝空内容. 98 return NoContent(); 99 } 100 catch 101 { 102 // 参数异常/验签失败均返回给支付宝空内容. 103 return NoContent(); 104 } 105 } 106 } 107 }
5. 修改 Views/Home/Index 页面,用于网站提交支付请求.
代码:
1 @{ 2 ViewData["Title"] = "Home Page"; 3 } 4 5 <div style="padding:24px 0"> 6 <h3>支付宝 电脑网站支付 - <a href="https://docs.open.alipay.com/270/alipay.trade.page.pay" target="_blank">API文档</a></h3> 7 <hr /> 8 <form asp-controller="Alipay" asp-action="PagePay" target="_blank"> 9 <div class="form-group"> 10 <label>body:</label> 11 <input type="text" class="form-control" name="body" value="支付宝网站支付测试详情"> 12 </div> 13 <div class="form-group"> 14 <label>subject:</label> 15 <input type="text" class="form-control" name="subject" value="支付宝网站支付测试"> 16 </div> 17 <div class="form-group"> 18 <label>total_amount:</label> 19 <input type="text" class="form-control" name="total_amount" value="0.01"> 20 </div> 21 <div class="form-group"> 22 <label>out_trade_no:</label> 23 <input type="text" class="form-control" name="out_trade_no" value="@DateTime.Now.ToString("yyyyMMddHHmmssfff")"> 24 </div> 25 <div class="form-group"> 26 <label>product_code:</label> 27 <input type="text" class="form-control" name="product_code" value="FAST_INSTANT_TRADE_PAY"> 28 </div> 29 <div class="form-group"> 30 <label>notify_url(通知Url需外网环境可访问):</label> 31 <input type="text" class="form-control" name="notify_url" value="http://xxx.com/alipay/pagepaynotify"> 32 </div> 33 <div class="form-group"> 34 <label>return_url:</label> 35 <input type="text" class="form-control" name="return_url" value="http://xxx.com/alipay/pagepayreturn"> 36 </div> 37 <button type="submit" class="btn btn-primary">提交</button> 38 </form> 39 </div>
实现页面如下:
有疑问可以在 https://github.com/Essensoft/Payment 提交Issue