前言

最近在使用ASP.NET Core来进行开发,刚好有个接入支付宝支付的需求,百度了一下没找到相关的资料,看了官方的SDK以及Demo都还是.NET Framework的,所以就先根据官方SDK的源码,用.NET Standard 2.0 实现了支付宝服务端SDK,Alipay.AopSdk.Core(github:https://github.com/stulzq/Alipay.AopSdk.Core) ,支持.NET CORE 2.0。为了使用方便,已上传至Nuget可以直接使用。

支付宝有比较多的支付产品,比如当面付、APP支付、手机网站支付、电脑网站支付等,本次讲的是电脑网站支付。

如果你没有时间阅读文章,可以直接从github获取Demo原来进行查看,非常简单。github: https://github.com/stulzq/Alipay.Demo.PCPayment

创建项目

新建一个ASP.NET Core 2.0 MVC项目

配置

由于我在开发的时候支付接口并没有申请下来,所以使用的是支付宝沙箱环境来进行开发的。

支付宝沙箱环境介绍:蚂蚁沙箱环境(Beta)是协助开发者进行接口功能开发及主要功能联调的辅助环境。沙箱环境模拟了开放平台部分产品的主要功能和主要逻辑,在开发者应用上线审核前,开发者可以根据自身需求,先在沙箱环境中了解、组合和调试各种开放接口,进行开发调通工作,从而帮助开发者在应用上线审核完成后,能更快速、更顺利的进行线上调试和验收工作。

如果在签约或创建应用前想要进行集成测试,可以使用沙箱环境。

沙箱环境支持使用个人账号或企业账号登陆。

沙箱环境地址:https://openhome.alipay.com/platform/appDaily.htm?tab=info

1.生成密钥

这里所使用的RSA密钥标准为PKCS1,需要特别注意。

可以下载我写的密钥生成器:https://github.com/dotnetcore/Alipay.AopSdk.Core/tree/dev/tool

运行可以直接生成长度为2048标准为PKCS1的公钥和私钥。

或者使用下载支付宝官方提供的密钥生成工具来进行生,详细介绍:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1

2.设置应用公钥

我们生成密钥之后,需要到支付宝后台设置应用公钥,就是我们生成的公钥。

设置之后,支付宝会给我们一个支付宝公钥,保存这个支付宝公钥

这个支付宝公钥和我们自己生成的公钥是不一样的,我们在配置SDK时用的公钥就是支付宝公钥

3.配置SDK

新建一个Config类,在里面存储我们的配置。

public class Config
{
// 应用ID,您的APPID
public static string AppId = ""; // 支付宝网关
public static string Gatewayurl = ""; // 商户私钥,您的原始格式RSA私钥
public static string PrivateKey = ""; // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static string AlipayPublicKey = ""; // 签名方式
public static string SignType = "RSA2"; // 编码格式
public static string CharSet = "UTF-8";
}
  • 应用ID和支付宝网关都可以在支付宝后台查看。

  • 商户私钥即我们自己生成的私钥,公钥就是支付宝公钥这里一定要注意,别用错了。这里的公钥私钥直接填写字符串即可。

  • 签名方式推荐使用RSA2,使用RSA2,支付宝会用SHA256withRsa算法进行接口调用时的验签(不限制密钥长度)。

  • 编码格式,如果我们是直接配置的字符串(公钥、私钥),那么就是我们代码的编码,如果使用的是文件(公钥、私钥),那么就是文件的编码。

  • 完成配置如下:

添加SDK

官方SDK的源码(.NET Framework),用.NET Standard 2.0 实现的支付宝服务端SDK,Alipay.AopSdk.Core(github:https://github.com/stulzq/Alipay.AopSdk.Core) ,支持.NET Core 2.0。

通过Nuget安装:Install-Package Alipay.AopSdk.Core

支付

添加一个控制器 PayController

/// 发起支付请求
/// </summary>
/// <param name="tradeno">外部订单号,商户网站订单系统中唯一的订单号</param>
/// <param name="subject">订单名称</param>
/// <param name="totalAmout">付款金额</param>
/// <param name="itemBody">商品描述</param>
/// <returns></returns>
[HttpPost]
public void PayRequest(string tradeno,string subject,string totalAmout,string itemBody)
{
DefaultAopClient client = new DefaultAopClient(Config.Gatewayurl, Config.AppId, Config.PrivateKey, "json", "2.0",
Config.SignType, Config.AlipayPublicKey, Config.CharSet, false); // 组装业务参数model
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.Body = itemBody;
model.Subject = subject;
model.TotalAmount = totalAmout;
model.OutTradeNo = tradeno;
model.ProductCode = "FAST_INSTANT_TRADE_PAY"; AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
// 设置同步回调地址
request.SetReturnUrl("http://localhost:5000/Pay/Callback");
// 设置异步通知接收地址
request.SetNotifyUrl("");
// 将业务model载入到request
request.SetBizModel(model); var response = client.SdkExecute(request);
Console.WriteLine($"订单支付发起成功,订单号:{tradeno}");
//跳转支付宝支付
Response.Redirect(Config.Gatewayurl + "?" + response.Body);
}

运行:

  • 图1

  • 图2

  • 图3

支付异步回调通知

支付宝同步回调通知(支付成功后跳转到商户网站),是不可靠的,所以这里必须使用异步通知来获取支付结果,异步通知即支付宝主动请求我们提供的地址,我们根据请求数据来校验,获取支付结果。

/// <summary>
/// 支付异步回调通知 需配置域名 因为是支付宝主动post请求这个action 所以要通过域名访问或者公网ip
/// </summary>
public async void Notify()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
Dictionary<string, string> sArray = GetRequestPost();
if (sArray.Count != 0)
{
bool flag = AlipaySignature.RSACheckV1(sArray, Config.AlipayPublicKey,Config.CharSet, Config.SignType, false);
if (flag)
{
//交易状态
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序 //注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
Console.WriteLine(Request.Form["trade_status"]); await Response.WriteAsync("success");
}
else
{
await Response.WriteAsync("fail");
}
}
}

同步回调

同步回调即支付成功跳转回商户网站

运行:

/// <summary>
/// 支付同步回调
/// </summary>
[HttpGet]
public IActionResult Callback()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
Dictionary<string, string> sArray = GetRequestGet();
if (sArray.Count != 0)
{
bool flag = AlipaySignature.RSACheckV1(sArray, Config.AlipayPublicKey, Config.CharSet, Config.SignType, false);
if (flag)
{
Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证通过";
}
else
{
Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证失败";
}
}
return View();
}

