asp .net mvc支付宝支付服务端demo

来源:互联网 发布:测试显示器的软件 编辑:程序博客网 时间:2024/06/05 08:25

本来支付宝支付不需要服务端提供什么代码的,最多就是存储一些公钥和私钥,但是为了安全,最好还是要在服务端提供支付宝的回调,毕竟客户端是不可相信的。

看了一下支付宝的开发文档,比微信支付的开发文档详细得多,微信开发文档,我竟然没找到服务端的一些demo,我也是醉了。

简单的来讲,支付宝支付分为三步

第一步:拼接参数

 

biz_content = "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"" + Consume.ToString("0.00") + "\",\"subject\":\"" + ConsumeType + "\",\"body\":\"我是支付宝支付\",\"out_trade_no\":\"" + orders.OrderId + "\"}";//把请求参数打包成数组Dictionary<string, string> sParaTemp = new Dictionary<string, string>();sParaTemp.Add("app_id", Com.Alipay.Config.App_id);    //写在一个类里面,配置文件sParaTemp.Add("biz_content", biz_content);sParaTemp.Add("charset", "utf-8");sParaTemp.Add("method", "alipay.trade.app.pay");sParaTemp.Add("notify_url", notify_url);sParaTemp.Add("sign_type", Com.Alipay.Config.Sign_type);sParaTemp.Add("timestamp", timestamp);sParaTemp.Add("version", version);

注意total_amount 他的单位是元,并且是精确到分的。还有notify_url一定要是可访问的,不然也会报错,如果是mvc的,就类似这样http://XXXX/KKPay/AliPayNotify ,一般来说,报错最多的还是这一步,要步步小心。

第二步:签名

签名方法如下:

        /// <summary>        /// 生成请求时的签名        /// </summary>        /// <param name="sPara">请求给支付宝的参数数组</param>        /// <returns>签名结果</returns>        public static string BuildRequestMysign(Dictionary<string, string> sPara)        {            //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串            string prestr = Core.CreateLinkString(sPara);            //把最终的字符串签名,获得签名结果            string mysign = "";            switch (_sign_type)            {                case "RSA":                    mysign = RSAFromPkcs8.sign(prestr, _private_key, _input_charset);                    break;                default:                    mysign = "";                    break;            }            return mysign;        }

这个方法是获取sign的,得到sign后,把他加到DIctionary里面去

                        sParaTemp.Add("sign", sign);

第三步:编码

     /// <summary>        /// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode        /// </summary>        /// <param name="sArray">需要拼接的数组</param>        /// <param name="code">字符编码</param>        /// <returns>拼接完成以后的字符串</returns>        public static string CreateLinkStringUrlencode(Dictionary<string, string> dicArray, Encoding code)        {            StringBuilder prestr = new StringBuilder();            foreach (KeyValuePair<string, string> temp in dicArray)            {                prestr.Append(temp.Key + "=" + HttpUtility.UrlEncode(temp.Value, code) + "&");            }            //去掉最後一個&字符            int nLen = prestr.Length;            prestr.Remove(nLen - 1, 1);            return prestr.ToString();        }
编码方式UTF-8

这个获得的就是传给支付宝的字符串,把它给客户端童鞋。客户端同学发起支付后,支付宝会往notify_url里面发一个请求。这个请求是post的形式的,他会返回来很多东西,具体是哪些东西可以看支付宝的文档。


我们要写一个接收回调的,他返回来的是支付宝支付是否成功。

首先我们要验证这个消息是不是支付宝发出的合法消息,因为有可能是别人伪装支付宝发出的支付成功的消息,这样,就会造成损失。

        /// <summary>        ///  验证消息是否是支付宝发出的合法消息        /// </summary>        /// <param name="inputPara">通知返回参数数组</param>        /// <param name="notify_id">通知验证ID</param>        /// <param name="sign">支付宝生成的签名结果</param>        /// <returns>验证结果</returns>        public bool Verify(SortedDictionary<string, string> inputPara, string notify_id, string sign)        {            //获取返回时的签名验证结果            bool isSign = GetSignVeryfy(inputPara, sign);            //获取是否是支付宝服务器发来的请求的验证结果            string responseTxt = "true";            if (notify_id != null && notify_id != "") { responseTxt = GetResponseTxt(notify_id); }            //写日志记录(若要调试,请取消下面两行注释)            //string sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign.ToString() + "\n 返回回来的参数:" + GetPreSignStr(inputPara) + "\n ";            //Core.LogResult(sWord);            //判断responsetTxt是否为true,isSign是否为true            //responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关            //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关            if (responseTxt == "true" && isSign)//验证成功            {                return true;            }            else//验证失败            {                return false;            }        }
如果验证成功,获取交易的状态

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

如果你的回调地址,没收到请求,支付宝会一直给你发消息,好像是一共发9次还是几次,忘记了,最后处理完,也要给支付宝发一个接收成功的消息,表明我接收到了回调。









      

0 0