DiscuzNT 商品交易插件设计之[线上交易]业务流程
在上一篇中, 我們了解了為提供支付寶在線支付功能,所需要的一些助手(helper)類, 在
本文中,我們將會以一個線上支付流程來進一步介紹業務設計上的一些內容和思想。
在之前的線下支付流程中,我們看到交易是靠買賣雙方不斷更新本地的交易狀態來進行推
動的。而線上支付這個過程的推動主要靠支付寶那面的操作來完成,而本地服務器只是提供了
交易信息并進行跳轉(到支付寶)。并接受支付寶回傳過來的交易信息,來更新本地數據庫中的
交易狀態并發送站內消息給買家或者賣家。
了解了上面的信息之后,我們通過一個簡單的例子來加以說明,同時按“老規矩”,在介
紹過程中穿插對源代碼的講解。
當我們在商品顯示頁面中點擊立即購買按鈕之后,如下圖:
我們會進入到“確認購買信息”頁面,如下圖:
當在“確認購買信息”頁面中的交易方式選項中選擇“支付寶在線交易”選項后,如上圖所示,
點擊確認購買后,系統會提示“交易單已創建”的成功信息,如下圖所示:
然后系統會將頁面重定向到onlinetrade.aspx頁,如下所示:
當我們點擊使用支付寶支付的按鈕之后,系統會創建訂單如下所示:
然后跳轉到支付寶交易頁面。如下圖:
在點擊“支付寶交易.付款”按鈕后并正確輸入相應登陸信息,我們就可以使用支付寶來逐步
完成交易流程了,因為這塊操作只有使用過支付寶的朋友都有心得,所以就不再多說了。我們
假設在支付寶平臺上付了款之后,這里支付寶會回傳數據到我們的本地服務器上,而我們本地
接受回傳數據并返回確認信息的頁面是tradenofity.aspx(參見源代碼cs文件),其內容如下
(詳見注釋):
///<summary>
///交易狀態通知頁面
///</summary>
publicclasstradenotify:PageBase
{
protectedoverridevoidShowPage()
{
if(CheckPayment())
{
Goodstradeloginfogoodstradeloginfo=TradeLogs.GetGoodsTradeLogInfo(DNTRequest.GetString("out_trade_no"));
if(goodstradeloginfo!=null&&goodstradeloginfo.Id>0)
{
switch(DNTRequest.GetString("trade_status"))
{
case"WAIT_BUYER_PAY"://等待買家付款
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_BUYER_PAY;break;
}
case"WAIT_SELLER_CONFIRM_TRADE"://交易已創建,等待賣家確認
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_SELLER_CONFIRM_TRADE;break;
}
case"WAIT_SYS_CONFIRM_PAY": //確認買家付款中,暫勿發貨
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_SYS_CONFIRM_PAY;break;
}
case"WAIT_SELLER_SEND_GOODS"://支付寶收到買家付款,請賣家發貨
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_SELLER_SEND_GOODS;break;
}
case"WAIT_BUYER_CONFIRM_GOODS"://賣家已發貨,買家確認中
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_BUYER_CONFIRM_GOODS;break;
}
case"WAIT_SYS_PAY_SELLER"://買家確認收到貨,等待支付寶打款給賣家
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_SYS_PAY_SELLER;break;
}
case"TRADE_FINISHED"://交易成功結束
{
goodstradeloginfo.Status=(int)TradeStatusEnum.TRADE_FINISHED;break;
}
case"TRADE_CLOSED"://交易中途關閉(未完成)
{
goodstradeloginfo.Status=(int)TradeStatusEnum.TRADE_CLOSED;break;
}
case"WAIT_SELLER_AGREE"://等待賣家同意退款
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_SELLER_AGREE;break;
}
case"SELLER_REFUSE_BUYER"://賣家拒絕買家條件,等待買家修改條件
{
goodstradeloginfo.Status=(int)TradeStatusEnum.SELLER_REFUSE_BUYER;break;
}
case"WAIT_BUYER_RETURN_GOODS"://賣家同意退款,等待買家退貨
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_BUYER_RETURN_GOODS;break;
}
case"WAIT_SELLER_CONFIRM_GOODS"://等待賣家收貨
{
goodstradeloginfo.Status=(int)TradeStatusEnum.WAIT_SELLER_CONFIRM_GOODS;break;
}
case"REFUND_SUCCESS"://退款成功
{
goodstradeloginfo.Status=(int)TradeStatusEnum.REFUND_SUCCESS;break;
}
}
goodstradeloginfo.Lastupdate=DateTime.Now;
TradeLogs.UpdateTradeLog(goodstradeloginfo,goodstradeloginfo.Status,true);
}
HttpContext.Current.Response.Write("success");//返回給支付寶消息,成功
}
else
{
HttpContext.Current.Response.Write("fail");
}
}
///<summary>
///獲取遠程服務器ATN結果
///</summary>
///<paramname="a_strUrl"></param>
///<paramname="timeout"></param>
///<returns></returns>
publicStringGet_Http(StringstrUrl,inttimeout)
{
stringstrResult;
try
{
HttpWebRequestmyReq=(HttpWebRequest)HttpWebRequest.Create(strUrl);
myReq.Timeout=timeout;
HttpWebResponseHttpWResp=(HttpWebResponse)myReq.GetResponse();
StreammyStream=HttpWResp.GetResponseStream();
StreamReadersr=newStreamReader(myStream,Encoding.UTF8);
StringBuilderstrBuilder=newStringBuilder();
while(-1!=sr.Peek())
{
strBuilder.Append(sr.ReadLine());
}
strResult=strBuilder.ToString();
}
catch(Exceptionexp)
{
strResult="錯誤:"+exp.Message;
}
returnstrResult;
}
///<summary>
///檢查支付結果
///</summary>
///<returns></returns>
privateboolCheckPayment()
{
AliPayConfigInfoaliPayConfigInfo=TradeConfigs.GetConfig().Alipayconfiginfo;
stringalipay_notify_url="https://www.alipay.com/cooperate/gateway.do?";
stringkey=aliPayConfigInfo.Sign;//partner的對應交易安全校驗碼(必須填寫)
string_input_charset=aliPayConfigInfo.Inputcharset;
stringpartner=aliPayConfigInfo.Partner;//partner合作伙伴id(必須填寫)
alipay_notify_url=alipay_notify_url+"service=notify_verify"+"&partner="+partner+
"¬ify_id="+DNTRequest.GetString("notify_id");
//獲取支付寶ATN返回結果,true是正確的訂單信息,false是無效的
stringresponseTxt=Get_Http(alipay_notify_url,120000);
//排序
string[]Sortedstr=System.Web.HttpContext.Current.Request.Form.AllKeys;
AliPayment.QuickSort(Sortedstr,0,Sortedstr.Length-1);
//構造待md5摘要字符串
StringBuilderprestr=newStringBuilder();
for(inti=0;i<Sortedstr.Length;i++)
{
if(DNTRequest.GetString(Sortedstr[i])!=""&&Sortedstr[i]!="sign"&&Sortedstr[i]!="sign_type")
{
if(i==Sortedstr.Length-1)
{
prestr.Append(Sortedstr[i]+"="+DNTRequest.GetString(Sortedstr[i]));
}
else
{
prestr.Append(Sortedstr[i]+"="+DNTRequest.GetString(Sortedstr[i])+"&");
}
}
}
prestr.Append(key);
//生成Md5摘要
stringmysign=AliPayment.GetMD5(prestr.ToString(),_input_charset);
//驗證支付發過來的消息,簽名是否正確
if(mysign==DNTRequest.GetString("sign")&&responseTxt=="true")
{
returntrue;
}
else
{
returnfalse;
}
}
}
上面的頁面用于接受支付寶post過來的數據,并對其有效性進行校驗,以避免是其它惡意請求。
這部分的工作是通過CheckPayment()方法來完成的。
當校驗通過后,就要進行更新交易狀態的操作了,正如我在線下支付一文中所說的,交易狀態
共有17種,這里只有主要的交易狀態進行了綁定并進行更新,參見如下代碼:
TradeLogs.UpdateTradeLog(goodstradeloginfo,goodstradeloginfo.Status,true);
而UpdateTradeLog方法在線下交易一文中已介紹過,這里就不多說了。
需要注意的一點就是,如果我們要想在本地測試該項功能,需要找網管協助將我們的機器IP地
址綁定(公布)到網上,使支付寶能夠訪問我們調試的機器,只有這樣交易信息才能正常發送過來。
當交易狀態更新結束之后,我們還要向支付寶平臺發送一個確認信息,以通知它我們已收到了
它發過來的交易信息。如果不這樣做的話,支付寶就會每隔一段時間來敲您網站的大門,不停的向
您發送該交易信息了。
當然這時相對于買家已經向交易成功邁出了第一步,而賣家因為本地數據庫中交易狀態已更新,
同時也收到了買家已付款的站內短消息(UpdateTradeLog方法中實現)。這時就要登陸支付寶平
臺來進行發貨或其它與本次交易有關的操作了,而這部分的內容很接近于線下支付流程,只不過是
將這個業務過程搬到了支付寶上來而已,這里就不再多說什么了。
到這里系統要做的就是不停的接受支付寶post過來的交易數據來更新本地數據庫中的交易狀態,
從而最終完成本次交易操作。當買賣雙方交易完成后,依舊會像在線下支付流程一樣,出現進行雙
方互評的交易鏈接,以便為信用機制提供數據支持,如下圖所示:
點擊后,我們會進入到評價頁面,如下:
當評價完成后,我們就可以去信用頁面看當前買賣雙方的信用,好評率等信息了,而信用機
制這方面的內容,會在下一篇文章中詳加說明。
到這里,我們完成了一個線上交易。當然我們可以通“用戶中心”來查看我們關注或進行中的
交易等信息,如下圖所示:
好了,今天的內容就先到這里。
tag:alipay,支付寶,discuznt,online trade,在線交易
作者:代震軍,daizhj
原文鏈接:http://www.cnblogs.com/daizhj/archive/2008/08/18/1270227.html
總結
以上是生活随笔為你收集整理的DiscuzNT 商品交易插件设计之[线上交易]业务流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构+算法面试100题~~~摘自CS
- 下一篇: 网站程序IIS布署问题备忘录