隐藏

.net core 3.1 webapi调用支付宝支付接口以及回调函数

发布:2022/7/1 13:32:00作者:管理员 来源:本站 浏览次数:1326

1使用场景在APP(是APP,不是其他,网页或者其他调用方式不同)中内集成支付宝支付


2去支付平台申请一个APPID(唯一标识) ,商家账号(PID,没有就自己申请一个)


3下载一个支付宝开放平台开发助手(其他的也行,只有能生成公钥私钥),生成公钥和私钥(私钥不能泄露),然后上传公钥生成支付宝公钥


应用公钥:商户自己生成的RSA公钥(与应用私钥必须匹配,生成的时候注意是java版本还是其他版本),需要将这个公钥上传到开发平台,验证是否是商户发起的,支付宝会生成对应的公钥。


应用私钥:商户自己生成RSA私钥(与应用公钥必须匹配,不能泄露),使用私钥对请求字符串加密


支付宝公钥:商户使用该公钥验证该结果是否是支付宝返回的


4服务端.net core webapi) sdk,用nuget包管理(也可以去支付宝官网下载https://docs.open.alipay.com/54/106370/)


5设置相关类

复制代码


   /// <summary>

   /// 调用阿里支付接口参数设置

   /// </summary>

   public class AlipayConfig

   {

       /// <summary>

       /// 发起请求的应用ID。沙箱与线上不同,请更换代码中配置;

       /// </summary>

       public string AppId { get; set; }


       /// <summary>

       /// 用于支付宝账户登录授权业务的入参 pid

       /// </summary>

       public string PId { get; set; }


       /// <summary>

       /// 支付宝私匙

       /// </summary>

       public string PrivateKey { get; set; }


       /// <summary>

       /// 应用公钥

       /// </summary>

       public string Publickey { get; set; }


       /// <summary>

       /// 支付宝公匙

       /// </summary>

       public string AlipayPublicKey { get; set; }


       /// <summary>

       ///  服务器异步通知路径

       /// </summary>

       public string notify_url { get; set; }


       /// <summary>

       ///  公匙类型/签名类型

       /// </summary>

       public string SignType { get; set; }


       /// <summary>

       ///  编码格式

       /// </summary>

       public string CharSet { get; set; }


       /// <summary>

       /// 向支付宝发起请求的网关。沙箱与线上不同,请更换代码中配置;沙箱:https://openapi.alipaydev.com/gateway.do上线https://openapi.alipay.com/gateway.do

       /// </summary>

       public string GatewayUrl { get; set; }


       /// <summary>

       /// 调用的接口版本

       /// </summary>

       public string Version { get; set; }


       /// <summary>

       /// 仅支持JSON

       /// </summary>

       public string Format { get; set; }


       public bool KeyFromFile { get; set; }

   }


复制代码


这些都是必填的,在appsetting中读取

复制代码


"Alipay": {

   "AppId": "申请的appid","PId": "商户id","PrivateKey": "私钥","Publickey": "公钥",

   "AlipayPublicKey": "阿里公钥",

   "notify_url": "回调函数地址",

   "SignType": "RSA2",

   "CharSet": "UTF-8",

   "GatewayUrl": "https://openapi.alipay.com/gateway.do",

   "Version": "2.0",

   "Format": "json",

   "KeyFromFile": false

 }        /// <summary>


复制代码


6 在startup注入


var alipay = Configuration.GetSection("Alipay");

services.Configure<AlipayConfig>(alipay);


7 在业务逻辑层

复制代码


public class OrderService : IOrderService, IBaseService

   {

       private readonly IAopClient _client;

       private readonly AlipayConfig _alipayConfig;public OrderService(IOptionsMonitor<AlipayConfig> alipayConfig)

       {

           _alipayConfig = alipayConfig.CurrentValue;

           _client = new DefaultAopClient(_alipayConfig.GatewayUrl, _alipayConfig.AppId, _alipayConfig.PrivateKey, _alipayConfig.Format, _alipayConfig.Version, _alipayConfig.SignType, _alipayConfig.AlipayPublicKey, _alipayConfig.CharSet, _alipayConfig.KeyFromFile);

       }


       /// <summary>

       /// 支付宝统一下单

       /// </summary>

       /// <param name="price"></param>

       /// <param name="orderNumber"></param>

       /// <returns></returns>

       public async Task<string> AliOrderAsync(int price, string orderNumber)

       {

           //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。

           // 组装业务参数model

           AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

           //订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000],必选

           model.TotalAmount = (price).ToString();

           //商品的标题 / 交易标题 / 订单标题 / 订单关键字等。必选

           model.Subject = "购买商品的标题";

           ///外部第三方的订单号,必选

           model.OutTradeNo = orderNumber;

           AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

           // 设置同步回调地址

           request.SetReturnUrl("");

           // 设置异步通知接收地址()

           request.SetNotifyUrl(_alipayConfig.notify_url);

           // 将业务model载入到request

           request.SetBizModel(model);

           var response = _client.SdkExecute(request);

           // Console.WriteLine($"订单支付发起成功,订单号:{response.Body}");

           //直接传客户端,不需要做form表单转换为json格式

           return response.Body;

       }


复制代码


8 然后在控制器中调用就可以了


9 客户端唤起支付宝界面进行支付,支付成功之后,会调用服务器的回调函数,主要作用是来验证订单信息,更新数据库


需要注意的是回调函数不能带有参数,只能post请求

复制代码


       /// <summary>

       /// Alipay回调通知

       /// </summary>

       /// <returns></returns>

       [HttpPost]

       public async Task<string> Alipaynotify()

       {

           string result = "success";

           SortedDictionary<string, string> sarray = new SortedDictionary<string, string>();

           var keys = Request.Form.Keys;

           if (keys != null)

           {

               foreach (string key in keys)

               {

                   sarray.Add(key, Request.Form[key]);

               }

           }

           if (sarray.Count > 0)

           {

               var notifyId = Request.Form["notify_id"].ToString();

               var sign = Request.Form["sign"].ToString();

               bool verifyresult = _paynotifyservice.GetVerifyResult(sarray, notifyId, sign);

               if (verifyresult) //验签成功 && 关键业务参数校验成功

               {

                   string out_trade_no = Request.Form["out_trade_no"];   //获取ali传过来的参数的值

                   string trade_no = Request.Form["trade_no"];

                   string trade_status = Request.Form["trade_status"];

                   string total_amount = Request.Form["total_amount"];

                   string buyer_id = Request.Form["buyer_id"];

                   string buyer_logon_id = Request.Form["buyer_logon_id"];

                   string app_id = Request.Form["app_id"];

                   var status = await _paynotifyservice.AlipayNotifyAsync(out_trade_no, trade_no, trade_status, float.Parse(total_amount), buyer_logon_id);  //进行数据的更新

                   if (status != 1)

                   {

                       result = "fail";

                   }

               }

               else//验证失败

               {

                   result = "fail";

               }

           }

           return result;

       }


复制代码

复制代码


        /// <summary>

       /// 调用阿里支付接口回调函数更新数据库

       /// </summary>

       /// <param name="OrderNumber"></param>

       /// <param name="aliOrderNo"></param>

       /// <param name="payStauts"></param>

       /// <param name="totalAmout"></param>

       /// <param name="buyerId"></param>

       /// <returns></returns>                      

       public async Task<int> AlipayNotifyAsync(string OrderNumber, string aliOrderNo, string payStauts, double totalAmout, string buyerId)

       {

           var result = -1;

           if (payStauts.Equals("TRADE_SUCCESS") || payStauts.Equals("TRADE_FINISHED"))

           {

               //此处应该校验交易金额是否正确。需要比对float或者double类型数据

               //逻辑处理,更新数据库中订单状态

               result = 1;

           }

           return result;

       }


       public bool GetVerifyResult(SortedDictionary<string, string> sarray, string notifyId, string sign)

       {

           var alinotify = new Notify(_alipayConfig.CharSet, _alipayConfig.SignType, _alipayConfig.PId, _alipayConfig.GatewayUrl, _alipayConfig.AlipayPublicKey);

           //对异步通知进行验签

           bool verifyresult = alinotify.Verify(sarray, notifyId, sign);

           return verifyresult;

       }


复制代码


至此,订单的整个流程就完成了