支付宝APP支付服务端详解

前面接了微信支付,相比微信支付,支付宝APP支付提供了支付分装类,下面将实现支付宝APP支付、订单查询、支付结果异步通知、APP支付申请参数说明,以及服务端返回APP端发起支付的签名、商户私钥、支付宝公钥的配置使用等。

支付注意事项

1、APP支付不能在沙箱测试、只能申请上线测试 
2、需要创建RSA密钥设置文档,设置后上传rsa_public_key.pem【开发者公钥,上传时需要去掉公钥的头和尾】上传成功后换取支付宝公钥,为项目的alipay_public_key.pem 
3、rsa_private_key_pkcs8.pem【开发者私钥】,去掉头和尾为项目的alipay_private_key_pkcs8.pem 
4、需要导入所需支付包:alipay-sdk-java.jar 和 commons-logging.jar,具体参考:服务端SDK

支付流程

支付文档参考:支付文档支付文档2

APP支付:服务器端按照文档【统一收单交易支付接口】创建支付OrderStr返回APP端——-APP端拿到OrderStr发起支付—–支付宝服务器端回调服务端异步通知接口——-服务器端按照【App支付结果异步通知】校验签名等做业务逻辑处理

APP支付订单查询:服务器端调用【统一收单线下交易查询】查询支付订单

APP支付申请退款:每笔支付可以申请多次退款,但退款总金额不能超过支付金额,调用【统一收单交易退款接口】发起退款申请

APP支付退款查询:服务端调用【 统一收单交易退款查询】查询退款订单信息

以上为转载。

在具体开发的时候会出现一些问题。总结一下:

问题1:生成密钥的问题

密钥有3个。

密钥生成见支付宝帮助文档,地址是  https://doc.open.alipay.com/doc2/detail.htm?treeId=193&articleId=105310&docType=1

我在使用WIN10系统使用方式1生成的时候,点击解压打开文件夹,直接运行“支付宝RAS密钥生成器SHAwithRSA1024_V1.0.bat”。他是啥都没有生成,然后我又自作聪明跑到  secret_key_tools_RSA_win\RSA\openssl 目录下运行生成公钥.bat , 生成公钥私钥转换PCKS8.bat , 私钥转换PCKS8.bat 批处理文件。(secret_key_tools_RSA_win.zip解压后的文件夹名)

结果是,还是有问题。

后来同事用方式1,但是改成苹果笔记本生成就好了。

好是怎么验证出来的呢?

打开 https://openhome.alipay.com/platform/detailApp.htm?appId=2016111602874881&tab=appSetting  地址,

在左边的导航栏里面选择,应用环境——》接口加签方式  打开下面的窗口。

在第三步下载签名检验的工具,将生成的密钥放入左侧,然后生成签名后,再放入第三步的窗口中进行验证看是否正确。校验通过,则说明公钥和私钥生成成功。

  

