瀏覽代碼

新增 H5下单API

Roc 5 年之前
父節點
當前提交
e5d7452b51

+ 39 - 1
samples/WebApplicationSample/Controllers/WeChatPayController.cs

@@ -214,7 +214,8 @@ namespace WebApplicationSample.Controllers
             var response = await _client.ExecuteAsync(request, _optionsAccessor.Value);
 
             // mweb_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,mweb_url的有效期为5分钟。
-            return Redirect(response.MwebUrl);
+            ViewData["response"] = response.Body;
+            return View();
         }
 
         /// <summary>
@@ -738,5 +739,42 @@ namespace WebApplicationSample.Controllers
             ViewData["response"] = response.Body;
             return View();
         }
+
+        /// <summary>
+        /// H5支付-H5下单API
+        /// </summary>
+        [HttpGet]
+        public IActionResult H5PayV3()
+        {
+            return View();
+        }
+
+        /// <summary>
+        /// H5支付-H5下单API
+        /// </summary>
+        /// <param name="viewModel"></param>
+        [HttpPost]
+        public async Task<IActionResult> H5PayV3(WeChatPayH5PayV3ViewModel viewModel)
+        {
+            var model = new WeChatPayTransactionsH5Model
+            {
+                AppId = _optionsAccessor.Value.AppId,
+                MchId = _optionsAccessor.Value.MchId,
+                Amount = new Amount { Total = viewModel.Total, Currency = "CNY" },
+                Description = viewModel.Description,
+                NotifyUrl = viewModel.NotifyUrl,
+                OutTradeNo = viewModel.OutTradeNo,
+                SceneInfo = new SceneInfo { PayerClientIp = "127.0.0.1" }
+            };
+
+            var request = new WeChatPayTransactionsH5Request();
+            request.SetBizModel(model);
+
+            var response = await _client.ExecuteAsync(request, _optionsAccessor.Value);
+
+            // h5_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,h5_url的有效期为5分钟。
+            ViewData["response"] = response.Body;
+            return View();
+        }
     }
 }

+ 19 - 0
samples/WebApplicationSample/Models/WeChatPayViewModel.cs

@@ -393,4 +393,23 @@ namespace WebApplicationSample.Models
         [Display(Name = "notify_url")]
         public string NotifyUrl { get; set; }
     }
+
+    public class WeChatPayH5PayV3ViewModel
+    {
+        [Required]
+        [Display(Name = "out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        [Required]
+        [Display(Name = "description")]
+        public string Description { get; set; }
+
+        [Required]
+        [Display(Name = "total")]
+        public int Total { get; set; }
+
+        [Required]
+        [Display(Name = "notify_url")]
+        public string NotifyUrl { get; set; }
+    }
 }

+ 45 - 0
samples/WebApplicationSample/Views/WeChatPay/H5PayV3.cshtml

@@ -0,0 +1,45 @@
+@model WeChatPayH5PayV3ViewModel
+@{
+    ViewData["Title"] = "H5支付-H5下单API";
+}
+<nav aria-label="breadcrumb">
+    <ol class="breadcrumb">
+        <li class="breadcrumb-item"><a asp-controller="WeChatPay" 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="WeChatPay" asp-action="H5PayV3">
+            <div asp-validation-summary="All" class="text-danger"></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="Description"></label>
+                <input type="text" class="form-control" asp-for="Description" value="微信H5支付测试" />
+            </div>
+            <div class="form-group">
+                <label asp-for="Total"></label>
+                <input type="text" class="form-control" asp-for="Total" value="1">
+            </div>
+            <div class="form-group">
+                <label asp-for="NotifyUrl"></label>
+                <input type="text" class="form-control" asp-for="NotifyUrl" value="http://*/notify/wechatpay/v3/transactions">
+            </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"); }
+}

+ 6 - 0
samples/WebApplicationSample/Views/WeChatPay/Index.cshtml

@@ -150,5 +150,11 @@
             <td><a href="https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transactions/chapter3_3.shtml" target="_blank">https://api.mch.weixin.qq.com/v3/pay/transactions/native</a></td>
             <td><a asp-controller="WeChatPay" asp-action="QrCodePayV3">立即测试</a></td>
         </tr>
+        <tr>
+            <th scope="row">23</th>
+            <td>H5支付-H5下单</td>
+            <td><a href="https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transactions/chapter3_4.shtml" target="_blank">https://api.mch.weixin.qq.com/v3/pay/transactions/h5</a></td>
+            <td><a asp-controller="WeChatPay" asp-action="H5PayV3">立即测试</a></td>
+        </tr>
     </tbody>
 </table>

+ 99 - 0
src/Essensoft.AspNetCore.Payment.WeChatPay/Domain/WeChatPayTransactionsH5Model.cs

