• 支付宝PC网站接口对接


    PC网站支付接口,请参考支付宝官方文档:https://b.alipay.com/signing/productSet.htm?navKey=all

    1.需要提供签约账号、商户密钥

    2.代码实现:

    支付接口(即时到账交易)

    1>调用支付宝支付网关

            /// <summary>
            /// PC网站支付
            /// </summary>
            /// <param name="postProcessPaymentRequest"></param>
            private void AlipayTradePCPayment(订单实体 order)
            {
                if (order == null)
                {
                    return;
                }
    
                Log.Info(this.GetType().ToString(), "AlipayTradePCPayment Start......");
    
                string responseText = string.Empty;
                try
                {
                    #region 调用支付宝支付接口
    
                    string partner = "签约账号";
                    string sign_type = "MD5";//签名方式:MD5、RSA、DSA
                    string key = "MD5密钥";//商户密钥
                    string input_charset = "utf-8";//字符编码格式 目前支持 gbk 或 utf-8
    
                    //把请求参数打包成数组
                    SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
    
                    sParaTemp.Add("service", "create_direct_pay_by_user");//调用的接口名,无需修改
                    sParaTemp.Add("partner", partner);//签约账号
                    sParaTemp.Add("seller_id", "");//收款支付宝账号
                    sParaTemp.Add("_input_charset", input_charset.ToLower());//字符编码格式 目前支持 gbk 或 utf-8
                    sParaTemp.Add("payment_type", "1");//支付类型,无需修改
                    sParaTemp.Add("notify_url", "http://XXXXXXXX/AliPayment/PaymentNotify");//服务器异步通知页面路径
                    sParaTemp.Add("return_url", "http://XXXXXXXX/AliPayment/PaymentReturn");//页面跳转同步通知页面路径
                    sParaTemp.Add("anti_phishing_key", "");//防钓鱼时间戳
                    sParaTemp.Add("exter_invoke_ip", "");//客户端的IP地址
                    sParaTemp.Add("out_trade_no", "");//商户订单号,商户网站订单系统中唯一订单号,必填
                    sParaTemp.Add("subject", "");//订单名称,必填
                    sParaTemp.Add("total_fee", "");//付款金额,必填 单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。
                    sParaTemp.Add("body", "");//商品描述,可空
    
                    //建立请求
                    Submit submit = new Submit(partner, key, input_charset, sign_type);
                    responseText = submit.BuildRequest(sParaTemp, "get", "确认");
    
                    #endregion
    
                    _httpContext.Response.Clear();
                    _httpContext.Response.Write(responseText.ToString());
                    _httpContext.Response.End();
                }
                catch (Exception ex)
                {
                    Log.Error(this.GetType().ToString(), "Exception: " + ex.Message);
                }
    
                Log.Info(this.GetType().ToString(), "AlipayTradePCPayment End......");
                _logger.Track(string.Format("支付宝PC网站支付跟踪信息。GetForm:{0}", responseText), FoxconnConsts.APPSETTING_KEY_TRACK_INTERFACE);
            }
    View Code

    验签、建立请求类

        /// <summary>
        /// 类名:Submit
        /// 功能:支付宝各接口请求提交类
        /// 详细:构造支付宝各接口表单HTML文本,获取远程HTTP数据
        /// 版本:3.3
        /// 修改日期:2011-07-05
        /// 说明:
        /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
        /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考
        /// </summary>
        public class Submit
        {
            #region 字段
            //支付宝网关地址(新)
            private static string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
            //合作身份者ID,签约账号,以2088开头由16位纯数字组成的字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
            private static string _partner = "";
            //商户的私钥
            private static string _key = "";
            //编码格式
            private static string _input_charset = "";
            //签名方式
            private static string _sign_type = "";
            #endregion
    
            public Submit(string partner, string key, string input_charset, string sign_type)
            {
                _partner = partner;
                _key = key;
                _input_charset = input_charset.ToLower();
                _sign_type = sign_type.ToUpper();
            }
    
            /// <summary>
            /// 生成请求时的签名
            /// </summary>
            /// <param name="sPara">请求给支付宝的参数数组</param>
            /// <returns>签名结果</returns>
            private string BuildRequestMysign(Dictionary<string, string> sPara)
            {
                //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
                string prestr = Core.CreateLinkString(sPara);
    
                //把最终的字符串签名,获得签名结果
                string mysign = "";
                switch (_sign_type)
                {
                    case "MD5":
                        mysign = AlipayMD5.Sign(prestr, _key, _input_charset);
                        break;
                    case "RSA":
                        mysign = RSAFromPkcs8.sign(prestr, _key, _input_charset);
                        break;
                    default:
                        mysign = "";
                        break;
                }
    
                return mysign;
            }
    
            /// <summary>
            /// 生成要请求给支付宝的参数数组
            /// </summary>
            /// <param name="sParaTemp">请求前的参数数组</param>
            /// <returns>要请求的参数数组</returns>
            private Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
            {
                //待签名请求参数数组
                Dictionary<string, string> sPara = new Dictionary<string, string>();
                //签名结果
                string mysign = "";
    
                //过滤签名参数数组
                sPara = Core.FilterPara(sParaTemp);
    
                //获得签名结果
                mysign = BuildRequestMysign(sPara);
    
                //签名结果与签名方式加入请求提交参数组中
                sPara.Add("sign", mysign);
                sPara.Add("sign_type", _sign_type);
    
                return sPara;
            }
    
            /// <summary>
            /// 生成要请求给支付宝的参数数组
            /// </summary>
            /// <param name="sParaTemp">请求前的参数数组</param>
            /// <param name="code">字符编码</param>
            /// <returns>要请求的参数数组字符串</returns>
            private string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
            {
                //待签名请求参数数组
                Dictionary<string, string> sPara = new Dictionary<string, string>();
                sPara = BuildRequestPara(sParaTemp);
    
                //把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode
                string strRequestData = Core.CreateLinkStringUrlencode(sPara, code);
    
                return strRequestData;
            }
    
            /// <summary>
            /// 建立请求,以表单HTML形式构造(默认)
            /// </summary>
            /// <param name="sParaTemp">请求参数数组</param>
            /// <param name="strMethod">提交方式。两个值可选:post、get</param>
            /// <param name="strButtonValue">确认按钮显示文字</param>
            /// <returns>提交表单HTML文本</returns>
            public string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string strButtonValue)
            {
                //待请求参数数组
                Dictionary<string, string> dicPara = new Dictionary<string, string>();
                dicPara = BuildRequestPara(sParaTemp);
    
                StringBuilder sbHtml = new StringBuilder();
    
                sbHtml.Append("<form id='alipaysubmit' name='alipaysubmit' action='" + GATEWAY_NEW + "_input_charset=" + _input_charset + "' method='" + strMethod.ToLower().Trim() + "'>");
    
                foreach (KeyValuePair<string, string> temp in dicPara)
                {
                    sbHtml.Append("<input type='hidden' name='" + temp.Key + "' value='" + temp.Value + "'/>");
                }
    
                //submit按钮控件请不要含有name属性
                sbHtml.Append("<input type='submit' value='" + strButtonValue + "' style='display:none;'></form>");
    
                sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");
    
                return sbHtml.ToString();
            }
    
    
            /// <summary>
            /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
            /// </summary>
            /// <param name="sParaTemp">请求参数数组</param>
            /// <returns>支付宝处理结果</returns>
            public string BuildRequest(SortedDictionary<string, string> sParaTemp)
            {
                Encoding code = Encoding.GetEncoding(_input_charset);
    
                //待请求参数数组字符串
                string strRequestData = BuildRequestParaToString(sParaTemp, code);
    
                //把数组转换成流中所需字节数组类型
                byte[] bytesRequestData = code.GetBytes(strRequestData);
    
                //构造请求地址
                string strUrl = GATEWAY_NEW + "_input_charset=" + _input_charset;
    
                //请求远程HTTP
                string strResult = "";
                try
                {
                    //设置HttpWebRequest基本信息
                    HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                    myReq.Method = "post";
                    myReq.ContentType = "application/x-www-form-urlencoded";
    
                    //填充POST数据
                    myReq.ContentLength = bytesRequestData.Length;
                    Stream requestStream = myReq.GetRequestStream();
                    requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
                    requestStream.Close();
    
                    //发送POST数据请求服务器
                    HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
                    Stream myStream = HttpWResp.GetResponseStream();
    
                    //获取服务器返回信息
                    StreamReader reader = new StreamReader(myStream, code);
                    StringBuilder responseData = new StringBuilder();
                    String line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        responseData.Append(line);
                    }
    
                    //释放
                    myStream.Close();
    
                    strResult = responseData.ToString();
                }
                catch (Exception exp)
                {
                    strResult = "报错:" + exp.Message;
                }
    
                return strResult;
            }
    
            /// <summary>
            /// 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
            /// 注意:远程解析XML出错,与IIS服务器配置有关
            /// </summary>
            /// <returns>时间戳字符串</returns>
            public string Query_timestamp()
            {
                string url = GATEWAY_NEW + "service=query_timestamp&partner=" + _partner + "&_input_charset=" + _input_charset;
                string encrypt_key = "";
    
                XmlTextReader Reader = new XmlTextReader(url);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(Reader);
    
                encrypt_key = xmlDoc.SelectSingleNode("/alipay/response/timestamp/encrypt_key").InnerText;
    
                return encrypt_key;
            }
        }
    View Code

    2>接收支付宝同步通知(get)

            /// <summary>
            /// 支付宝支付同步通知
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public ActionResult PaymentReturn()
            {
                string result = string.Empty;
                Log.Info(this.GetType().ToString(), "PaymentReturn End......");
    
                try
                {
                    SortedDictionary<string, string> sPara = GetRequestGet();
                    if (sPara.Count > 0)//判断是否有带返回参数
                    {
                        bool verifyResult = Verify(sPara, Request.QueryString["notify_id"], Request.QueryString["sign"]);
    
                        if (verifyResult)//验证成功
                        {
                            //商户订单号
                            string out_trade_no = Request.QueryString["out_trade_no"];
                            //支付宝交易号
                            string trade_no = Request.QueryString["trade_no"];
                            //交易状态
                            string trade_status = Request.QueryString["trade_status"];
    
                            if (Request.QueryString["trade_status"] == "TRADE_FINISHED" || Request.QueryString["trade_status"] == "TRADE_SUCCESS")
                            {
                                //判断该笔订单是否在商户网站中已经做过处理
                                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                                //如果有做过处理,不执行商户的业务程序
                            }
                            else
                            {
                                result = "trade_status=" + Request.QueryString["trade_status"];
                            }
    
                            //打印页面
                            result = "验证成功";
                        }
                        else//验证失败
                        {
                            result = "验证失败";
                        }
                    }
                    else
                    {
                        result = "无返回参数";
                    }
                    Log.Info(this.GetType().ToString(), "result:" + result);
    
                }
                catch (Exception ex)
                {
                    Log.Info(this.GetType().ToString(), "Exception:" + ex.Message);
                    _logger.Track(string.Format("支付宝支付同步通知跟踪信息。结果:{0}", ex.Message), FoxconnConsts.APPSETTING_KEY_TRACK_INTERFACE);
                }
                Log.Info(this.GetType().ToString(), "PaymentReturn End......");
    
                return Redirect(Url.RouteUrl("CustomerOrders"));
            }
    View Code 
            /// <summary>
            /// 获取支付宝GET过来通知消息,并以“参数名=参数值”的形式组成数组
            /// </summary>
            /// <returns>request回来的信息组成的数组</returns>
            public SortedDictionary<string, string> GetRequestGet()
            {
                int i = 0;
                SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
                NameValueCollection coll;
                //Load Form variables into NameValueCollection variable.
                coll = Request.QueryString;
    
                // Get names of all forms into a string array.
                String[] requestItem = coll.AllKeys;
    
                for (i = 0; i < requestItem.Length; i++)
                {
                    sArray.Add(requestItem[i], Request.QueryString[requestItem[i]]);
                }
    
                return sArray;
            }
    View Code 

    支付宝通知处理类

       /// <summary>
        /// 类名:Notify
        /// 功能:支付宝通知处理类
        /// 详细:处理支付宝各接口通知返回
        /// 版本:3.3
        /// 修改日期:2011-07-05
        /// '说明:
        /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
        /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
        /// 
        /// //////////////////////注意/////////////////////////////
        /// 调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常 
        /// </summary>
        public class Notify
        {
            #region 字段
            private string _partner = "";               //合作身份者ID
            private string _key = "";                   //MD5:商户的私钥 RSA:支付宝的公钥
            private string _input_charset = "";         //编码格式
            private string _sign_type = "";             //签名方式
    
            //支付宝消息验证地址
            private string Https_veryfy_url = "https://mapi.alipay.com/gateway.do?service=notify_verify&";
            #endregion
    
    
            /// <summary>
            /// 构造函数
            /// 从配置文件中初始化变量
            /// </summary>
            /// <param name="inputPara">通知返回参数数组</param>
            /// <param name="notify_id">通知验证ID</param>
            public Notify(string partner, string key, string input_charset, string sign_type)
            {
                //初始化基础配置信息
                _partner = partner.Trim();
                _key = key.Trim();
                _input_charset = input_charset.Trim().ToLower();
                _sign_type = sign_type.Trim().ToUpper();
            }
            
             /// <summary>
            /// 从文件读取公钥转公钥字符串
            /// </summary>
            /// <param name="Path">公钥文件路径</param>
            public static string getPublicKeyStr(string Path)
            {
                StreamReader sr = new StreamReader(Path);
                string pubkey = sr.ReadToEnd();
                sr.Close();
                if (pubkey != null)
                {
                    pubkey = pubkey.Replace("-----BEGIN PUBLIC KEY-----", "");
                    pubkey = pubkey.Replace("-----END PUBLIC KEY-----", "");
                    pubkey = pubkey.Replace("
    ", "");
                    pubkey = pubkey.Replace("
    ", "");
                }
                return pubkey;
            }
    
            /// <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 = "false";
                if (notify_id != null && notify_id != "") { responseTxt = GetResponseTxt(notify_id); }
    
                //写日志记录(若要调试,请取消下面两行注释)
                //string sWord = "responseTxt=" + responseTxt + "
     isSign=" + isSign.ToString() + "
     返回回来的参数:" + GetPreSignStr(inputPara) + "
     ";
                //Core.LogResult(sWord);
    
                //判断responsetTxt是否为true,isSign是否为true
                //responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
                //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
                if (responseTxt == "true" && isSign)//验证成功
                {
                    return true;
                }
                else//验证失败
                {
                    return false;
                }
            }
    
            /// <summary>
            /// 获取待签名字符串(调试用)
            /// </summary>
            /// <param name="inputPara">通知返回参数数组</param>
            /// <returns>待签名字符串</returns>
            private string GetPreSignStr(SortedDictionary<string, string> inputPara)
            {
                Dictionary<string, string> sPara = new Dictionary<string, string>();
    
                //过滤空值、sign与sign_type参数
                sPara = Core.FilterPara(inputPara);
    
                //获取待签名字符串
                string preSignStr = Core.CreateLinkString(sPara);
    
                return preSignStr;
            }
    
            /// <summary>
            /// 获取返回时的签名验证结果
            /// </summary>
            /// <param name="inputPara">通知返回参数数组</param>
            /// <param name="sign">对比的签名结果</param>
            /// <returns>签名验证结果</returns>
            private bool GetSignVeryfy(SortedDictionary<string, string> inputPara, string sign)
            {
                Dictionary<string, string> sPara = new Dictionary<string, string>();
    
                //过滤空值、sign与sign_type参数
                sPara = Core.FilterPara(inputPara);
                
                //获取待签名字符串
                string preSignStr = Core.CreateLinkString(sPara);
    
                //获得签名验证结果
                bool isSgin = false;
                if (sign != null && sign != "")
                {
                    switch (_sign_type)
                    {
                        case "MD5":
                            isSgin = AlipayMD5.Verify(preSignStr, sign, _key, _input_charset);
                            break;
                        case "RSA":
                            isSgin = RSAFromPkcs8.verify(preSignStr, sign, _key, _input_charset);
                            break;
                        default:
                            break;
                    }
                }
    
                return isSgin;
            }
    
            /// <summary>
            /// 获取是否是支付宝服务器发来的请求的验证结果
            /// </summary>
            /// <param name="notify_id">通知验证ID</param>
            /// <returns>验证结果</returns>
            private string GetResponseTxt(string notify_id)
            {
                string veryfy_url = Https_veryfy_url + "partner=" + _partner + "&notify_id=" + notify_id;
    
                //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求
                string responseTxt = Get_Http(veryfy_url, 120000);
    
                return responseTxt;
            }
    
            /// <summary>
            /// 获取远程服务器ATN结果
            /// </summary>
            /// <param name="strUrl">指定URL路径地址</param>
            /// <param name="timeout">超时时间设置</param>
            /// <returns>服务器ATN结果</returns>
            private string Get_Http(string strUrl, int timeout)
            {
                string strResult;
                try
                {
                    HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                    myReq.Timeout = timeout;
                    HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
                    Stream myStream = HttpWResp.GetResponseStream();
                    StreamReader sr = new StreamReader(myStream, Encoding.Default);
                    StringBuilder strBuilder = new StringBuilder();
                    while (-1 != sr.Peek())
                    {
                        strBuilder.Append(sr.ReadLine());
                    }
    
                    strResult = strBuilder.ToString();
                }
                catch (Exception exp)
                {
                    strResult = "错误:" + exp.Message;
                }
    
                return strResult;
            }
        }
    View Code

    3>接收支付宝异步通知(post)

            /// <summary>
            /// 支付宝支付异步通知
            /// </summary>
            /// <returns></returns>
            [ValidateInput(false)]
            public ActionResult PaymentNotify()
            {
                string result = string.Empty;
                try
                {
                    Log.Info(this.GetType().ToString(), "PaymentNotify Start......");
    
                    SortedDictionary<string, string> sPara = GetRequestPost();
                    if (sPara.Count > 0)//判断是否有带返回参数
                    {
                        bool verifyResult = Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
                        Log.Debug(this.GetType().ToString(), "verifyResult:" + verifyResult);
    
                        if (verifyResult)//验证成功
                        {
                            //商户订单号
                            string out_trade_no = Request.Form["out_trade_no"];
                            //支付宝交易号
                            string trade_no = Request.Form["trade_no"];
                            //交易状态
                            string trade_status = Request.Form["trade_status"];
    
                            if (string.IsNullOrEmpty(out_trade_no))
                            {
                                throw new Exception("商户订单号不能为空");
                            }
    
                            Log.Debug(this.GetType().ToString(), string.Format("out_trade_no:【{0}】-trade_no:【{1}】-trade_status:【{2}】", out_trade_no, trade_no, trade_status));
                                                  
    
                            if (trade_status == "TRADE_FINISHED")
                            {
                                //判断该笔订单是否在商户网站中已经做过处理
                                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                                //如果有做过处理,不执行商户的业务程序
    
    
                                //处理业务逻辑  
                                //_orderProcessingService.BathMarkOrderAsPaid(out_trade_no);
    
                                //注意:
                                //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                            }
                            else if (trade_status == "TRADE_SUCCESS")
                            {
                                //判断该笔订单是否在商户网站中已经做过处理
                                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                                //如果有做过处理,不执行商户的业务程序
    
                                //处理业务逻辑                            
                                Log.Info(this.GetType().ToString(), "订单状态更新成功");
    
                                //注意:
                                //付款完成后,支付宝系统发送该交易状态通知
                            }
                            else
                            {
                            }
    
                            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
    
                            Response.Write("success");  //请不要修改或删除
                            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        }
                        else//验证失败
                        {
                            Response.Write("fail");
                        }
                    }
                    else
                    {
                        Response.Write("无通知参数");
                        Log.Info(this.GetType().ToString(), "result:无通知参数");
                    }
                }
                catch (Exception ex)
                {
                    Response.Write("fail");
    
                    Log.Info(this.GetType().ToString(), "Exception:" + ex.Message);
                    _logger.Track(string.Format("支付宝支付异步通知跟踪信息。结果:{0}", ex.Message), FoxconnConsts.APPSETTING_KEY_TRACK_INTERFACE);
                }
    
                Response.End();
                Log.Info(this.GetType().ToString(), "PaymentNotify End......");
                return Content("fail");
            }
    View Code
           /// <summary>
            /// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组
            /// </summary>
            /// <returns>request回来的信息组成的数组</returns>
            public SortedDictionary<string, string> GetRequestPost()
            {
                int i = 0;
                SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
                NameValueCollection coll;
                //Load Form variables into NameValueCollection variable.
                coll = Request.Form;
    
                // Get names of all forms into a string array.
                String[] requestItem = coll.AllKeys;
    
                for (i = 0; i < requestItem.Length; i++)
                {
                    sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
                }
    
                return sArray;
            }
    View Code

    退款接口(即时到账有密退款接口):

    1>调用支付宝支付网关

            /// <summary>
            /// 退款
            /// </summary>
            /// <param name="refundPaymentRequest"></param>
            /// <returns></returns>
            private bool AlipayTradePCRefund(退款实体 refundModel)
            {
                var result = false;
                if (refundModel == null)
                {
                    Log.Error(this.GetType().ToString(), "退款数据不能为空");
                    return result;
                }
                string responseText = string.Empty;
                try
                {
                    #region 调用支付宝退款接口
    
                    string partner = "签约账号";
                    string sign_type = "MD5";//签名方式:MD5、RSA、DSA
                    string key = "MD5密钥";//商户密钥
                    string input_charset = "utf-8";//字符编码格式 目前支持 gbk 或 utf-8
    
                    //服务器异步通知页面路径
                    string notify_url = "http://XXXXXXXX/AliPayment/RefundNotify";
                    Log.Debug(this.GetType().ToString(), "notify_url:" + notify_url);
    
                    //退款当天日期
                    string refund_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    //必填,格式:年[4位]-月[2位]-日[2位] 小时[2位 24小时制]:分[2位]:秒[2位],如:2007-10-01 13:13:13
    
                    //批次号
                    string batch_no = DateTime.UtcNow.ToString("yyyyMMdd") + refundModel.RefundNumber;//?
                    //必填,格式:当天日期[8位]+序列号[3至24位],如:201008010000001
                    Log.Debug(this.GetType().ToString(), "batch_no:" + batch_no);
    
                    //退款笔数
                    string batch_num = "1";
                    //必填,参数detail_data的值中,“#”字符出现的数量加1,最大支持1000笔(即“#”字符出现的数量999个)
    
                    //退款详细数据
                    string detail_data = "";
                    //必填,具体格式请参见接口技术文档
                    StringBuilder sb = new StringBuilder();
    
                    Log.Debug(this.GetType().ToString(), "batch_num:" + batch_num);
                    foreach (var item in 集合)
                    {
                        sb.AppendFormat("{0}^{1}^{2}#", "交易号", "退款金额", "退款原因");
                    }
    
                    if (sb.Length > 0)
                    {
                        detail_data = sb.ToString().Substring(0, sb.ToString().Length - 1);
                    }
    
                    Log.Debug(this.GetType().ToString(), "detail_data:" + detail_data);
    
                    //把请求参数打包成数组
                    SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
                    sParaTemp.Add("service", "refund_fastpay_by_platform_pwd");//调用的接口名,无需修改
                    sParaTemp.Add("partner", partner);//签约账号
                    sParaTemp.Add("_input_charset", _alipayPaymentSettings.InputCharset.ToLower());//字符编码格式 目前支持 gbk 或 utf-8  
                    sParaTemp.Add("notify_url", notify_url);//服务器异步通知页面路径
                    sParaTemp.Add("seller_user_id", _alipayPaymentSettings.SellerId);//收款支付宝账号
                    sParaTemp.Add("refund_date", refund_date);//退款日期
                    sParaTemp.Add("batch_no", batch_no);//批次号
                    sParaTemp.Add("batch_num", batch_num);//退款笔数
                    sParaTemp.Add("detail_data", detail_data);//退款详细数据
    
                    //建立请求
                    Submit submit = new Submit(partner, key, input_charset, sign_type);
                    responseText = submit.BuildRequest(sParaTemp, "get", "确认");
                    
                    #endregion
    
                    _httpContext.Response.Clear();
                    _httpContext.Response.Write(responseText);
                    _httpContext.Response.End();
    
                    result = true;
                }
                catch (Exception ex)
                {
                    responseText = ex.Message;
                    Log.Error(this.GetType().ToString(), "Exception: " + ex.Message);
                }
                Log.Debug(this.GetType().ToString(), string.Format("支付宝退款跟踪信息。GetForm:{0}", responseText));
                Log.Info(this.GetType().ToString(), "Refund End......");
    
                return result;
            }
    View Code

    2>接收支付宝异步通知(post)

            /// <summary>
            /// 支付宝退款异步通知
            /// </summary>
            /// <returns></returns>
            [ValidateInput(false)]
            public ActionResult RefundNotify()
            {
                string result = string.Empty;
                try
                {
                    Log.Info(this.GetType().ToString(), "RefundNotify Start......");
    
                    SortedDictionary<string, string> sPara = GetRequestPost();
                    if (sPara.Count > 0)//判断是否有带返回参数
                    {
                        bool verifyResult = Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
    
                        if (verifyResult)//验证成功
                        {
                            //退款批次号
                            string batch_no = Request.Form["batch_no"];
                            Log.Debug(this.GetType().ToString(), "batch_no:" + batch_no);
    
                            //退款成功总数
                            string success_num = Request.Form["success_num"];
                            Log.Debug(this.GetType().ToString(), "success_num:" + success_num);
    
                            //退款结果明细
                            string result_details = Request.Form["result_details"];
                            Log.Debug(this.GetType().ToString(), "result_details:" + result_details);
    
                            //交易状态
                            //string trade_status = Request.Form["trade_status"];
                            //Log.Info(this.GetType().ToString(), "trade_status:" + trade_status);
    
                            //全额退款情况:trade_status= TRADE_CLOSED,而refund_status=REFUND_SUCCESS 
                            //非全额退款情况:trade_status= TRADE_SUCCESS,而refund_status=REFUND_SUCCESS
                            
    
                            Response.Write("success");  //请不要修改或删除
                        }
                        else//验证失败
                        {
                            Response.Write("fail");
                        }
                    }
                    else
                    {
                        Response.Write("无通知参数");
                    }            
                }
                catch(Exception ex)
                {
                    Log.Info(this.GetType().ToString(), "Exception:" + ex.Message);
    
                    _logger.Track(string.Format("支付宝退款跟踪信息。结果:{0}", ex.Message), FoxconnConsts.APPSETTING_KEY_TRACK_INTERFACE);
                }
                Log.Info(this.GetType().ToString(), "RefundNotify End......");
    
                return Content("fail");
            }
    View Code

    查询接口:

            /// <summary>
            /// 查询订单在支付宝的状态
            /// </summary>
            /// <param name="queryOrderRequest"></param>
            /// <returns></returns>
            private void AlipayTradePCQuery(订单查询实体 orderQuery)
            {
                var result = new 订单查询实体();
                if (orderQuery == null)
                {
                    //"查询数据不能为空"
                    return;
                }
    
                #region 调用支付宝订单查询接口
    
                string partner = "签约账号";
                string sign_type = "MD5";//签名方式:MD5、RSA、DSA
                string key = "MD5密钥";//商户密钥
                string input_charset = "utf-8";//字符编码格式 目前支持 gbk 或 utf-8
    
                //支付宝交易号
                string trade_no = "";
                //支付宝交易号与商户网站订单号不能同时为空
    
                //商户订单号
                string out_trade_no = "";
    
    
                ////////////////////////////////////////////////////////////////////////////////////////////////
    
                //把请求参数打包成数组
                SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
                sParaTemp.Add("service", "single_trade_query");//调用的接口名,无需修改
                sParaTemp.Add("partner", partner);//签约账号
                sParaTemp.Add("_input_charset", input_charset.ToLower());//字符编码格式 目前支持 gbk 或 utf-8
                sParaTemp.Add("trade_no", trade_no);
                sParaTemp.Add("out_trade_no", out_trade_no);//商户订单号,商户网站订单系统中唯一订单号,必填
    
    
                //建立请求
                Submit submit = new Submit(partner, key, input_charset, sign_type);
                string sHtmlText = submit.BuildRequest(sParaTemp);
                XmlDocument xmlDoc = new XmlDocument();
                try
                {
                    xmlDoc.LoadXml(sHtmlText);
                    string isSuccess = xmlDoc.SelectSingleNode("/alipay/is_success").InnerText;
                    if (isSuccess == "T")//请求成功
                    {
                        #region 根据订单状态处理业务数据
    
                        string tradeState = xmlDoc.SelectSingleNode("/alipay/response/trade/trade_status").InnerText;                    
                        if (tradeState == "TRADE_FINISHED" || tradeState == "TRADE_CLOSED" || tradeState == "TRADE_SUCCESS")//支付成功
                        {
                            string transaction_id = xmlDoc.SelectSingleNode("/alipay/response/trade/trade_no").InnerText;
                            //string buyer_id = xmlDoc.SelectSingleNode("/alipay/response/trade/buyer_id").InnerText;
                            string buyer_emial = xmlDoc.SelectSingleNode("/alipay/response/trade/buyer_email").InnerText;
    
                            //处理订单业务
                        }
                        #endregion
                    }
                    else
                    {
                        string error = xmlDoc.SelectSingleNode("/alipay/error").InnerText;
                        result.AddError(string.Format("支付宝PC网站接口查询订单失败![接口返回码:{0}]", error));
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(this.GetType().ToString(), "Exception:" + ex.Message);
                }
                #endregion
            }
    View Code

    3.记录日记类

        public class Log
        {
            //在网站根目录下创建日志目录
            public static string path = HttpRuntime.AppDomainAppPath + "logs\Alipay";
            /**
             * 向日志文件写入调试信息
             * @param className 类名
             * @param content 写入内容
             */
            public static void Debug(string className, string content)
            {
                WriteLog("DEBUG", className, content);
            }
    
            /**
            * 向日志文件写入运行时信息
            * @param className 类名
            * @param content 写入内容
            */
            public static void Info(string className, string content)
            {
                WriteLog("INFO", className, content);
            }
    
            /**
            * 向日志文件写入出错信息
            * @param className 类名
            * @param content 写入内容
            */
            public static void Error(string className, string content)
            {
                WriteLog("ERROR", className, content);
            }
    
            /**
            * 实际的写日志操作
            * @param type 日志记录类型
            * @param className 类名
            * @param content 写入内容
            */
            protected static void WriteLog(string type, string className, string content)
            {
                if (!Directory.Exists(path))//如果日志目录不存在就创建
                {
                    Directory.CreateDirectory(path);
                }
    
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");//获取当前系统时间
                string filename = path + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";//用日期对日志文件命名
    
                //创建或打开日志文件,向日志文件末尾追加记录
                StreamWriter mySw = File.AppendText(filename);
    
                //向日志文件写入内容
                string write_content = time + " " + type + " " + className + ": " + content;
                mySw.WriteLine(write_content);
    
                //关闭日志文件
                mySw.Close();
                mySw.Dispose();
            }
        }
    View Code 
  • 相关阅读:
    BZOJ1085 SCOI2005 骑士精神【IDA* 启发式迭代加深】
    BZOJ1690 Usaco2007 Dec 奶牛的旅行 【01分数规划】
    SPOJ104 Highways 【矩阵树定理】
    BZOJ1597土地购买 【斜率优化DP】
    【模板】NTT
    【模板】FFT
    BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】
    POJ3696 The Windy's 【网络流】
    POJ2728 Desert King 【最优比率生成树】
    BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*
  • 原文地址:https://www.cnblogs.com/ywblog/p/6560093.html
Copyright © 2020-2023  润新知