1. 程式人生 > >asp .net mvc支付寶支付服務端demo

asp .net mvc支付寶支付服務端demo

本來支付寶支付不需要服務端提供什麼程式碼的,最多就是儲存一些公鑰和私鑰,但是為了安全,最好還是要在服務端提供支付寶的回撥,畢竟客戶端是不可相信的。

看了一下支付寶的開發文件,比微信支付的開發文件詳細得多,微信開發文件,我竟然沒找到服務端的一些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次還是幾次,忘記了,最後處理完,也要給支付寶發一個接收成功的訊息,表明我接收到了回撥。