.NET Core2.0 环境下MVC模式的支付宝扫码支付接口-沙箱环境开发测试

2023-05-16

所有配置以及相关信息均可以从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;width: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
    }
}  

 生成二维码支付界面:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET Core2.0 环境下MVC模式的支付宝扫码支付接口-沙箱环境开发测试 的相关文章

  • HTTP, WWW-Authenticate, Authorization 验证授权 | Apache验证 | Python处理

    2019独角兽企业重金招聘Python工程师标准 gt gt gt HTTP验证 有时你访问网页时会碰到这种情况 xff1a 这种方式是基于HTTP协议的一种验证方式 xff0c 这里可以参考HTTP协议的具体解释 xff1a http w
  • 虚拟化(KVM)

    虚拟化介绍 VMware Workstation就是虚拟化 虚拟化简单讲 xff0c 就是把一台物理计算机虚拟成多台逻辑计算机 xff0c 每个逻辑计算机里面可以运行不同的操作系统 xff0c 相互不受影响 xff0c 这样就可以充分利用硬
  • 头文件中的(全局)变量只能放声明,不能定义

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 头文件中的变量只能声明 xff0c 不能定义 xff0c 否则其他多个 c文件包含该头文件 xff0c 出现重复定义 xff0c 导致链接出错 ifndef define
  • 程序启动时的堆栈

    程序启动时 xff0c Linux把4种类型的信息存放到程序堆栈中 xff1a xff08 1 xff09 命令行参数 xff08 包括程序名称 xff09 的数目 xff08 2 xff09 从shell提示符执行的程序的名称 xff08
  • suse linux双网卡双网关配置

    公司有台SUSE LINUX服务器需要用到2个网络 xff0c 一个网段是192的 xff0c 用来上OP管理平台系统 一个是B网络 xff0c 网段是202的 xff0c 用来上外网 我们都知道一台电脑拥有两个网关是不可能的 xff0c
  • 统计学中抽样比例一般占百分之多少

    要具体问题具体分析 一般和要求的误差限 置信区间及总体方差有关系 比如最基本的简单随机抽样 其样本量确定公式就是1 n 61 1 N 43 d 2 u 2 S 2 样本量和误差限成反比 和置信区间及总体方差成正比 请问一堆url怎么算方差
  • emqtt 试用(二)验证 emq 和 mosquito 的共享订阅

    本地订阅 Local Subscription 本地订阅 Local Subscription 只在本节点创建订阅与路由表 xff0c 不会在集群节点间广播全局路由 xff0c 非常适合物联网数据采集应用 使用方式 订阅者在主题 Topic
  • spring security实现动态配置url权限的两种方法

    缘起 标准的RABC 权限需要支持动态配置 xff0c spring security默认是在代码里约定好权限 xff0c 真实的业务场景通常需要可以支持动态配置角色访问权限 xff0c 即在运行时去配置url对应的访问角色 基于sprin
  • 干货!2018年你值得一看的网页设计作品集赏析

    网页设计作品集 61 门面 43 能力 网页设计作品集对网页设计师而言 xff0c 既是网页门面 xff0c 也是个人专业素养的体现 那么在作品集设计上万不能掉以轻心 无论是制作一份简约大方还是极具表现力的精良作品集 xff0c 设计师们都
  • ElasticSearch在原索引基础上添加字段和修改字段

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 业务场景 xff1a 现在的系统设计不满足业务需求时就需要升级服务 xff0c 为了满足业务需求有时需要对ES中 字段进行添加或修改操作 xff0c 接下来我们查看为 ma
  • echarts中关于字体设置的配置

    1 legend字体大小的配置 2 x轴和y轴上的刻度值的字体大小的配置 3 visualMap的字体大小的配置 4 饼状图上的文字大小的配置 其对应的是 转载于 https blog 51cto com 11871779 2401302
  • 堡垒机 jumpserver

    堡垒机介绍 在一个特定网络环境下 xff0c 为了保障网络和数据不受外界入侵和破坏 xff0c 而运用各种技术手段实时收集和监控网络环境中每一个组成部分的系统状态 安全事件 网络活动 xff0c 以便集中报警 及时处理及审计定责 我们又把堡
  • vim替换命令

    在VIM中进行文本替换 xff1a 1 替换当前行中的内容 xff1a s from to xff08 s即substitude xff09 s from to xff1a 将当前行中的第一个from xff0c 替换成to 如果当前行含有
  • xxxxxxxxxxxxxxxxxxxxxxxxxxxx

    Get Authorization code Request https accounts google com o oauth2 v2 auth redirect uri 61 https 3A 2F 2Fdevelopers googl
  • linux 系统密码忘记后的 5 种方法【转】

    如果你既没做系统启动软盘 xff0c 同时多系统的引导LILO 和GRUB 又被删除 xff0c 那么只能使用Linux 系统安装盘来恢复root的密码 xff0c 步骤如下 一 lilo引导在出现 lilo 提示时键入 linux sin
  • 理解程序内存

    内存对很多人来说感觉是个很熟悉的东西 xff0c 因为我们在用VC调试程序时 xff0c 很多时候都会察看内存中变量的值 但是 xff0c 很多时候我们的思维也就因此局限在有源码的模块 xff0c 当遇到一些跨模块或是没有源代码的Bug x
  • 内核调试

    转载一篇文章 xff1a http my oschina net fgq611 blog 113249 linux内核调试方法总结 1 二分法与printk AB之间有个bug xff0c 在AB之间找个中间点C xff0c 使用print
  • 提供一个免费的CSDN下载账号

    账号 xff1a windforce05 password xff1a w12345678 请下载了资源后评价一下资源 xff0c 以便赚回分数
  • 答读者问(7):相关实习、在软件开发和测试等论文和关系问题

    最近收到一个研究生朋友的电子邮件 xff0c 让我想起自己毕业前 xff0c 我们已经有很多的疑惑 xff0c 人谁想要的答案 互联网不仅是我们最好的老师 同一时候也是最好的桥梁 我们都要感谢并善于利用它 闲话不说 xff0c 言归正传 邮
  • 安装完office2016 64位后,在安装visio时,报错,无法安装,

    安装环境要求 xff1a 系统要求 xff1a win8 win10等 xff1b office要求 xff1a sw 批量版 不能和cn xff08 零售版 xff09 365版混装 重点注意事项一定要注意批量版和零售版的区别 xff0c

