zoukankan      html  css  js  c++  java
  • .NET Core2.0 环境下MVC模式的支付宝扫码支付接口-沙箱环境开发测试

    所有配置以及相关信息均可以从PC支付中获取

    使用的生成二维码的组件名为QRCoder,该组件引用了一个第三方实现的System.Drawing类库,和支付宝官网类似

    当面付SDK为Alipay.AopSdk.F2FPay 直接使用Nuget工具下载安装即可

    view 中的Scan.cshtml页面代码:

    @{
        ViewData["Title"] = "扫码支付";
    }
    
    <div class="row">
        <div class="col-sm-12">
            <h1>扫码支付</h1>
            
            <form class="form-horizontal" role="form">
                <div class="form-group">
                    <label for="tradeno" class="control-label col-sm-2">商户订单号:</label>
                    <div class="col-sm-10">
                        <input type="text" name="tradeno" class="form-control" id="tradeno" value="" />
                    </div>
                </div>
    
                <div class="form-group">
                    <label for="orderName" class="control-label col-sm-2">订单名称:</label>
                    <div class="col-sm-10">
                        <input type="text" name="orderName" class="form-control" id="orderName" value="iPhone X" />
                    </div>
                </div>
                
                <div class="form-group">
                    <label for="orderAmount" class="control-label col-sm-2">付款金额:</label>
                    <div class="col-sm-10">
                        <input type="number" max="9.99" name="orderAmount" class="form-control" id="orderAmount" value="9.99" />
                    </div>
                </div>
    
                <div class="form-group">
                    <div class="col-sm-10 col-sm-offset-2">
                        <button class="btn btn-success btn-block" type="button" id="btnGen" onclick="GenCode()" >生成二维码</button>
                        <p class="help-block text-center">支付结果将显示在返回信息中,需要启用异步通知请使用公网ip或者域名等。</p>
                        <p class="help-block text-center">生产环境建议通过轮询加异步通知的方式保证支付结果,本页面若要在支付成功后自动跳转建议使用SignalR来实现</p>
                    </div>
    
                </div>
            </form>
        </div>
        
        <div class="col-sm-12" s>
            <form class="form-horizontal" role="form">
                <div class="form-group">
                    <label for="tradeno" class="control-label col-sm-2">二维码:</label>
                    <div class="col-sm-10">
                        <img id="imgqrcode" style="height:255px;249px;"/>
                    </div>
                </div>
    
            </form>
        </div>
    </div>
    
    @section Scripts{ 
        
        <script>
            function GenCode() {
                $("#imgqrcode").attr("src",
                    "/FTFPay/ScanCodeGen?orderName=" +
                    $("#orderName").val() +
                    "&orderAmount=" +
                    $("#orderAmount").val() +
                    "&outTradeNo=" +
                    $("#tradeno").val() +
                    "&rand=" +
                    new Date().getTime());
            }
    
            function GetDateNow() {
                var vNow = new Date();
                var sNow = "";
                sNow += String(vNow.getFullYear());
                sNow += String(vNow.getMonth() + 1);
                sNow += String(vNow.getDate());
                sNow += String(vNow.getHours());
                sNow += String(vNow.getMinutes());
                sNow += String(vNow.getSeconds());
                sNow += String(vNow.getMilliseconds());
                document.getElementById("tradeno").value =  sNow;
            }
            GetDateNow();
        </script>
    }


    此代码:

     

    controllers: FTFPayController.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.DrawingCore;
    using System.DrawingCore.Imaging;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Alipay.AopSdk.F2FPay.AspnetCore;
    using Alipay.AopSdk.F2FPay.Business;
    using Alipay.AopSdk.F2FPay.Domain;
    using Alipay.AopSdk.F2FPay.Model;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using QRCoder;
    
    namespace Alipay.PCPayment.Controllers
    {
        /// <summary>
        /// 扫码支付
        /// </summary>
        public class FTFPayController : Controller
        {
            private readonly IAlipayF2FService _alipayF2FService;
            private readonly IHostingEnvironment _hostingEnvironment;
            public FTFPayController(IHostingEnvironment hostingEnvironment, IAlipayF2FService alipayF2FService)
            {
                _hostingEnvironment = hostingEnvironment;
                _alipayF2FService = alipayF2FService;
            }
            public IActionResult Index()
            {
                return View();
            }
    
    
            #region 扫码支付
    
            public IActionResult Scan()
            {
                return View();
            }
    
            /// <summary>
            /// 生成支付二维码
            /// </summary>
            /// <param name="orderName">订单名称</param>
            /// <param name="orderAmount">订单金额</param>
            /// <param name="outTradeNo">订单号</param>
            /// <returns></returns>
            [HttpGet]
            public IActionResult ScanCodeGen(string orderName, string orderAmount, string outTradeNo)
            {
    
                AlipayTradePrecreateContentBuilder builder = BuildPrecreateContent(orderName, orderAmount, outTradeNo);
    
                //如果需要接收扫码支付异步通知,那么请把下面两行注释代替本行。
                //推荐使用轮询撤销机制,不推荐使用异步通知,避免单边账问题发生。
                AlipayF2FPrecreateResult precreateResult = _alipayF2FService.TradePrecreate(builder);
                //string notify_url = "http://10.5.21.14/Pay/Notify";  //商户接收异步通知的地址
                //AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder, notify_url);
    
                //以下返回结果的处理供参考。
                //payResponse.QrCode即二维码对于的链接
                //将链接用二维码工具生成二维码打印出来,顾客可以用支付宝钱包扫码支付。
                var bitmap = new Bitmap(Path.Combine(_hostingEnvironment.WebRootPath, "images/error.png"));
                switch (precreateResult.Status)
                {
                    case ResultEnum.SUCCESS:
                        bitmap.Dispose();
                        bitmap = RenderQrCode(precreateResult.response.QrCode);
                        //轮询订单结果
                        //根据业务需要,选择是否新起线程进行轮询
                        ParameterizedThreadStart parStart = new ParameterizedThreadStart(LoopQuery);
                        Thread myThread = new Thread(parStart);
                        object o = precreateResult.response.OutTradeNo;
                        myThread.Start(o);
                        break;
                    case ResultEnum.FAILED:
                        Console.WriteLine("生成二维码失败:" + precreateResult.response.Body);
                       // return Config.ResponseFail("生成二维码失败:" + precreateResult.response.Body);
                        break;
    
                    case ResultEnum.UNKNOWN:
                       // return Config.ResponseFail("生成二维码失败:" + (precreateResult.response == null ? "配置或网络异常,请检查后重试" : "系统异常,请更新外部订单后重新发起请求"));
                        Console.WriteLine("生成二维码失败:" + (precreateResult.response == null ? "配置或网络异常,请检查后重试" : "系统异常,请更新外部订单后重新发起请求"));
                        break;
                }
                MemoryStream ms = new MemoryStream();
                bitmap.Save(ms, ImageFormat.Png);
                byte[] bytes = ms.GetBuffer();
                return File(bytes, "image/png");
            }
    
    
            /// <summary>
            /// 构造支付请求数据
            /// </summary>
            /// <param name="orderName">订单名称</param>
            /// <param name="orderAmount">订单金额</param>
            /// <param name="outTradeNo">订单编号</param>
            /// <returns>请求结果集</returns>
            private AlipayTradePrecreateContentBuilder BuildPrecreateContent(string orderName, string orderAmount, string outTradeNo)
            {
                //线上联调时,请输入真实的外部订单号。
                if (string.IsNullOrEmpty(outTradeNo))
                {
                    outTradeNo = System.DateTime.Now.ToString("yyyyMMddHHmmss") + "0000" + (new Random()).Next(1, 10000).ToString();
                }
    
                AlipayTradePrecreateContentBuilder builder = new AlipayTradePrecreateContentBuilder();
                //收款账号
                builder.seller_id = Config.Uid;
                //订单编号
                builder.out_trade_no = outTradeNo;
                //订单总金额
                builder.total_amount = orderAmount;
                //参与优惠计算的金额
                //builder.discountable_amount = "";
                //不参与优惠计算的金额
                //builder.undiscountable_amount = "";
                //订单名称
                builder.subject = orderName;
                //自定义超时时间
                builder.timeout_express = "5m";
                //订单描述
                builder.body = "";
                //门店编号,很重要的参数,可以用作之后的营销
                builder.store_id = "test store id";
                //操作员编号,很重要的参数,可以用作之后的营销
                builder.operator_id = "test";
    
                //传入商品信息详情
                List<GoodsInfo> gList = new List<GoodsInfo>();
                GoodsInfo goods = new GoodsInfo();
                goods.goods_id = "goods id";
                goods.goods_name = "goods name";
                goods.price = "9.99";
                goods.quantity = "1";
                gList.Add(goods);
                builder.goods_detail = gList;
    
                //系统商接入可以填此参数用作返佣
                //ExtendParams exParam = new ExtendParams();
                //exParam.sysServiceProviderId = "20880000000000";
                //builder.extendParams = exParam;
    
                return builder;
    
            }
    
            /// <summary>
            /// 渲染二维码
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            private Bitmap RenderQrCode(string str)
            {
                QRCodeGenerator.ECCLevel eccLevel = QRCodeGenerator.ECCLevel.L;
                using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
                {
                    using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(str, eccLevel))
                    {
                        using (QRCode qrCode = new QRCode(qrCodeData))
                        {
    
                            Bitmap bp = qrCode.GetGraphic(20, Color.Black, Color.White,
                                new Bitmap(Path.Combine(_hostingEnvironment.WebRootPath, "images/alipay.png")), 15);
                            return bp;
                        }
                    }
                }
    
            }
    
            /// <summary>
            /// 轮询支付结果
            /// </summary>
            /// <param name="o">订单号</param>
            public void LoopQuery(object o)
            {
                AlipayF2FQueryResult queryResult = new AlipayF2FQueryResult();
                int count = 100;
                int interval = 10000;
                string outTradeNo = o.ToString();
    
                for (int i = 1; i <= count; i++)
                {
                    Thread.Sleep(interval);
                    queryResult = _alipayF2FService.TradeQuery(outTradeNo);
                    if (queryResult?.Status == ResultEnum.SUCCESS)
                    {
                        DoSuccessProcess(queryResult);
                        return;
                    }
                }
                DoFailedProcess(queryResult);
            }
    
            /// <summary>
            /// 请添加支付成功后的处理
            /// </summary>
            private ContentResult  DoSuccessProcess(AlipayF2FQueryResult queryResult)
            {
                //支付成功,请更新相应单据
                return Config.Response_Success("扫码支付成功:商户订单号 " + queryResult.response.OutTradeNo);
                //Console.WriteLine("扫码支付成功:商户订单号 " + queryResult.response.OutTradeNo);
    
            }
            /// <summary>
            /// 请添加支付成功后的处理 控制台的输出结果信息
            /// </summary>
            private void DoSuccess_Process(AlipayF2FQueryResult queryResult)
            {
                //支付成功,请更新相应单据
                
                Console.WriteLine("扫码支付成功:商户订单号 " + queryResult.response.OutTradeNo);
    
            }
            /// <summary>
            /// 请添加支付失败后的处理
            /// </summary>
            private ContentResult DoFailedProcess(AlipayF2FQueryResult queryResult)
            {
                //支付失败,请更新相应单据
                return Config.Response_Success("扫码支付成功:商户订单号 " + queryResult.response.OutTradeNo);
                
                // Console.WriteLine("扫码支付失败:商户订单号 " + queryResult.response.OutTradeNo);
            }
            /// <summary>
            /// 请添加支付失败后的处理 控制台的输出信息
            /// </summary>
            private void DoFailed_Process(AlipayF2FQueryResult queryResult)
            {
                //支付失败,请更新相应单据
               
                 Console.WriteLine("扫码支付失败:商户订单号 " + queryResult.response.OutTradeNo);
            }
            #endregion
        }
    }

     生成二维码支付界面:

    用沙箱版支付宝测试扫码支付 扫一扫即可支付,在这里发现扫码反应效果有点慢

  • 相关阅读:
    人月神话 读书笔记01
    团队项目个人每日总结(4.26)
    团队项目个人每日总结(4.25)
    团队项目个人每日总结(4.24)
    百度的用户体验
    团队项目个人每日总结(4.23)
    用户场景描述
    团队项目个人每日总结(4.22)
    团队项目个人每日总结(4.21)
    构建之法阅读笔记03
  • 原文地址:https://www.cnblogs.com/Warmsunshine/p/7920751.html
Copyright © 2011-2022 走看看