Asp.NET Core3.1接入支付宝的 手机网页版支付 接口,前端vue请求 后端使用core3.1做接口(超详细)

最近做大二商城项目时需要使用支付宝支付,就百度了一下支付宝支付的方法。发现七成以上是java的,.NET Core真的是寥寥无几,不禁感叹 .Net在中国真的那么少用吗?
现在开始准备开发吧
调用支付宝接口前需要做以下准备:
1.需要有蚂蚁金服申请的APPID
2.需要创建私钥与公钥

首先,我们先登录到 蚂蚁金服开发者平台 如下登录成功后的:
在这里插入图片描述因为我也不是企业账号,没有那个什么证书 没法申请签约在线支付,,所以我们使用下方的研发模式,也就是沙盒模式。
在这里插入图片描述现在我们来生成秘钥 ,在 文档 中输入 如何生成rsa:
在这里插入图片描述进入,点击 如何生成RSA2密钥 ,进入如下页面:
在这里插入图片描述下载对应操作系统的应用,下载完成 安装后(安装可能较慢,耐心等待)打开:

在这里插入图片描述现在我们打开生成的文件路径:
在这里插入图片描述回到开发者平台,现在我们开始上传秘钥与下载支付宝公钥,上一步有一个地方说错了,上传的应该是公钥,私钥是留在后面接口调用时使用的
在这里插入图片描述如果是第一次上传,一个只有一个设置,打开即可
在这里插入图片描述复制应用公钥是切记不要做其他输入操作,特别注意别不小心输入了一个空格什么的,必须是原封不动的复制粘贴

加签完成,打个码 寻求点心里安慰,哈哈哈哈
在这里插入图片描述在这里插入图片描述最好将应用秘钥和支付宝公钥放在一个文件夹里,好找
若有不明白,可以 查阅支付宝的接入文档 不明白就看文档(一个无奈的选择)

好的,选择支付宝这边的准备工作已经完成,现在我们开始接入支付接口
在这里我选择的是 Essensoft.AspNetCore.Payment 提供的开源方法,开源地址 想了解更多的同学可以下载他们的开源项目进行研究,里面的事例也很明白简洁,注释也写得很好,就是有些找不到(怪我眼瞎…)值得主要的是 他的开发环境配置文件在这个下面
在这里插入图片描述好了,回到正题
现在我们需要下载他们已经封装好的dll了,在浏览中搜索Essensoft.AspNetCore.Payment下载最新版的即可,这里有一个坑 大家注意下,当我们下载这个包的时候 就需要卸载掉支付宝的payment包,他们只能存在一个,不然调用支付接口时会报错 说方法指定不明确(我怀疑是他们的方法名一样,参数也一样 但是调用不明确,这个问题找了我一个多小时,差点想放弃)
在这里插入图片描述安装完成后,我们继续如下配置,我这里是配置开发环境,生产环境也是如此,只需要上线时做对应修改即可
在这里插入图片描述
对应填写即可 uid表示的是商户id,就是你进行收钱的地方。
注意AlipayPublicKey和AppPrivateKey 不能换行 不能换行 不能换行
AppPrivateKey就是生成的应用私钥
AlipayPublicKey是上面保存的支付宝公钥

 //阿里支付 配置
    "Alipay": {
      //此处为蚂蚁金服开放平台上创建的APPID,而非老版本的商户号
      "AppId": "",
      // 支付宝公钥
      "AlipayPublicKey": "",
      // 商户私钥
      "AppPrivateKey": "",
      "CharSet": "UTF-8",
      "Gatewayurl": "https://openapi.alipaydev.com/gateway.do",
      "ServerUrl": "https://openapi.alipaydev.com/gateway.do",
      "SignType": "RSA2",
      "Uid": ""
    }

下面来到Startup 进行支付宝的依赖注入

 // 添加支付宝客户端依赖注入
            // 引入Payment 依赖注入
            services.AddAlipay();
            //微信的
            //services.AddWeChatPay();
            var t = Configuration.GetSection("Alipay");
            // 在 appsettings.json(开发环境:appsettings.Development.json) 中 配置选项
            services.Configure<AlipayOptions>(Configuration.GetSection("Alipay"));
            //services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"))

然后我们创建如下控制器:
其实我只是进行了第一个的使用,余下两个需要接收支付宝的通知,因为内网穿透实在是太慢了,就没进行测试使用
在这里插入图片描述现在我们来到支付控制器
这是我的代码,请按照自己的项目修改,推荐先去下载研究一下这个开源项目 真的蛮好,里面还有很多其他的支付方式,并可支持最新的技术