订单查询

查询订单当前状态:已付款、未付款等等。

运行:

[HttpPost]
public JsonResult Query(string tradeno, string alipayTradeNo)
{
DefaultAopClient client = new DefaultAopClient(Config.Gatewayurl, Config.AppId, Config.PrivateKey, "json", "2.0",
Config.SignType, Config.AlipayPublicKey, Config.CharSet, false);
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.OutTradeNo = tradeno;
model.TradeNo = alipayTradeNo; AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.SetBizModel(model); var response = client.Execute(request);
return Json(response.Body);
}

订单退款

退回该订单金额。

运行:

/// <summary>
/// 订单退款
/// </summary>
/// <param name="tradeno">商户订单号</param>
/// <param name="alipayTradeNo">支付宝交易号</param>
/// <param name="refundAmount">退款金额</param>
/// <param name="refundReason">退款原因</param>
/// <param name="refundNo">退款单号</param>
/// <returns></returns>
[HttpPost]
public JsonResult Refund(string tradeno,string alipayTradeNo,string refundAmount,string refundReason,string refundNo)
{
DefaultAopClient client = new DefaultAopClient(Config.Gatewayurl, Config.AppId, Config.PrivateKey, "json", "2.0",
Config.SignType, Config.AlipayPublicKey, Config.CharSet, false); AlipayTradeRefundModel model = new AlipayTradeRefundModel();
model.OutTradeNo = tradeno;
model.TradeNo = alipayTradeNo;
model.RefundAmount = refundAmount;
model.RefundReason = refundReason;
model.OutRequestNo = refundNo; AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.SetBizModel(model); var response = client.Execute(request);
return Json(response.Body);
}

退款查询

查询退款信息。

运行:

/// <summary>
/// 退款查询
/// </summary>
/// <param name="tradeno">商户订单号</param>
/// <param name="alipayTradeNo">支付宝交易号</param>
/// <param name="refundNo">退款单号</param>
/// <returns></returns>
[HttpPost]
public JsonResult RefundQuery(string tradeno,string alipayTradeNo,string refundNo)
{
DefaultAopClient client = new DefaultAopClient(Config.Gatewayurl, Config.AppId, Config.PrivateKey, "json", "2.0",
Config.SignType, Config.AlipayPublicKey, Config.CharSet, false); if (string.IsNullOrEmpty(refundNo))
{
refundNo = tradeno;
} AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
model.OutTradeNo = tradeno;
model.TradeNo = alipayTradeNo;
model.OutRequestNo = refundNo; AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
request.SetBizModel(model); var response = client.Execute(request);
return Json(response.Body);
}

订单关闭

对一定时间以后没有进行付款的订单进行关闭,订单状态需为:待付款,已完成支付的订单无法关闭。

运行:

/// <summary>
/// 关闭订单
/// </summary>
/// <param name="tradeno">商户订单号</param>
/// <param name="alipayTradeNo">支付宝交易号</param>
/// <returns></returns>
[HttpPost]
public JsonResult OrderClose(string tradeno, string alipayTradeNo)
{
DefaultAopClient client = new DefaultAopClient(Config.Gatewayurl, Config.AppId, Config.PrivateKey, "json", "2.0",
Config.SignType, Config.AlipayPublicKey, Config.CharSet, false); AlipayTradeCloseModel model = new AlipayTradeCloseModel();
model.OutTradeNo = tradeno;
model.TradeNo = alipayTradeNo; AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
request.SetBizModel(model); var response = client.Execute(request);
return Json(response.Body);
}

