zoukankan      html  css  js  c++  java
  • .net core 3.1 webapi调用支付宝支付接口以及回调函数

    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;
            }

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

  • 相关阅读:
    shell 命令参数
    Windows系统配置Python环境,python2和python3共存
    jmeter面试题及答案
    接口测试
    python语法基础
    pycharm环境安装及注册
    Win10下python 2.7与python 3.6双环境安装图文教程
    eclipse中导入maven项目时pom文件报错
    ssm-crud项目--总结
    ssm-crud项目——分页查询
  • 原文地址:https://www.cnblogs.com/carlpeng/p/13468878.html
Copyright © 2011-2022 走看看