仅做参考 后面有使用说明

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Essensoft.AspNetCore.Payment.Alipay;
using Essensoft.AspNetCore.Payment.Alipay.Domain;
using Essensoft.AspNetCore.Payment.Alipay.Request;
using MallApi.Helpers;
using MallApi.ModelHelper.OnlinePay;
using MallApi.Models;
using MallApi.ResultModel;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace MallApi.Controllers.OnlinePay
{
    [Microsoft.AspNetCore.Cors.EnableCors("any")]
    [Route("api/[controller]")]
   // [ServiceFilter(typeof(API.TokenFilter))]
    public class AlipayController : ControllerBase
    {
        private readonly IAlipayClient _client;
        private readonly IOptions<AlipayOptions> _optionsAccessor;

        public AlipayController(IAlipayClient client, IOptions<AlipayOptions> optionsAccessor)
        {
            _client = client;
            _optionsAccessor = optionsAccessor;
        }

        private readonly BaseResultModel models = new BaseResultModel();
        private readonly ShopappContext db = new ShopappContext();
        private readonly AliPayInfo aliPayInfo = new AliPayInfo();
        /// <summary>
        /// 电脑网站支付
        /// </summary>
        /// <param name="viewModel"></param>
        [HttpPost]
        [Route("pcPay")]
        public async Task<IActionResult> PagePay(AlipayTradePagePayViewModel viewModel)
        {
            var model = new AlipayTradePagePayModel
            {
                Body = viewModel.Body,
                Subject = viewModel.Subject,
                TotalAmount = viewModel.TotalAmount,
                OutTradeNo = viewModel.OutTradeNo,
                ProductCode = viewModel.ProductCode
            };
            AlipayTradePagePayRequest req = new AlipayTradePagePayRequest();
            req.SetBizModel(model);
            req.SetNotifyUrl(viewModel.NotifyUrl);
            req.SetReturnUrl(viewModel.ReturnUrl);
            var response = await _client.PageExecuteAsync(req, _optionsAccessor.Value);
            return Content(response.Body, "text/html", Encoding.UTF8);
        }
        /// <summary>
        /// 手机网站支付
        /// </summary>
        [HttpPost]
        [Route("appWebPay")]
        public async Task<IActionResult> WapPay(AlipayTradeWapPayViewModel viewMode)
        {
            try
            {
                //通过订单编号获得商品的标题
                SpOrder spOrder = db.SpOrder.FirstOrDefault(p => p.OrderNumber == viewMode.OutTradeNo && p.OrderPay == 0);
                if (spOrder == null)
                {
                    models.Code = 404;
                    models.msg = "订单不存在或已支付";
                    return Ok(models);
                }
                SpOrderGoods spOrderGoods = db.SpOrderGoods.FirstOrDefault(p => p.OrderId == spOrder.OrderId);
                SpGoodsInf spGoodsInf = db.SpGoodsInf.FirstOrDefault(p => p.GoodsId == spOrderGoods.GoodsId );
                if (spGoodsInf == null)
                {
                    models.Code = 404;
                    models.msg = "该商品不存在或已下架";
                    return Ok(models);
                }
                AlipayTradeWapPayModel model = new AlipayTradeWapPayModel
                {
                    Body = viewMode.Body,
                    Subject = spGoodsInf.GoodsName,
                    TotalAmount = viewMode.TotalAmount,
                    OutTradeNo = viewMode.OutTradeNo.Trim(),
                    ProductCode = viewMode.ProductCode,
                    QuitUrl= "http://www.hj0819.top:8081/#/order/1",
                };
                var req = new AlipayTradeWapPayRequest();
                req.SetBizModel(model);
                //支付宝服务器主动通知商户服务器里指定的页面http/https路径。 
                // req.SetNotifyUrl("http:///www.hj0819.top:4436/alipay/notify/wappay");
                //可实现支付成功后跳转到商家页面的功能,而且跳转后的return_url页面的地址栏中会返回同步通知参数。
                 req.SetReturnUrl("http://www.hj0819.top:8081/#/aliPayIsok");
                
                var response = await _client.PageExecuteAsync(req, _optionsAccessor.Value);
                if (response.IsError)
                {
                    //错误时
                    models.Code = 203;
                    models.msg = "支付宝对接错误:"+response.Msg;
                }
                models.Code = 201;
                models.msg = "支付宝对接成功";
                models.data = response.Body;
                return Ok(models);
            }
            catch (Exception e)
            {
                models.Code = 519;
                models.msg = "发生内部错误:" + e.Message;
                return Ok(models);
                throw;
            }
           
        }
        /// <summary>
        /// 交易查询
        /// </summary>
        [HttpPost]
        [Route("ExecuteAliPay")]
        public async Task<IActionResult> ExecuteAsync(AlipayTradeQueryViewModel viewMode)
        {
            //判断该笔订单是否被支付
            SpOrder spOrder = db.SpOrder.FirstOrDefault(p => p.OrderNumber == viewMode.OutTradeNo.Trim() && p.OrderPay == 0);
            if (spOrder == null)
            {
                models.Code = 200;
                models.msg = "订单被支付";
                models.data = spOrder;
                return Ok(models);
            }
            var model = new AlipayTradeQueryModel
            {
                OutTradeNo = viewMode.OutTradeNo.Trim(),
                TradeNo = viewMode.TradeNo
            };

            var req = new AlipayTradeQueryRequest();
            req.SetBizModel(model);
            var response = await _client.ExecuteAsync(req, _optionsAccessor.Value);
            //转换为json
            JObject jos = (JObject)JsonConvert.DeserializeObject(((AlipayResponse)response).Body);
            string aliPay = jos["alipay_trade_query_response"].ToString();
            JObject jo = (JObject)JsonConvert.DeserializeObject(aliPay);
            string code = jo["code"].ToString();
            
            //解析信息
            if(code != "10000")
            {
                //一般错误为 交易不存在
                models.Code = 202;
                models.msg = jo["sub_msg"].ToString();
                return Ok(models);
            }
            //解析支付宝的交易流水
            string trade_no = jo["trade_no"].ToString();
            return Ok(aliPayInfo.PayOrder(viewMode.OutTradeNo, trade_no));
            
        }

    }
}

