1.新建.NET Core web项目

2.Controllers-Models-Views 分三个大部分

3.下载安装最新sdk

官方的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下载安装,直接使用集成的SDK即可,道理和官网支付宝demo一个样。

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

4.首先要配置支付宝商户信息 在这里使用的是沙箱账号

新建一个配置类基本不用但是后续代码还是可以方便使用。

Config.cs

using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;namespace Alipay.PCPayment
{public class Config{// 应用ID,您的APPID 沙箱public static string AppId= "2016********3";/// <summary>/// 合作商户uid 沙箱/// </summary>public static string Uid= "208**********2";// 支付宝网关 沙箱地址public static string Gatewayurl="https://openapi.alipaydev.com/gateway.do";// 支付宝网关 生产地址// public static string Gatewayurl = "https://openapi.alipay.com/gateway.do";/// <summary>/// 异步通知 处理支付宝接口通知返回 获取是否是支付宝服务器发来的请求的验证结果/// </summary>/// <param name="notifyId">通知验证ID</param>/// <returns>验证结果</returns>public static async Task<string> VerifyNotifyAsync(string notifyId){return await SendAsync(Uid, notifyId);}/// <summary>///  //支付宝消息验证地址/// </summary>private const string API_URL = "https://mapi.alipay.com/gateway.do?service=notify_verify&";/// <summary>/// 获取是否是支付宝服务器发来的请求的验证结果/// </summary>/// <param name="partner">partner 合作身份ID</param>/// <param name="notify_id">通知验证ID</param>/// <returns>验证结果</returns>public static async Task<string> SendAsync(string partner, string notify_id){string strResult;string verifyUrl = API_URL + "partner=" + partner + "&notify_id=" + notify_id;//获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求try{using (var client = new HttpClient()){//client.Timeout = 120000;var response = await client.GetAsync(verifyUrl);if (response.IsSuccessStatusCode){byte[] data = await response.Content.ReadAsByteArrayAsync();Encoding.UTF8.GetString(data);return strResult= "true";}}}catch (Exception exp){strResult = "错误信息:" + exp.Message;}return string.Empty;} public static ContentResult Response_Success(string msg = null)        {            return new ContentResult            {                Content = msg ?? "success"            };        }        public static ContentResult ResponseFail(string msg = null)        {            return new ContentResult            {                Content = msg ?? "fail"            };        }
}}

5. 添加一个控制器 PayController

