.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;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") + "" + (new Random()).Next(, ).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 = "";
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(, Color.Black, Color.White,
new Bitmap(Path.Combine(_hostingEnvironment.WebRootPath, "images/alipay.png")), );
return bp;
}
}
} } /// <summary>
/// 轮询支付结果
/// </summary>
/// <param name="o">订单号</param>
public void LoopQuery(object o)
{
AlipayF2FQueryResult queryResult = new AlipayF2FQueryResult();
int count = ;
int interval = ;
string outTradeNo = o.ToString(); for (int i = ; 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
}
}
生成二维码支付界面:
用沙箱版支付宝测试扫码支付 扫一扫即可支付,在这里发现扫码反应效果有点慢
.NET Core2.0 环境下MVC模式的支付宝扫码支付接口-沙箱环境开发测试的更多相关文章
- ASP.NET Core2.0 环境下MVC模式的支付宝PC网站支付接口-沙箱环境开发测试
1.新建.NET Core web项目 2.Controllers-Models-Views 分三个大部分 3.下载安装最新sdk 官方的SDK以及Demo都还是.NET Framework的,根据官 ...
- Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...
- .NET MVC结构框架下的微信扫码支付模式二 API接口开发测试
直接上干货 ,我们的宗旨就是为人民服务.授人以鱼不如授人以渔.不吹毛求疵.不浮夸.不虚伪.不忽悠.一切都是为了社会共同进步,繁荣昌盛,小程序猿.大程序猿.老程序猿还是嫩程序猿,希望这个社会不要太急功近 ...
- thinkphp5.0 微信扫码支付模式二
仅供个人参考,方便大家. 一.1)https://pay.weixin.qq.com/index.php/core/home/login 复制此地址 打开微信商户平台. 2)下载安全操作证书(最好在 ...
- ASP.NET Core 2.0 支付宝当面付之扫码支付
前言 自从微软更换了CEO以后,微软的战略方向有了相当大的变化,不再是那么封闭,开源了许多东西,拥抱开源社区,.NET实现跨平台,收购xamarin并免费提供给开发者等等.我本人是很喜欢.net的,并 ...
- 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付
微信支付教程系列之扫码支付 今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...
- Net MVC微信扫码支付
微信扫码支付+Asp.Net MVC 这里的扫码支付指的是PC网站上面使用微信支付,也就是官方的模式二,网站是Asp.net MVC,整理如下. 一.准备工作 使用的微信API中的统一下单方法,关键的 ...
- JAVA微信扫码支付模式二功能实现完整例子
概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...
- Java之微信支付(扫码支付模式二)案例实战
摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...
随机推荐
- 【解决问题】failed: java.lang.RuntimeException: org.openqa.selenium.WebDriverException: Unexpected error launching Internet Explorer.
failed: java.lang.RuntimeException: org.openqa.selenium.WebDriverException: Unexpected error launchi ...
- iOS 关于 GIF 图片那点事
前言 前几天我们项目组的群里提了这么一件事情:在我们的应用中存储动态的GIF图到相册,保存的图片变成了静态图片.而微博则能正确保存,可见这并不是一个技术不可实现的.前不久刚好看了苹果关于ImageIO ...
- jquery 滑动取值
JavaScript 滑动条效果 jquery 滚动条插件 仿iphone苹果横行滚动条美化样式商品图片展示
- C语言学习笔记 (001) - 常量指针与指针常量的区别(转帖)
三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量 ...
- mariadb/mysql配置允许远程访问方式
首先配置允许访问的用户,采用授权的方式给用户权限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY '123456' WITH GRANT ...
- POJ 3207 Ikki's Story IV - Panda's Trick (2-sat)
Ikki's Story IV - Panda's Trick Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 6691 ...
- Xcode dSYM 文件
1.什么是 dSYM 文件 Xcode 编译项目后,我们会看到一个同名的 dSYM 文件,dSYM 是保存 16 进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,并且 ...
- 《JAVA与模式》之访问者模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...
- sql改写or 改成union不等价数据变多
select count(*) from (SELECT A.* FROM (SELECT CD.*, nvl(CV.SUM_CI_BALANCE, 0) as SUM_CI_BALANCE, nvl ...
- asp.net与C# path.GetFullPath 获取上级目录
string path = new directoryinfo("../").fullname;//当前应用程序路径的上级目录 获取当前目录可以使用appdomain.curren ...