使用说明:
在这里插入图片描述在这里插入图片描述成功请求,支付宝给我们返回一个表单(html代码),response.Body中,,我们后端只需要将这个返回给前端即可。
好的,现在我们后端的支付请求已经基本结束了,现在我们切换到前端做处理。
我前端是用vue做的
直接看代码

//进行后端请求
this.$api.onlinePay
        .appWebPay({
        //直接的订单编号
          OutTradeNo: this.order_num,
          Subject: "手机网站支付测试",
          //这里的请求方式是固定的 手机网站支付方式
          ProductCode: "QUICK_WAP_WAY",
          body: "手机网站支付描述信息",
          //价格
          TotalAmount: this.payOrder.goodsPrice
        })
        .then(res => {
          loading.close();
          if (res.data.code === 201) {
            //返回的是一个表单
            //我们需要创建一个新的页面 将代码展示上去,然后点击表单的提交按钮,这样就可以跳转到支付宝的支付页面了 可以选择唤起支付宝支付和进行网页支付
            //有一个注意点 沙盒模式,必须使用沙盒账号进行支付,普通账号会支付失败
            this.html = res.data.data;
            var form = res.data.data;
            const div = document.createElement("div");
            div.innerHTML = form; //此处form就是后台返回接收到的数据
            document.body.appendChild(div);
            //进行表单提交 跳转
            document.forms[0].submit();
          } else {
            return this.$message.error(res.data.msg);
          }
        })
        .catch(err => {
          loading.close();
          return this.$message.error("服务器连接异常");
        });

到此,我们的支付已经完成了,,,要想知道怎么获得支付状态,可以选择异步或同步,我没完成,,就选择了手动查询,进行在支付宝支付完成后跳转到一个页面 页面有一个按钮 用来向后端发送一个请求,查询是否支付成功 ,
前端的请求如下:
注意 当OutTradeNo和TradeNo同时存在时,支付宝将优先选择使用TradeNo

// 查询支付状态
    payCode() {
      const loading = this.$loading({
        lock: true,
        text: "支付结果查询中....",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)"
      });
      this.$api.onlinePay
        .ExecuteAliPay({
        //自己的订单编号(存在自己数据库中的)
          OutTradeNo: this.order_num,
          //阿里云返回的交易流水 因为我们没有,所有选择为空
          TradeNo: ""
        })
        .then(res => {
          loading.close();
          if (res.data.code === 201) {
            Toast.success(res.data.msg);
          } else {
            Toast.fail(res.data.msg);
          }
        })
        .catch(err => {
          loading.close();
          Toast.fail("服务器连接异常");
        });
    },

后端的如下:

 /// <summary>
        /// 交易查询
        /// </summary>
        [HttpPost]
        [Route("ExecuteAliPay")]
        public async Task<IActionResult> ExecuteAsync(AlipayTradeQueryViewModel viewMode)
        {
            //判断该笔订单是否被支付
            SpOrder spOrder = db.SpOrder.FirstOrDefault(p => p.OrderNumber == viewMode.OutTradeNo.Trim() && p.OrderPay == 0);
            if (spOrder == null)
            {
                models.Code = 200;
                models.msg = "订单被支付";
                models.data = spOrder;
                return Ok(models);
            }
            var model = new AlipayTradeQueryModel
            {
                OutTradeNo = viewMode.OutTradeNo.Trim(),
                TradeNo = viewMode.TradeNo
            };

            var req = new AlipayTradeQueryRequest();
            req.SetBizModel(model);
            var response = await _client.ExecuteAsync(req, _optionsAccessor.Value);
            //转换为json
            JObject jos = (JObject)JsonConvert.DeserializeObject(((AlipayResponse)response).Body);
            string aliPay = jos["alipay_trade_query_response"].ToString();
            JObject jo = (JObject)JsonConvert.DeserializeObject(aliPay);
            string code = jo["code"].ToString();
            
            //解析信息
            if(code != "10000")
            {
                //一般错误为 交易不存在
                models.Code = 202;
                models.msg = jo["sub_msg"].ToString();
                return Ok(models);
            }
            //code == "10000" 表示支付成功
            //解析支付宝的交易流水
			//以下就可以进行自己的业务处理了
            string trade_no = jo["trade_no"].ToString();
            return Ok(aliPayInfo.PayOrder(viewMode.OutTradeNo, trade_no));
            
        }

好了,到这里已经结束啦,,,谢谢你的阅读
若有错误,还望海涵 也请指正
若有用语不当影响了阅读 在此表示抱歉

猜你喜欢

转载自blog.csdn.net/weixin_44517477/article/details/107242610