using System;
using System.Collections.Generic;
using Alipay.AopSdk.AspnetCore;
using Alipay.AopSdk.Core;
using Alipay.AopSdk.Core.Domain;
using Alipay.AopSdk.Core.Request;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Alipay.Demo.PCPayment.Interfaces;
using Microsoft.Extensions.Logging;
namespace Alipay.PCPayment.Controllers
{   /// <summary>/// PC网站支付/// </summary>public class PayController : Controller{private readonly IAlipayService _alipayService;private readonly IAccounts _IAccounts;private readonly ILogger _logger;public PayController(IAlipayService alipayService,  ILogger<PayController> logger){_alipayService = alipayService;_logger = logger;}//_alipayService.Execute();#region 发起支付public IActionResult Index(){return View();}/// <summary>/// 发起支付请求/// </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);// 组装业务参数modelAlipayTradePagePayModel model = new AlipayTradePagePayModel{Body = itemBody,Subject = subject,TotalAmount = totalAmout,OutTradeNo = tradeno,ProductCode = "FAST_INSTANT_TRADE_PAY"};AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();// 设置同步回调地址 可以是调试模式地址 并非公网或域名地址 Pay走的是控制器的request.SetReturnUrl("http://190.120.120.01:110/Pay/Callback");// 设置异步通知接收地址 必须是公网或域名地址 Pay走的是控制器的方法request.SetNotifyUrl("http://50.200.50.10:110/Pay/AlipayNotify");// 将业务model载入到request
            request.SetBizModel(model);var response = _alipayService.SdkExecute(request);Console.WriteLine($"订单支付发起成功,订单号:{tradeno}");//跳转支付宝支付 支付网关地址Response.Redirect(Config.Gatewayurl + "?" + response.Body);}#endregion支付异步回调通知 使用异步通知来获取支付结果,异步通知即支付宝主动请求我们提供的地址,我们根据请求数据来校验,获取支付结果。#region 支付异步回调通知/// <summary>/// 异步通知即支付宝主动请求我们提供的地址,我们根据请求数据来校验,获取支付结果。/// 支付异步回调通知 需配置域名 因为是支付宝主动post请求这个action 所以要通过域名访问或者公网ip/// </summary>//public  async Task<IActionResult> AlipayNotify([FromForm]Dictionary<string,string> NotifyArray)public async Task<IActionResult> AlipayNotify(){/* 实际验证过程建议商户添加以下校验。1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)*/Dictionary<string, string> NotifyArray = GetRequestPost();//通知验证IDstring notifyId = NotifyArray["notify_id"];try{ if (NotifyArray.Count != 0){   //验签以及验证合作伙伴IDbool flag = _alipayService.RSACheckV1(NotifyArray);if (await Config.VerifyNotifyAsync(notifyId) == "true" && flag){//交易状态if (NotifyArray["trade_status"] == "TRADE_FINISHED" ||NotifyArray["trade_status"] == "TRADE_SUCCESS"){if (NotifyArray["app_id"] == Config.AppId){  // 修改支付信息以及状态//return await UpdateAliPayAsyn(NotifyArray);
                        }}await Response.WriteAsync("success");}else{await Response.WriteAsync("fail");}}}catch (Exception e){_logger.LogError("Alipay notify fail, {0}", e);}return View();//string msg = null;//return new ContentResult//{//    Content = msg ?? "fail"//};
        }/// <summary>/// 更新支付宝支付结果信息/// 判断该笔订单是否已经做过处理///如果没有做过处理,根据订单号(out_trade_no)在商户的订单系统中查到该笔订单的详细,并执行商户的业务程序///请务必判断请求时的total_amount与通知时获取的total_fee为一致的///如果有做过处理,不执行商户的业务程序/// </summary>/// <param name="dict"></param>/// <returns></returns>//private async Task<ContentResult> UpdateAliPayAsyn(Dictionary<string, string> dict)//{//    //获取支付的订单号//    string msg = null;//    var orderNO = await accountsOrder.GetOrderAsync(dict["out_trade_no"]);//    if (orderNO == null || !accountsOrder.ReadyOrderStatus(orderNO))//    {//        _logger.LogInformation("充值订单号不存在");//       //        return new ContentResult//        {//            Content = msg ?? "fail"//        };//    }//    //if (!EqualAmountAliPay(order.PayPrice, dict["total_amount"]))//    //{//    //    return AliPay.ResponseFail("订单金额不匹配");//    //}//    更新订单支付通知结果//    //if (await accountsOrder.UpdateOrderAsync(order))//    //{//    //    await accountsOrder.SaveAliPayNotifyDataAsync(dict);//    //    _logger.LogInformation("[支付宝]支付成功,系统于 " + dtStartTime.ToString() + " 接收到请求,于 " + dict["notify_time"] + " 完成处理,交易流水号:" + dict["trade_no"] + ",交易单号:" + dict["out_trade_no"], "支付宝日志");//    //    return AliPay.ResponseSuccess();//    //}//    //else//    //{//    //    _logger.LogInformation("[支付宝]订单号:" + dict["out_trade_no"] + "状态:" + dict["trade_status"], "支付宝日志");//    //    if (dict["trade_status"] == "TRADE_CLOSED")//    //    {//    //        return AliPay.ResponseSuccess();//    //    }//    //    else//    //    {    //成功//    //        if (order.PayStatus == 1)//    //        {//    //            _logger.LogInformation("[支付宝]已支付过:" + order.RechargeOrderNO, "支付宝日志");//    //            return AliPay.ResponseSuccess();//    //        }//    //        else//    //        //等待支付//    //        {//    //            _logger.LogInformation("[支付宝]未支付:" + order.RechargeOrderNO, "支付宝日志");//    //            return AliPay.ResponseFail("等待支付");//    //        }//    //    }//        return new ContentResult//        {//            Content = msg ?? "fail"//        };//    }#endregion

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

        #region 支付同步回调/// <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 = _alipayService.RSACheckV1(sArray);if (flag){Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");ViewData["PayResult"] = "同步验证通过";Response.Redirect("http://190.120.120.01:110/");}else{Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");ViewData["PayResult"] = "同步验证失败";}}return View();}#endregion#region 解析请求参数private Dictionary<string, string> GetRequestGet(){Dictionary<string, string> sArray = new Dictionary<string, string>();ICollection<string> requestItem = Request.Query.Keys;foreach (var item in requestItem){sArray.Add(item, Request.Query[item]);}return sArray;}/// <summary>/// 获取返回的请求结果/// </summary>/// <returns></returns>private Dictionary<string, string> GetRequestPost(){Dictionary<string, string> sArray = new Dictionary<string, string>();ICollection<string> requestItem = Request.Form.Keys;foreach (var item in requestItem){sArray.Add(item, Request.Form[item]);}return sArray;}#endregion    }    }
}

