• 支付宝移动支付开发详细教程服务端采用.net mvc webapi(C#)


    转自:http://www.kwstu.com/ArticleView/netmvc_201511132005431321

    最近开发手机app需要实现移动支付功能,由于考虑支付安全将支付宝生成签名写到了服务器端,官网给的demo是在客户端的,纠结了几天终于实现了。

    注本教程不对支付宝申请,移动开发配置做解释,核心需要注意的地方就是在官方下载的demo中有生成私钥跟公钥的工具,公钥需要在商家管理后台跟支付宝做交换,这个很关键,笔者在调试的时候出现错误了,最后问支付宝官方客服要了这几个信息。

    开发思路:下载支付宝移动支付demo,根据demo的代码重新写服务器端,然后将生成的签名信息替换demo里面参数测试服务器端的代码是否成功,然后在写服务器端的返回成功处理程序。

    废话不多说了直接上代码吧

    1、C#生成支付签名代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    //第一步去支付宝付款,根据支付宝返回结果进行处理,如果成功需要生成会员记录、充值记录、广告位记录
                        //第一步开始
                        //支付类型
                        string payment_type = "1";
                        //必填,不能修改
                        //服务器异步通知页面路径
                        //string notify_url = "http://" + HttpContext.Request.Url.Host.ToString() + "/ZwOnLine/notifyUrl";
                        string notify_url = "http://api.kwstu.com/Pay/NotifyUrl";
                        //需http://格式的完整路径,不能加?id=123这类自定义参数
                        //页面跳转同步通知页面路径
                        //需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/
                        //卖家支付宝帐户
                        string seller_id = "***";
                        //必填
                        //商户订单号
                        string out_trade_no = checkId;
                        //商户网站订单系统中唯一订单号,必填
                        //订单名称
                        string subject = unitBase.NAME + "[" + zphBase.ZPHNAME + "(" + zphZwService.ZWID + ")]";
                        //必填
                        //付款金额
                        //string total_fee = "0.1";
                        string total_fee = price;
                        //必填
                        //订单描述
                        string body = unitBase.NAME + "于" + DateTime.Now.ToString("yyyy-MM-dd") + "在线预订“" + zphBase.ZPHNAME + "”的" + zphZwService.ZWID + "号展位,缴费" + price + "元。";
                        //防钓鱼时间戳
                        //string anti_phishing_key = "";
                        //若要使用请调用类文件submit中的query_timestamp函数
                        //超时时间需要动态计算,并且减去2,如果超时时间小于2是否让继续支付。
                        TimeSpan time = DateTime.Now - Convert.ToDateTime(zphZwService.LOCKDATE);
                        int minTmp = 10 - ((int)time.TotalMinutes);
                        string minStr = "";
                        if (minTmp >= 2)
                            minStr = (minTmp - 1) + "m";
                        else if (minTmp <= 1)
                            return ClassesLib.ToJson(new
                            {
                                success = false,
                                msg = "操作失败,剩余支付时间不足,请重新选择展位!",
                                error_code = "400"
                            });
                        ////////////////////////////////////////////////////////////////////////////////////////////////
                        string signStr = "partner="" + Config.Partner + ""&seller_id="****"&out_trade_no="" + out_trade_no + ""&subject="" + subject + ""&body="" + body + ""&total_fee="0.01"&notify_url="" + notify_url + ""&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&return_url="m.alipay.com"";
                        string retrnStr = "partner="" + Config.Partner + ""&seller_id="****"&out_trade_no="" + out_trade_no + ""&subject="" + subject + ""&body="" + body + ""&total_fee="0.01"&notify_url="" + notify_url + ""&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&return_url="m.alipay.com"&sign="" + HttpUtility.UrlEncode(RSAFromPkcs8.sign(signStr, Config.Private_key, Config.Input_charset), System.Text.Encoding.UTF8) + ""&sign_type="RSA"";
    客户端将returnStr直接提交的支付宝即可,修改demo中的如下代码进行调试,客户端可以不做账号信息配置,包名要注意
    1
    2
    3
    // 完整的符合支付宝参数规范的订单信息
            //final String payInfo= orderInfo + "&sign="" + sign + ""&" + getSignType();
            final String payInfo="partner="*****"&seller_id="*****"&out_trade_no="ZFB_201511111751182080"&subject="酷网网络工作室[2015-11-21(周六)综合人才招聘会(A012)]"&body="酷网网络工作室于2015-11-11在线预订“2015-11-21(周六)综合人才招聘会”的A012号展位,缴费200元。"&total_fee="0.01"&notify_url="http://api.kwstu.com/Pay/NotifyUrl"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&return_url="m.alipay.com"&sign="KbCV%2bHvHhGHuE%2fSxFjaXQJ9BP%2bY5m7bR9IxGKL7nk%2bz%2fxI%2fNALY21XEgAFOhGbzCTwer02FSKI2oadw9ChHYIhyC7f6o3vWl18k01o34hyrCexXfSP36ZkZ4k2V0ABaHGbrBLOPD73SewPtfxEfiJj88JJIDEbYI9CU%2bFhJWEHo%3d"&sign_type="RSA"";

    将final String payInfo= orderInfo + "&sign="" + sign + ""&" + getSignType();代码注释直接赋值returnStr的值即可

    服务端支付成功处理代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    /// <summary>
            /// 功能:服务器异步通知页面
            /// 版本:3.3
            /// 日期:2012-07-10
            /// 说明:
            /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
            /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
            ///
            /// ///////////////////页面功能说明///////////////////
            /// 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
            /// 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
            /// 该页面调试工具请使用写文本函数logResult。
            /// 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知
            /// </summary>
            public ActionResult NotifyUrl()
            {
                SortedDictionary<string, string> sPara = GetRequestPost();
                ClassesLib.InsertLog("1(notifyUrl)");
                if (sPara.Count > 0)//判断是否有带返回参数
                {
                    ClassesLib.InsertLog("2(notifyUrl)");
                    Notify aliNotify = new Notify();
                    bool verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
                    ClassesLib.InsertLog("--" + "notify_id:" + Request.Form["notify_id"] + "--" + "sign:" + Request.Form["sign"]);
                    //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
                    //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
                    //商户订单号                string out_trade_no = Request.Form["out_trade_no"];
                    string out_trade_no = Request.Form["out_trade_no"];
                    ClassesLib.InsertLog("--" + "out_trade_no:" + Request.Form["out_trade_no"]);
                    //支付宝交易号                string trade_no = Request.Form["trade_no"];
                    string trade_no = Request.Form["trade_no"];
                    ClassesLib.InsertLog("--" + "trade_no:" + Request.Form["trade_no"]);
                    //交易状态
                    string trade_status = Request.Form["trade_status"];
                    ClassesLib.InsertLog("--" + "trade_status:" + Request.Form["trade_status"]);
                    if (verifyResult)//验证成功
                    {
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        //请在这里加上商户的业务逻辑程序代码
                        if (Request.Form["trade_status"] == "TRADE_FINISHED")
                        {
                            ClassesLib.InsertLog(out_trade_no + "订单状态正常(notifyUrl)");
                            //判断该笔订单是否在商户网站中已经做过处理
                            //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                            //如果有做过处理,不执行商户的业务程序
                            //注意:
                            //该种交易状态只在两种情况下出现
                            //1、开通了普通即时到账,买家付款成功后。
                            //2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。
                            
                        }
                        else if (Request.Form["trade_status"] == "TRADE_SUCCESS")
                        {
                            ClassesLib.InsertLog(out_trade_no + "订单状态正常(notifyUrl)");
                            //判断该笔订单是否在商户网站中已经做过处理
                            //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                            //如果有做过处理,不执行商户的业务程序
                            //注意:
                            //该种交易状态只在一种情况下出现——开通了高级即时到账,买家付款成功后。
                             
                                 
                        }
                        else
                        {
                            ClassesLib.InsertLog(out_trade_no + "状态错误(notifyUrl)");
                            return Content("trade_status=" + Request.QueryString["trade_status"]);
                        }
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    }
                    else//验证失败
                    {
                        ClassesLib.InsertLog(out_trade_no + "验证失败(notifyUrl)");
                        return Content("验证失败");
                    }
                }
                else
                {
                    ClassesLib.InsertLog("无返回参数(notifyUrl)");
                    return Content("无返回参数");
                }
            }

    开发资料获取地址:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-8489738063.2.VrK9RN&id=524269482340

  • 相关阅读:
    java学习6-java基础类库
    java学习5-面向对象(下)
    java学习4-面向对象(上)
    java学习3-流程控制与数组
    java学习2-数据类型和运算符
    pycharm(社区版2019.1版本)打开README.md文件卡死解决办法
    python深拷贝与浅拷贝的区别
    python中list切片详解
    python使用input().split()接收多个用户输入
    python学习-语言概述(一)
  • 原文地址:https://www.cnblogs.com/kwstu/p/4994761.html
Copyright © 2020-2023  润新知