地址集合

最重要的:

本文Demo:https://github.com/stulzq/Alipay.Demo.PCPayment

如果有问题欢迎提出!

ASP.NET Core 2.0 使用支付宝PC网站支付的更多相关文章

  1. ASP.NET Core 2.0 使用支付宝PC网站支付实现代码(转)

    最近在使用ASP.NET Core来进行开发,刚好有个接入支付宝支付的需求,百度了一下没找到相关的资料,看了官方的SDK以及Demo都还是.NET Framework的,所以就先根据官方SDK的源码, ...

  2. ASP.NET Core2.0 环境下MVC模式的支付宝PC网站支付接口-沙箱环境开发测试

    1.新建.NET Core web项目 2.Controllers-Models-Views 分三个大部分 3.下载安装最新sdk 官方的SDK以及Demo都还是.NET Framework的,根据官 ...

  3. asp.net core 2.0+sqlsugar搭建个人网站系列(0)

    一些废话 马上就要过年了,回顾这一年最大的收获就是技术有了很大的提升,其他的方面没有什么改变,现在还是单身小屌丝一枚. 这一年来学习的主要重点就是asp.net core,中间也使用 core+EF做 ...

  4. Java支付宝PC网站支付功能开发(详细教程)

    一.前言 本案例使用的是Java实现的.使用支付宝的沙盒环境示例.发布需要换成正式环境.这里就不作详细说明了 本代码适合用来做参考,不要直接复制去使用. 没有账号的需要去平台注册一个: 登录支付宝开发 ...

  5. ASP.NET Core 2.0 支付宝当面付之扫码支付

    前言 自从微软更换了CEO以后,微软的战略方向有了相当大的变化,不再是那么封闭,开源了许多东西,拥抱开源社区,.NET实现跨平台,收购xamarin并免费提供给开发者等等.我本人是很喜欢.net的,并 ...

  6. NET Core 2.0 使用支付宝

    ASP.NET Core 2.0 使用支付宝PC网站支付   前言 最近在使用ASP.NET Core来进行开发,刚好有个接入支付宝支付的需求,百度了一下没找到相关的资料,看了官方的SDK以及Demo ...

  7. MVC支付宝PC网站接口对接

    PC网站支付接口,请参考支付宝官方文档:https://b.alipay.com/signing/productSet.htm?navKey=all 1.需要提供签约账号.商户密钥 2.代码实现: 支 ...

  8. 支付宝PC网站接口对接

    PC网站支付接口,请参考支付宝官方文档:https://b.alipay.com/signing/productSet.htm?navKey=all 1.需要提供签约账号.商户密钥 2.代码实现: 支 ...

  9. [亲测]ASP.NET Core 2.0怎么发布/部署到Ubuntu Linux服务器并配置Nginx反向代理实现域名访问

    前言 ASP.NET Core 2.0 怎么发布到Ubuntu服务器?又如何在服务器上配置使用ASP.NET Core网站绑定到指定的域名,让外网用户可以访问呢? 步骤 第1步:准备工作 一台Liun ...

随机推荐

  1. 权限大全-linux基础

    一.文件权限 (1)文件的权限主要针对三类对象定义: u:属主,owner    g:属组,group    o:其他,other    权限有三种:    r:可读    w:可写    x:可执行 ...

  2. python+selenium自动化软件测试(第15章):基础实战(2)

    #coding:utf-8 #for windows/py2.7 from time import sleep from selenium import webdriver browser = web ...

  3. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  4. jQuery EasyUI弹出确认对话框(确认操作中.....)

    因为毕业设计的原因,在初期设计系统的时候没有考虑功能的正确性,所以很多的功能都没有加验证和确认的操作,给人在操作方面上有一些不好的感觉(可能失误点击后,数据就别删除,或者增加了),所以在网上找了一些资 ...

  5. Java基础学习 —— bat处理文件

    bat处理文件:就是一次性可以执行多个命令的文件 为什么要学bat处理文件? 快速运行一个软件我一般都会打包成jar包的形式来执行jar双击对图形界面管用 但是对控制台的程序是不起作用的.对于控制台的 ...

  6. 游戏平台代表--PS4【推荐】

    目前市上专业的游戏主机三足鼎立,分别是任天堂的wii,微软的xbox,已经索尼的PlayStation系列,这其中的老大当然是索尼PS4啦,因为即使美国佬也是优选ps4而不是自家的Xbox.小编历经千 ...

  7. 英语学习APP案例分析

    第一部分 调研, 评测 1.上手体验 界面简洁,有常规的词典翻译功能,针对四六级或考研的人有特别的"单词挑战"模块,以及针对口语训练的"我爱说英语"模块,多功能 ...

  8. java四则运算生成器

    题目描述: 从<构建之法>第一章的 "程序" 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 "软件",满足以下需求: 除 ...

  9. 201521123104《Java程序设计》第7周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 源代码如下: pu ...

  10. 201521123058 java第六次作业

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1.clone方法 1.1 Object对 ...