7.支付订单信息页面

Index.cshtml 支付请求action POST

@{ViewData["Title"] = "PC网站支付";
}
<h2>PC网站支付</h2>
<div class="row"><div class="col-sm-12" s><form  asp-action="PayRequest" method="post" 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="subject" class="control-label col-sm-2">订单名称:</label><div class="col-sm-10"><input type="text" name="subject" class="form-control" id="subject" value="iPhone X" /></div></div><div class="form-group"><label for="totalAmout" class="control-label col-sm-2">付款金额:</label><div class="col-sm-10"><input type="number" min="0.01" name="totalAmout" class="form-control" id="totalAmout" value="99.99" /></div></div><div class="form-group"><label for="itemBody" class="control-label col-sm-2">商品描述:</label><div class="col-sm-10"><input type="text"  name="itemBody" class="form-control" id="itemBody" value="苹果手机" /></div></div><div class="form-group"><div class="col-sm-10 col-sm-offset-2"><button class="btn btn-success btn-block">付款</button><p class="help-block text-center">如果您点击“付款”按钮,即表示您同意该次的执行操作。</p></div></div></form></div></div><script>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>

8.配置系统启动项目信息

Startup.cs

public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){services.AddMvc();Console.WriteLine(Configuration["Alipay:AlipayPublicKey"]);services.AddAlipay(options =>{options.AlipayPublicKey = Configuration["Alipay:AlipayPublicKey"];options.AppId = Configuration["Alipay:AppId"];options.CharSet = Configuration["Alipay:CharSet"];options.Gatewayurl = Configuration["Alipay:Gatewayurl"];options.PrivateKey = Configuration["Alipay:PrivateKey"];options.SignType = Configuration["Alipay:SignType"];options.Uid = Configuration["Alipay:Uid"];}).AddAlipayF2F();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();app.UseBrowserLink();}else{app.UseExceptionHandler("/Home/Error");}app.UseStaticFiles();app.UseMvc(routes =>{routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");});}}

appsettings.json

{"Logging": {"IncludeScopes": false,"LogLevel": {"Default": "Error"}},"WriteTo": ["LiterateConsole",{"Name": "RollingFile","Args": { "pathFormat": "logs\\log-{Date}.txt" }}],"Alipay": {"AlipayPublicKey": "/fVCQx+B+++++HLB7K9yTNoBWBGsOsNpTiErj2wqdyOp8KVSp/5P1","AppId": "2016******03","CharSet": "UTF-8","Gatewayurl": "https://openapi.alipaydev.com/gateway.do","PrivateKey": "/eQ1ykzA5hecyw4K/+/pIFjLm/M/+/vj0gy+eqabgVUjyOLDuEc"\",": null,"SignType": "RSA2","Uid": "208********2"}
}

9、支付演示
支付请求页面

跳转到支付宝支付网关沙箱地址

拿起手机APP沙箱版的进行扫码支付 或者进行沙箱账号买家账户登录支付

支付成功提示页面

转载于:https://www.cnblogs.com/Warmsunshine/p/7904609.html

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

  1. 支付宝支付(2) 电脑网站支付(SpringBoot+沙箱环境+Alipay Easy SDK)

    一.前言 支付宝支付(1) 电脑网站支付(SpringBoot+沙箱环境) Alipay Easy SDK 文档 Alipay Easy -> https://github.com/alipay ...

  2. ASP.NET Core 2.0 使用支付宝PC网站支付

    概述 支付宝有比较多的支付产品,比如当面付.APP支付.手机网站支付.电脑网站支付等,本次讲的是电脑网站支付. 详细 代码下载:http://www.demodashi.com/demo/11730. ...

  3. 【SpringBoot深入浅出系列】SpringBoot之实现支付宝扫码支付(沙箱环境编码实现)

    目录 一.准备工作 1.应用 APPID 2.商户私钥,即应用私钥 3.支付宝公钥 4.签名方式 5.字符编码格式 6.支付宝网关 二.沙箱环境编码实现 1.项目说明 2.创建 Spring Init ...

  4. 支付宝支付(1) 电脑网站支付(SpringBoot+沙箱环境)

    一.前言 本文将基于 springboot+沙箱环境 来简单实现支付宝的电脑网站支付功能 二.获取所需配置参数信息 APPID 支付宝网关 支付宝公钥 RSA2私钥 登录支付宝 -> 研发服务 ...

  5. SpringBoot支付宝扫码支付(沙箱环境)

    目录 前言 一.起调代码如下: 1.1 config配置类信息 1.2 AlipayController层 1.3 AlipayService层 二.支付宝回调接口 2.1 AlipayCallbac ...

  6. 帧中继环境下NBMA模式的配置

    帧中继环境下NBMA模式的配置 1.  实验目的: 通过本次的实验,我们可以掌握如下技能 1)        帧中继静态映射及其broadcast参数的含义. 2)        NBMA模式下的DR ...

  7. springboot+调用支付宝第三方接口(沙箱环境)

    springboot+调用支付宝第三方接口(沙箱环境) 大神勿喷!! 网址:https://developers.alipay.com/platform/developerIndex.htm 沙箱环境 ...

  8. 调用支付宝第三方接口(沙箱环境) Spring Boot+Maven

    调用支付宝第三方接口(沙箱环境) Spring Boot+Maven 一.蚂蚁金服开放平台的操作 网址:https://open.alipay.com/platform/home.htm 支付宝扫码登 ...

  9. Python实现支付宝二维码支付(沙箱环境)

    Python实现支付宝二维码支付 一.沙箱环境配置 1.登陆蚂蚁金融开放平台:https://openhome.alipay.com 2.选择进入我的开放平台.寻找开发中心的研发服务. 3.点击沙箱环 ...