随机推荐

  • tex中把参考文献标题删除

    如果是book类 lt br gt renewcommand bibname lt br gt 如果是article类 lt br gt renewcommand refname
  • 德州扑克AI--Programming Poker AI(译)

    前言 最近在研究德州扑克的AI 也想由浅入深的看下 在网上找了一圈 发现很多文章都提到了一篇文章 Programming Poker AI 仔细拜读了一下 觉得非常不错 这里作下简单的翻译工作 可能加些自己的一些理解 权当做一回大自然的搬运
  • centos7优化内核参数详解

    一 Sysctl命令用来配置与显示在 proc sys目录中的内核参数 xff0e 如果想使参数长期保存 xff0c 可以通过编辑 etc sysctl conf文件来实现 命令格式 xff1a sysctl n e w variable
  • 50行代码实现3D模拟真实撒金币动效

    我们将会用50行不到的代码来实现一个3D模拟撒金币动效 你只需要一点Egret基础就能够快速上手 xff0c 如果你不了解Egret xff0c 这里有一篇3分钟创建hello world来带你快速入门 实现效果 源码和在线demo 完整的
  • 微信小程序之——自定义分享按钮(完整版)

    声明 onShareAppMessage 函数 onShareAppMessage return title 39 弹出分享时显示的分享标题 39 desc 39 分享页面的内容 39 path 39 page user id 61 123
  • SQL Server developer和enterprise有什么区别?以及各个版本的定义

    1 Enterprise 作为高级版本 xff0c SQL Server Enterprise 版提供了全面的高端数据中心功能 xff0c 性能极为快捷 虚拟化不受限制 xff0c 还具有端到端的商业智能 xff0c 可为关键任务工作负荷提
  • java 图形界面---字体的设置

    Java绘图中 xff0c 显示文字的方法主要有三种 xff1a xff08 1 xff09 drawString String str int x int y xff1a 在指定的位置显示字符串 xff08 2 xff09 drawCha
  • "不能为虚拟电脑 ubuntu 打开一个新任务"的解决办法

    使用virtualbox报错 xff1a 不能为虚拟电脑 ubuntu3 打开一个新任务 The virtual machine 39 ubuntu3 39 has terminated unexpectedly during startu
  • 获取当前程序所在路径/目录

    char path buffer MAX PATH char drive MAX DRIVE char dir MAX DIR char fname MAX FNAME char ext MAX EXT GetModuleFileName
  • 理解Windows内核模式与用户模式

    内核层次架构 windows程序运行分为内核模式和用户模式 xff0c 内核模式可以访问所有的内存地址空间 xff0c 并且可以访问所有的CPU指令 一般程序运行在用户模式 xff0c 通过系统调用切换到内核模式执行系统功能 xff0c W
  • 自定义加数字

    每一位同时加 lt html gt lt head gt lt meta name 61 34 generator 34 content 61 34 HTML Tidy for HTML5 experimental for Windows
  • 使用C++ REST SDK开发简单的Web(HTTP)服务

    C 43 43 REST SDK是微软开源的一套客户端 服务器通信库 xff0c 提供了URI构造 解析 xff0c JSON编解码 xff0c HTTP客户端 HTTP服务端 xff0c WebSocket客户端 xff0c 流式传输 x
  • 头文件 INTRINS.H 的用法

    KEIL中头文件INTRINS H的作用 在C51单片机编程中 xff0c 头文件INTRINS H的函数使用起来 xff0c 就会让你像在用汇编时一样简便 内部函数 描述 crol 字符循环左移 cror 字符循环右移 irol 整数循环
  • 数模转换模块PCF8591

    介绍 有些传感器的输出值有模拟值 xff0c 这样的数值是不可读的 xff0c 如果想要把这些模拟值变为可读的 xff0c 就必须要用到数模转化模块 PCF8591是一个单片集成 单独供电 低功耗 8 bit CMOS数据获取器件 PCF8
  • 香橙派Orangepi Zero2控制舵机转动

    通过香橙派输出PWM波控制舵机 xff0c 首先需要了解Linux的定时器功能 xff0c 通过配置定时器产生PWM波 xff1a 218条消息 Linux时间函数与定时器简介 xff2c xff2a xff38 的博客 CSDN博客 1
  • UDP Linux编程(客户端&服务器端)

    服务器端 服务器不用绑定地址 xff0c 他只需要进行绑定相应的监听端口即可 include lt sys types h gt include lt sys socket h gt include lt pthread h gt incl
  • Visual Studio 与 Visual C++ 关系

    Visual Studio netVisual C 43 43 netVisual C 43 43 MSC VER备注Visual Studio net 2002Visual C 43 43 net 2002Visual C 43 43 7
  • C语言之基本算法08—去掉最高分去掉最低分求平均值

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • MySQL -- Fast Index Creation

    1 fast index creation简介 MySQL5 5之后 xff0c 对innodb表创建或删除辅助索引的效率提升了很多 xff0c 即增加了新的功能fast index creation 因为MySQL5 5之后 xff0c
  • .NET Core2.0 环境下MVC模式的支付宝扫码支付接口-沙箱环境开发测试

    所有配置以及相关信息均可以从PC支付中获取 使用的生成二维码的组件名为QRCoder xff0c 该组件引用了一个第三方实现的System Drawing类库 xff0c 和支付宝官网类似 当面付SDK为Alipay AopSdk F2FP