具体代码如下。

  /// <summary>
        /// 支付下单
        /// </summary>
        [Route("SignaturesUrl")]
        public AliPayReturn SignaturesUrl()
        {
            //post接收客户端发来的订单信息.
            Dictionary<string, string> sPara = GetRequestPost();

            ////获取订单信息partner.
            //string partner = HttpContext.Current.Request.Form["partner"];

            ////获取订单信息service.
            //string service = HttpContext.Current.Request.Form["service"];

            AliPayReturn request_code = new AliPayReturn();
            request_code.OMsg = new OMsg();

            //判断partner和service信息匹配成功.
            //if (partner != null && service != null)
            //{
            //    if (partner.Replace("\"", "") == Config.partner && service.Replace("\"", "") == Config.service)
            //    {
            //将获取的订单信息,按照“参数=参数值”的模式用“&”字符拼接成字符串.
            string data = Core.CreateLinkString(sPara);

            //调试用,打印日志信息,默认在项目路径下的log文件夹.
            //Core.LogResult(data);
            //string jsonSign= HttpUtility.UrlEncode(RSA.sign("a=123", Config.private_key, "GBK"));
            //使用商户的私钥进行RSA签名,并且把sign做一次urleccode.
            string sign = HttpUtility.UrlEncode(RSA.sign(data, Config.private_key, Config.input_charset));

            //拼接请求字符串(注意:不要忘记参数值的引号).
            data = HttpUtility.UrlEncode(data) + "&sign=\"" + sign + "\"&sign_type=\"" + Config.sign_type + "\"";

            Core.LogResult("服务端返回的值:" + data);
            //返回给客户端请求.
            //HttpContext.Current.Response.Write(data);
            Dictionary<string, string> dicResult = new Dictionary<string, string>();
            dicResult.Add("return_url", data);
            request_code.OMsg.Flag = "S";
            request_code.OMsg.Msg = "调用成功";
            request_code.return_info = dicResult;
            return request_code;
            //    }
            //    else
            //    {
            //        //HttpContext.Current.Response.Write("订单信息不匹配!");
            //        request_code.OMsg.Flag = "F";
            //        request_code.OMsg.Msg = "订单信息不匹配";
            //        return request_code;
            //    }
            //}
            //else
            //{
            //    //HttpContext.Current.Response.Write("无客户端请求!");
            //    request_code.OMsg.Flag = "F";
            //    request_code.OMsg.Msg = "无客户端请求";
            //    return request_code;
            //}
        }

        /// <summary>
        /// 回调接口
        /// </summary>
        /// <param name="id"></param>
        [Route("NotifyUrl/{id}")]
        public void NotifyUrl(int id)
        {
            Dictionary<string, string> sPara = GetRequestPost();
            string notify_id = HttpContext.Current.Request.Form["notify_id"];//获取notify_id

            string sign = HttpContext.Current.Request.Form["sign"];//获取sign

            if (notify_id != null && notify_id != "")//判断是否有带返回参数
            {
                Notify aliNotify = new Notify();
                if (aliNotify.GetResponseTxt(notify_id) == "true")
                {
                    if (aliNotify.GetSignVeryfy(sPara, sign))
                    {
                        //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
                        //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表

                        //商户订单号
                        string out_trade_no = HttpContext.Current.Request.Form["out_trade_no"];

                        //支付宝交易号
                        string trade_no = HttpContext.Current.Request.Form["trade_no"];

                        //交易状态
                        string trade_status = HttpContext.Current.Request.Form["trade_status"];

                        if (HttpContext.Current.Request.Form["trade_status"] == "TRADE_FINISHED")
                        {
                            //判断该笔订单是否在商户网站中已经做过处理
                            //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                            //请务必判断请求时的out_trade_no、total_fee、seller_id与通知时获取的out_trade_no、total_fee、seller_id为一致的
                            //如果有做过处理,不执行商户的业务程序

                            //注意:
                            //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                        }
                        else if (HttpContext.Current.Request.Form["trade_status"] == "TRADE_SUCCESS")
                        {
                            //判断该笔订单是否在商户网站中已经做过处理
                            //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                            //请务必判断请求时的out_trade_no、total_fee、seller_id与通知时获取的out_trade_no、total_fee、seller_id为一致的
                            //如果有做过处理,不执行商户的业务程序

                            //注意:
                            //付款完成后,支付宝系统发送该交易状态通知
                        }
                        //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
                        HttpContext.Current.Response.Write("success");  //请不要修改或删除
                    }
                    else
                    {
                        HttpContext.Current.Response.Write("sign fail!");
                    }
                }
                else
                {
                    HttpContext.Current.Response.Write("response fail!");
                }
            }
            else
            {
                HttpContext.Current.Response.Write("非通知参数!");
            }

        }

        /// <summary>
        /// 获取请求数据
        /// </summary>
        /// <returns></returns>
        private Dictionary<string, string> GetRequestPost()
        {
            ;
            SortedDictionary<string, string> sArraytemp = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = HttpContext.Current.Request.Form;

            #region 读取客户端传递的参数
            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;
            string paramLog = "客户端提交的参数值:";
            ; i < requestItem.Length; i++)
            {
                sArraytemp.Add(requestItem[i], HttpContext.Current.Request.Form[requestItem[i]]);
                paramLog += requestItem[i] + "," + HttpContext.Current.Request.Form[requestItem[i]] + "<br>";   //添加
            }
            Core.LogResult(paramLog);
            #endregion

            Dictionary<string, string> sArray = new Dictionary<string, string>();
            foreach (KeyValuePair<string, string> temp in sArraytemp)
            {
                sArray.Add(temp.Key, temp.Value);
            }

            return sArray;
        }
    }

