站点图标 江湖人士

ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

这篇文章将介绍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

退出移动版