最新文章

  1. socket编程:多路复用I/O服务端客户端之poll
  2. 打开.264后缀名格式的文件
  3. 人工智能缺陷与误觉:让机器产生幻觉的「怪异事件」 1
  4. android wifi定位服务,如何在Android中使用Wifi获取位置?
  5. java jpanel 分层显示_java – 向JPanel显示视频
  6. 软件工程转计算机科学与技术,计算机与软件工程学院本科生转专业实施方案
  7. hash redis springboot_Redis常见的工作场景使用实战,Redisson分布式锁的实现
  8. Linux shell 内部命令与外部命令有什么区别以及怎么辨别
  9. 手机照片局部放大镜_手机摄影,竟然有3种对焦方式,想拍出专业水准,你必须了解...
  10. hduoj Stars 二维树状数组
  11. MySQL配置与启动
  12. 2006 年100 款最佳安全工具谱
  13. C语言库函数查找工具MSDN
  14. CXF学习创建WebService
  15. 25岁社招进阿里,从电商到有赞新零售,他仅1年就打开了马云一直想做的新领域!...
  16. javascript 知识点总结
  17. 宅男也可变形男-我是如何在11个月零27天减掉80斤的
  18. PPT 问题 PowerPoint 储存此文件时发生错误
  19. 【边做项目边学Android】手机安全卫士09-手机防盗界面设置向导1
  20. Selenium中的隐式等待和显式等待

热门文章

  1. python学习笔记(10)--组合数据类型(序列类型)
  2. jquery改变字符串中部分字符的颜色
  3. BZOJ 4517 组合数+错排
  4. phoengap–node+websocket在线聊天室
  5. windows phone画板程序
  6. Flex调用WebService后的数据处理
  7. python a and b_python-尽管Numpy建议a.b,为什么a.dot(b)比a @ b更...
  8. python tkinter实例_python绘制一个图形示例源码(tkinter)
  9. tcp wireshark 过滤syn_使用 WireShark 分析 TCP/IP 三次握手 和 四次挥手
  10. java nginx https_docker nginx 配置ssl,实现https