支付宝支付-APP支付服务端详解的更多相关文章

  1. http客户端请求及服务端详解

    http客户端请求及服务端详解 引言 HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展. ...

  2. 支付宝集成+网站支付+APP支付+手机网站支付

    网站支付宝 1.申请签约后获得相应的pid:208***开头和key 这里说明下pc网站支付采用md5加密所以这里只需要提供pid和key不需要上传公钥. 2.下载即时到账demo http://do ...

  3. aplipay支付-app支付之前后端实现

    目录 前言 一 前台aplipay实现 1.1 安装0x5e/react-native-alipay 1.2. 配置 1.3. Alipay.pay(orderStr) 二 后端 2.1 服务端sdk ...

  4. php 支付宝新版本app支付以及回调

    ;支付宝快速接入; 支付宝2017年新版本支付基本业务逻辑 服务端生成字符串 交给客户端, 客户端调用接口,将这段字符串str传过去 调用起支付界面. 其中字符串str包含了所有请求参数,以及请求参数 ...

  5. 支付宝app支付服务端流程

    支付宝APP支付服务端详解 前面接了微信支付,相比微信支付,支付宝APP支付提供了支付封装类,下面将实现支付宝APP支付.订单查询.支付结果异步通知.APP支付申请参数说明,以及服务端返回APP端发起 ...

  6. android支付宝app支付(原生态)-包括android前端与java后台

    本文讲解了 android开发的原生态app集成了支付宝支付, 还提供了java后台服务器处理支付宝支付的加密代码, app前端与java后台服务器使用json数据格式交互信息,java后台服务主要用 ...

  7. android 集成支付宝app支付(原生态)-包括android前端与java后台

    本文讲解了 android开发的原生态app集成了支付宝支付, 还提供了java后台服务器处理支付宝支付的加密代码, app前端与java后台服务器使用json数据格式交互信息,java后台服务主要用 ...

  8. 微信支付(APP支付)-服务端开发(一)

    微信支付,首先需要注册一个商户平台公众账号,(网址:https://pay.weixin.qq.com/index.php/home/d_login) 目前微信支付的接入方式有四种方式:公众号支付,A ...

  9. .Net后台实现支付宝APP支付

    前面讨论了微信支付,接下来聊聊支付宝的APP支付(新款支付宝支付).其实这些支付原理都一样,只不过具体到每个支付平台,所使用的支付配置参数不同,返回至支付端的下单参数也不同. 话不多说,直接上代码. ...

随机推荐

  1. iOS面试题

    一个区分度很大的面试题 考察一个面试者基础咋样,基本上问一个 @property 就够了: @property 后面可以有哪些修饰符? 线程安全的: atomic,nonatomic 访问权限的 re ...

  2. Jquery制作--焦点图淡出淡入

    之前写了一个焦点图左右轮播的,感觉淡出淡入用得也比较多,就干脆一起放上来啦.这个容器用了百分比宽度,图片始终保持居中处理,定宽或者自适应宽度都是可以的. 兼容到IE6+以上浏览器,有淡出淡入速度和切换 ...

  3. linux 下C++查询mysql数据库

    上一节我们看了怎么使用mysql提供的API来连接mysql数据库,现在来看看怎么执行一条简单的查询语句,并且把查询的结果显示出来. 准备工作:首先新建了一个数据库inote,在这个数据库下面新建了一 ...

  4. JavaScript学习笔记(1))——————call,apply方法

    学习前端也有一段时间了,但是效果甚微.利用时间不够充分,虽然是利用工作之余来学习.但是这不能成为我的借口. 今天学习了(其实看了很多遍)call apply方法. function abc(a,b){ ...

  5. 上个项目的一些反思 III

    离线缓存 之前的项目因为实时性要求比较高,所以一打开客户端,就开始做网络请求.现在想想,是没有做内容的离线缓存.这个问题,我没意识到.产品经理也没有意识到... 我觉得Archiver,来做比较合适, ...

  6. How do I get the path of the current executed file in Python?

    First, you need to import from inspect and os from inspect import getsourcefile from os.path import ...

  7. Google Code Jam 2016 Round 1B B

    题意:给出两个数字位数相同,分别中间有若干位不知道,用问号表示.现在要求补全这两个数字,使得差值的绝对值最小,多解则取第一个数字的值最小的,再多解就取第二个数字最小的. 分析: 类似数位dp,但是很多 ...

  8. window 安装grunt

    1.先安装nodejs ,npm ,参考 http://www.cnblogs.com/seanlv/archive/2011/11/22/2258716.html 2 安装grunt 百度搜索 参考 ...

  9. shell:遍历目录和子目录的所有文件

    #!/bin/bash function getdir(){ ` do dir_or_file=$"/"$element if [ -d $dir_or_file ] then g ...

  10. Ubuntu 12.04 安装 Apache2+PHP5+MySQL

    LAMP是Linux web服务器组合套装的缩写,分别是Apache+MySQL+PHP.此教程教大家如何在Ubuntu 12.04 LTS server 上安装Apache2服务器,包括PHP5(m ...