@@ -0,0 +1,99 @@
+using System.Text.Json.Serialization;
+
+namespace Essensoft.AspNetCore.Payment.WeChatPay.Domain
+{
+    /// <summary>
+    /// H5下单API-请求参数
+    /// 最新更新时间:2020.05.26
+    /// https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transactions/chapter3_4.shtml
+    /// </summary>
+    public class WeChatPayTransactionsH5Model : WeChatPayObject
+    {
+        /// <summary>
+        /// 公众号ID
+        /// 直连商户申请的公众号或移动应用appid。
+        /// 示例值:wxd678efh567hg6787
+        /// </summary>
+        [JsonPropertyName("appid")]
+        public string AppId { get; set; }
+
+        /// <summary>
+        /// 直连商户号
+        /// 直连商户的商户号,由微信支付生成并下发。
+        /// 示例值:1230000109
+        /// </summary>
+        [JsonPropertyName("mchid")]
+        public string MchId { get; set; }
+
+        /// <summary>
+        /// 商品描述
+        /// 商品描述
+        /// 示例值:Image形象店-深圳腾大-QQ公仔
+        /// </summary>
+        [JsonPropertyName("description")]
+        public string Description { get; set; }
+
+        /// <summary>
+        /// 商户订单号
+        /// 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一,详见【商户订单号】。
+        /// 特殊规则:最小字符长度为6
+        /// 示例值:1217752501201407033233368018
+        /// </summary>
+        [JsonPropertyName("out_trade_no")]
+        public string OutTradeNo { get; set; }
+
+        /// <summary>
+        /// 交易结束时间
+        /// 订单失效时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒。
+        /// 示例值:2018-06-08T10:34:56+08:00
+        /// </summary>
+        [JsonPropertyName("time_expire")]
+        public string TimeExpire { get; set; }
+
+        /// <summary>
+        /// 附加数据
+        /// 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
+        /// 示例值:自定义数据
+        /// </summary>
+        [JsonPropertyName("attach")]
+        public string Attach { get; set; }
+
+        /// <summary>
+        /// 通知地址
+        /// 通知URL必须为直接可访问的URL,不允许携带查询串。
+        /// 格式:URL
+        /// 示例值:https://www.weixin.qq.com/wxpay/pay.php
+        /// </summary>
+        [JsonPropertyName("notify_url")]
+        public string NotifyUrl { get; set; }
+
+        /// <summary>
+        /// 订单优惠标记
+        /// 订单优惠标记
+        /// 示例值:WXG
+        /// </summary>
+        [JsonPropertyName("goods_tag")]
+        public string GoodsTag { get; set; }
+
+        /// <summary>
+        /// 订单金额
+        /// 订单金额信息
+        /// </summary>
+        [JsonPropertyName("amount")]
+        public Amount Amount { get; set; }
+
+        /// <summary>
+        /// 优惠功能
+        /// 优惠功能
+        /// </summary>
+        [JsonPropertyName("detail")]
+        public Detail Detail { get; set; }
+
+        /// <summary>
+        /// 场景信息
+        /// 支付场景描述
+        /// </summary>
+        [JsonPropertyName("scene_info")]
+        public SceneInfo SceneInfo { get; set; }
+    }
+}

+ 29 - 0
src/Essensoft.AspNetCore.Payment.WeChatPay/Request/WeChatPayTransactionsH5Request.cs

@@ -0,0 +1,29 @@
+using Essensoft.AspNetCore.Payment.WeChatPay.Response;
+
+namespace Essensoft.AspNetCore.Payment.WeChatPay.Request
+{
+    /// <summary>
+    /// H5下单API
+    /// 最新更新时间:2020.05.26
+    /// https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transactions/chapter3_4.shtml
+    /// </summary>
+    public class WeChatPayTransactionsH5Request : IWeChatPayV3PostRequest<WeChatPayTransactionsH5Response>
+    {
+        private WeChatPayObject bizModel;
+
+        public string GetRequestUrl()
+        {
+            return "https://api.mch.weixin.qq.com/v3/pay/transactions/h5";
+        }
+
+        public WeChatPayObject GetBizModel()
+        {
+            return bizModel;
+        }
+
+        public void SetBizModel(WeChatPayObject bizModel)
+        {
+            this.bizModel = bizModel;
+        }
+    }
+}

+ 20 - 0
src/Essensoft.AspNetCore.Payment.WeChatPay/Response/WeChatPayTransactionsH5Response.cs

@@ -0,0 +1,20 @@
+using System.Text.Json.Serialization;
+
+namespace Essensoft.AspNetCore.Payment.WeChatPay.Response
+{
+    /// <summary>
+    /// H5下单API-返回参数
+    /// 最新更新时间:2020.05.26
+    /// https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transactions/chapter3_4.shtml
+    /// </summary>
+    public class WeChatPayTransactionsH5Response : WeChatPayV3Response
+    {
+        /// <summary>
+        /// 支付跳转链接
+        /// h5_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,h5_url的有效期为5分钟。
+        /// 示例值:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx2016121516420242444321ca0631331346&package=1405458241
+        /// </summary>
+        [JsonPropertyName("h5_url")]
+        public string H5Url { get; set; }
+    }
+}