大型網(wǎng)上購物系統(tǒng)除了能讓會員選擇貨到付款結(jié)賬方式外,還應該提供一些更方便快捷的網(wǎng)上支付方式。如果網(wǎng)上商店沒有足夠的實力提供會員直接在網(wǎng)站中建立現(xiàn)金賬戶的功能,就可以將訂單信息轉(zhuǎn)接到支付寶,讓會員從支付寶付款。當然就算會員可以在網(wǎng)站上建立自己的現(xiàn)金賬戶,提供支付寶支付功能也不失為另一種方便快捷的支付方式,這可以給客戶提供更多可選的支付方式。
首先,網(wǎng)上購物系統(tǒng)必須與支付寶公司簽訂合作協(xié)議,以確保從本購物網(wǎng)站上傳到
支付寶網(wǎng)站上的訂單信息能被正確接收。
當會員于購物網(wǎng)站上買下一系列商品并選擇支付寶付款方式后,購物系統(tǒng)即將會員購物的訂單信息轉(zhuǎn)發(fā)到支付寶,網(wǎng)站頁面也會轉(zhuǎn)到支付寶的付款頁面。此時,支付寶頁面會發(fā)送一個驗證信息到本網(wǎng)站以確認支付寶正確收到訂單信息。
會員于支付寶網(wǎng)站付款完成后,網(wǎng)站頁面會重新跳回本購物網(wǎng)站,同時支付寶會將已付款的訂單信息發(fā)回本網(wǎng)站以便對本購物網(wǎng)站的數(shù)據(jù)庫進行必要的修改操作。另外本網(wǎng)站還需要向支付寶網(wǎng)站發(fā)送一個返回信息,告知支付寶本系統(tǒng)已正確收到付款完畢的訂單信息并且已經(jīng)完成對數(shù)據(jù)的處理操作。
向支付寶網(wǎng)站傳送訂單信息時主要參數(shù)的含義:
gateway :支付接口
service:識別是何接口實現(xiàn)何功能的表示
selleremail:商家簽約時的支付寶賬號,即收款的支付寶賬號
key:安全校驗碼,與partner是一組
partner:商戶ID,合作伙伴ID
signtype:加密類型
inputcharset:編碼類型
showurl:展示地址,即在支付寶頁面時商品名稱旁邊的“詳情”的鏈接地址
outtradeno:會員訂單編號,訂單編號必須在本系統(tǒng)中保持唯一
subject:商品名稱,也可稱為訂單名稱,該接口并不是單一的只能買一樣東西,可把一次支付當作一次下訂單
body:商品描述,即備注
totalfee:商品價格,也可稱為訂單的總金額
源碼分析(C#):
首先必須建立一個通知頁面(Notify.aspx)和一個返回頁面(Return.aspx)以接受并驗證從支付寶返回的信息并對數(shù)據(jù)庫中相應的訂單信息做修改處理操作。
Notify.aspx.cs
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
using
System;
using
System.Data;
using
System.Configuration;
using
System.Collections;
using
System.Web;
using
System.Web.Security;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.WebControls.WebParts;
using
System.Web.UI.HtmlControls;
using
System.Text;
using
System.Collections.Specialized;
using
System.IO;
using
Gateway;
///
///
創(chuàng)建該頁面文件時,請留心該頁面文件中無任何HTML代碼及空格。
///
該頁面稱作“通知頁”,是異步被支付寶服務器所調(diào)用。
///
當支付寶的訂單狀態(tài)改變時,支付寶服務器則會自動調(diào)用此頁面,因此請做好自身網(wǎng)站訂單信息與支付寶上的訂單的同步工作
///
public
partial
class
AlipayNotify : System.Web.UI.Page {
protected
void
PageLoad(
object
sender, EventArgs e) {
string
alipayNotifyURL
=
"
https://www.alipay.com/cooperate/gateway.do?service=notifyverify
"
;
//
string alipayNotifyURL = "
http://notify.alipay.com/trade/notifyquery.do?
";
//
此路徑是在上面鏈接地址無法起作用時替換使用。
string
partner
=
""
;
//
partner合作伙伴id(必須填寫)
string
key
=
""
;
//
partner 的對應交易安全校驗碼(必須填寫)
string
inputcharset
=
"
utf-8
"
;
//
編碼類型,完全根據(jù)客戶自身的項目的編碼格式而定,千萬不要填錯。否則極其容易造成MD5加密錯誤。
alipayNotifyURL
=
alipayNotifyURL
+
"
&partner=
"
+
partner
+
"
?ifyid=
"
+
Request.Form[
"
notifyid
"
];
//
獲取支付寶ATN返回結(jié)果,true是正確的訂單信息,false 是無效的
string
responseTxt
=
AliPay.GetHttp(alipayNotifyURL,
120000
);
//
*******加密簽名程序開始*******
int
i; NameValueCollection coll;
//
Load Form variables into NameValueCollection variable.
coll
=
Request.Form;
//
Get names of all forms into a string array.
String[] requestarr
=
coll.AllKeys;
//
進行排序;
string
[] Sortedstr
=
AliPay.BubbleSort(requestarr);
//
構(gòu)造待md5摘要字符串 ;
StringBuilder prestr
=
new
StringBuilder();
for
(i
=
0
; i
<
Sortedstr.Length; i
++
) {
if
(Request.Form[Sortedstr[i]]
!=
""
&&
Sortedstr[i]
!=
"
sign
"
&&
Sortedstr[i]
!=
"
signtype
"
) {
if
(i
==
Sortedstr.Length
-
1
) { prestr.Append(Sortedstr[i]
+
"
=
"
+
Request.Form[Sortedstr[i]]); }
else
{ prestr.Append(Sortedstr[i]
+
"
=
"
+
Request.Form[Sortedstr[i]]
+
"
&
"
); } } } prestr.Append(key);
string
mysign
=
AliPay.GetMD5(prestr.ToString(), inputcharset);
//
*******加密簽名程序結(jié)束*******
string
sign
=
Request.Form[
"
sign
"
];
if
(mysign
==
sign
&&
responseTxt
==
"
true
"
)
//
驗證支付發(fā)過來的消息,簽名是否正確,只要成功進如這個判斷里,則表示該頁面已被支付寶服務器成功調(diào)用
//
但判斷內(nèi)出現(xiàn)自身編寫的程序相關(guān)錯誤導致通知給支付寶并不是發(fā)送success的消息或沒有更新客戶自身的數(shù)據(jù)庫的情況,請自身程序編寫好應對措施,否則查明原因時困難之極
{
if
(Request.Form[
"
tradestatus
"
]
==
"
WAITBUYERPAY
"
)
//
判斷支付狀態(tài)等待買家付款(文檔中有枚舉表可以參考)
{
//
更新自己數(shù)據(jù)庫的訂單語句,請自己填寫一下
string
strOrderNO
=
Request.Form[
"
outtradeno
"
];
//
訂單號
string
strPrice
=
Request.Form[
"
totalfee
"
];
//
金額 如果你申請了商家購物卷功能,在返回信息里面請不要做金額的判斷,否則會校驗通過不了。
}
else
if
(Request.Form[
"
tradestatus
"
]
==
"
TRADEFINISHED
"
||
Request.Form[
"
tradestatus
"
]
==
"
TRADESUCCESS
"
)
//
判斷支付狀態(tài)交易成功結(jié)束(文檔中有枚舉表可以參考)
{
//
更新自己數(shù)據(jù)庫的訂單語句,請自己填寫一下
string
strOrderNO
=
Request.Form[
"
outtradeno
"
];
//
訂單號
string
strPrice
=
Request.Form[
"
totalfee
"
];
//
金額
}
else
{
//
更新自己數(shù)據(jù)庫的訂單語句,請自己填寫一下
} Response.Write(
"
success
"
);
//
返回給支付寶消息,成功,請不要改寫這個success
//
success與fail及其他字符的區(qū)別在于,支付寶的服務器若遇到success時,則不再發(fā)送請求通知(即不再調(diào)用該頁面,讓該頁面再次運行起來),
//
若不是success,則支付寶默認沒有收到成功的信息,則會反復不停地調(diào)用該頁面直到失效,有效調(diào)用時間是24小時以內(nèi)。
//
最好寫TXT文件,以記錄下是否異步返回記錄。
///
/寫文本,紀錄支付寶返回消息,比對md5計算結(jié)果(如網(wǎng)站不支持寫txt文件,可改成寫數(shù)據(jù)庫)
//
string TOEXCELLR = "MD5結(jié)果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;
//
StreamWriter fs = new StreamWriter(Server.MapPath("NotifyDATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);
//
fs.Write(TOEXCELLR);
//
fs.Close();
}
else
{ Response.Write(
"
fail
"
);
//
最好寫TXT文件,以記錄下是否異步返回記錄。
//
寫文本,紀錄支付寶返回消息,比對md5計算結(jié)果(如網(wǎng)站不支持寫txt文件,可改成寫數(shù)據(jù)庫)
string
TOEXCELLR
=
"
MD5結(jié)果:mysign=
"
+
mysign
+
"
,sign=
"
+
sign
+
"
,responseTxt=
"
+
responseTxt; StreamWriter fs
=
new
StreamWriter(Server.MapPath(
"
NotifyDATA/
"
+
DateTime.Now.ToString().Replace(
"
:
"
,
""
))
+
"
.txt
"
,
false
, System.Text.Encoding.Default); fs.Write(TOEXCELLR); fs.Close(); } } }
Return.aspx.cs
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
using
System;
using
System.Data;
using
System.Configuration;
using
System.Collections;
using
System.Web;
using
System.Web.Security;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.WebControls.WebParts;
using
System.Web.UI.HtmlControls;
using
System.Text;
using
System.Collections.Specialized;
using
System.IO;
using
Gateway;
///
///
創(chuàng)建該頁面文件時,請留心該頁面文件是可以對其進行美工處理的,原因在于支付完成以后,當前窗口會從支付寶的頁面跳轉(zhuǎn)回這個頁面。
///
該頁面稱作“返回頁”,是同步被支付寶服務器所調(diào)用,可當作是支付完成后的提示信息頁,如“您的某某某訂單,多少金額已支付成功”。
///
public
partial
class
AlipayReturn : System.Web.UI.Page {
protected
void
PageLoad(
object
sender, EventArgs e) {
string
alipayNotifyURL
=
"
https://www.alipay.com/cooperate/gateway.do?service=notifyverify
"
;
//
string alipayNotifyURL = "
http://notify.alipay.com/trade/notifyquery.do?
";
//
此路徑是在上面鏈接地址無法起作用時替換使用。
string
key
=
""
;
//
partner 的對應交易安全校驗碼(必須填寫)
string
partner
=
""
;
//
partner合作伙伴id(必須填寫)
string
inputcharset
=
"
utf-8
"
;
//
編碼類型,完全根據(jù)客戶自身的項目的編碼格式而定,千萬不要填錯。否則極其容易造成MD5加密錯誤。
alipayNotifyURL
=
alipayNotifyURL
+
"
&partner=
"
+
partner
+
"
?ifyid=
"
+
Request.QueryString[
"
notifyid
"
];
//
獲取支付寶ATN返回結(jié)果,true是正確的訂單信息,false 是無效的
string
responseTxt
=
AliPay.GetHttp(alipayNotifyURL,
120000
);
//
*******加密簽名程序開始
//
*******
int
i; NameValueCollection coll;
//
Load Form variables into NameValueCollection variable.
coll
=
Request.QueryString;
//
Get names of all forms into a string array.
String[] requestarr
=
coll.AllKeys;
//
進行排序;
string
[] Sortedstr
=
AliPay.BubbleSort(requestarr);
//
構(gòu)造待md5摘要字符串 ;
StringBuilder prestr
=
new
StringBuilder();
for
(i
=
0
; i
<
Sortedstr.Length; i
++
) {
if
(Request.Form[Sortedstr[i]]
!=
""
&&
Sortedstr[i]
!=
"
sign
"
&&
Sortedstr[i]
!=
"
signtype
"
) {
if
(i
==
Sortedstr.Length
-
1
) { prestr.Append(Sortedstr[i]
+
"
=
"
+
Request.QueryString[Sortedstr[i]]); }
else
{ prestr.Append(Sortedstr[i]
+
"
=
"
+
Request.QueryString[Sortedstr[i]]
+
"
&
"
); } } } prestr.Append(key);
//
生成Md5摘要;
string
mysign
=
AliPay.GetMD5(prestr.ToString(), inputcharset);
//
*******加密簽名程序結(jié)束*******
string
sign
=
Request.QueryString[
"
sign
"
];
//
Response.Write(prestr.ToString());
//
調(diào)試用,支付寶服務器返回時的完整路徑。
if
(mysign
==
sign
&&
responseTxt
==
"
true
"
)
//
驗證支付發(fā)過來的消息,簽名是否正確
{
//
更新自己數(shù)據(jù)庫的訂單語句,請自己填寫一下
string
strOrderNO
=
Request.QueryString[
"
outtradeno
"
];
//
訂單號
string
strPrice
=
Request.QueryString[
"
totalfee
"
];
//
金額
string
strTradeStatus
=
Request.QueryString[
"
TRADESTATUS
"
];
//
訂單狀態(tài)
Response.Write(
"
訂單號:
"
+
strOrderNO
+
"
金額:
"
+
strPrice);
//
成功,可美化該頁面,提示信息
}
else
{ Response.Write(
"
------------------------------------------
"
); Response.Write(
"
Result:responseTxt=
"
+
responseTxt); Response.Write(
"
Result:mysign=
"
+
mysign); Response.Write(
"
Result:sign=
"
+
sign); Response.Write(
"
支付失敗
"
);
//
支付失敗,提示信息
} } }
除此之外在Notify.aspx頁面和Return.aspx頁面公用的一些方法,可以提取出來放在一個公共的類里面(Alipay.cs)
Alipay.cs
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
using
System.Web;
using
System.Text;
using
System.Security.Cryptography;
using
System.IO;
using
System.Net;
using
System;
///
///
New Interface for AliPay
///
namespace
Gateway {
public
class
AliPay {
///
///
與ASP兼容的MD5加密算法
///
public
static
string
GetMD5(
string
s,
string
inputcharset) { MD5 md5
=
new
MD5CryptoServiceProvider();
byte
[] t
=
md5.ComputeHash(Encoding.GetEncoding(inputcharset).GetBytes(s)); StringBuilder sb
=
new
StringBuilder(
32
);
for
(
int
i
=
0
; i
<
t.Length; i
++
) { sb.Append(t[i].ToString(
"
x
"
).PadLeft(
2
,
“
0
“
)); }
return
sb.ToString(); }
///
///
冒泡排序法
///
按照字母序列從a到z的順序排列
///
public
static
string
[] BubbleSort(
string
[] r) {
int
i, j;
//
交換標志
string
temp;
bool
exchange;
for
(i
=
0
; i
<
r.Length; i
++
)
//
最多做R.Length-1趟排序
{ exchange
=
false
;
//
本趟排序開始前,交換標志應為假
for
(j
=
r.Length
-
2
; j
>=
i; j
--
) {
//
交換條件
if
(System.String.CompareOrdinal(r[j
+
1
], r[j])
<
0
) { temp
=
r[j
+
1
]; r[j
+
1
]
=
r[j]; r[j]
=
temp; exchange
=
true
;
//
發(fā)生了交換,故將交換標志置為真
} }
if
(
!
exchange)
//
本趟排序未發(fā)生交換,提前終止算法
{
break
; } }
return
r; }
///
///
生成URL鏈接或加密結(jié)果
///
///
參數(shù)加密數(shù)組
///
編碼格式
///
加密類型
///
安全校驗碼
///
字符串URL或加密結(jié)果
public
static
string
CreatUrl(
//
string gateway,
//
GET方式傳遞參數(shù)時請去掉注釋
string
[] para,
string
inputcharset,
string
signtype,
string
key ) {
int
i;
//
進行排序;
string
[] Sortedstr
=
BubbleSort(para);
//
構(gòu)造待md5摘要字符串 ;
StringBuilder prestr
=
new
StringBuilder();
for
(i
=
0
; i
<
Sortedstr.Length; i
++
) {
if
(i
==
Sortedstr.Length
-
1
) { prestr.Append(Sortedstr[i]); }
else
{ prestr.Append(Sortedstr[i]
+
"
&
"
); } } prestr.Append(key);
//
生成Md5摘要;
string
sign
=
GetMD5(prestr.ToString(), inputcharset);
//
以下是POST方式傳遞參數(shù)
return
sign;
//
以下是GET方式傳遞參數(shù)
//
構(gòu)造支付Url;
//
char[] delimiterChars = { “=“};
//
StringBuilder parameter = new StringBuilder();
//
parameter.Append(gateway);
//
for (i = 0; i < Sortedstr.Length; i++)
//
{
//
UTF-8格式的編碼轉(zhuǎn)換
//
parameter.Append(Sortedstr[i].Split(delimiterChars)[0] + "=" + HttpUtility.UrlEncode(Sortedstr[i].Split(delimiterChars)[1]) + "&");
//
}
//
//
parameter.Append("sign=" + sign + "&signtype=" + signtype);
//
//
//
返回支付Url;
//
return parameter.ToString();
}
//
獲取遠程服務器ATN結(jié)果,驗證是否是支付寶服務器發(fā)來的請求
public
static
string
GetHttp(
string
astrUrl,
int
timeout) {
string
strResult;
try
{ HttpWebRequest myReq
=
(HttpWebRequest)HttpWebRequest.Create(astrUrl); 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; } } }
以上三個文件建之后,就可以在需要的地方對支付寶接口進行調(diào)用以完成支付寶支付的功能了(Default.aspx.cs)
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
using
System;
using
System.Data;
using
System.Configuration;
using
System.Web;
using
System.Web.Security;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.WebControls.WebParts;
using
System.Web.UI.HtmlControls;
using
Gateway;
public
partial
class
Default : System.Web.UI.Page {
protected
void
PageLoad(
object
sender, EventArgs e) { }
protected
void
BtnAlipayClick(
object
sender, EventArgs e) {
//
業(yè)務參數(shù)賦值;
string
gateway
=
"
https://www.alipay.com/cooperate/gateway.do?
"
;
//
支付接口
string
service
=
"
createdirectpaybyuser
"
;
//
服務名稱,這個是識別是何接口實現(xiàn)何功能的標識,請勿修改
string
selleremail
=
""
;
//
商家簽約時的支付寶帳號,即收款的支付寶帳號
string
signtype
=
"
MD5
"
;
//
加密類型,簽名方式“不用改”
string
key
=
""
;
//
安全校驗碼,與partner是一組,獲取方式是:用簽約時支付寶帳號登陸支付寶網(wǎng)站www.alipay.com,在商家服務我的商家里即可查到。
string
partner
=
""
;
//
商戶ID,合作身份者ID,合作伙伴ID
string
inputcharset
=
"
utf-8
"
;
//
編碼類型,完全根據(jù)客戶自身的項目的編碼格式而定,千萬不要填錯。否則極其容易造成MD5加密錯誤。
string
showurl
=
"
http://www.alipay.com/
"
;
//
展示地址,即在支付頁面時,商品名稱旁邊的“詳情”的鏈接地址。
string
outtradeno
=
TxtOrderno.Text.Trim();
//
客戶自己的訂單號,訂單號必須在自身訂單系統(tǒng)中保持唯一性
string
subject
=
TxtSubject.Text.Trim();
//
商品名稱,也可稱為訂單名稱,該接口并不是單一的只能買一樣東西,可把一次支付當作一次下訂單
string
body
=
TxtBody.Text.Trim();
//
商品描述,即備注
string
totalfee
=
TxtTotalfee.Text.Trim();
//
商品價格,也可稱為訂單的總金額
//
服務器通知url(AlipayNotify.aspx文件所在路經(jīng)),必須是完整的路徑地址
string
notifyurl
=
"
http://localhost:8978/directvs2005utf/AlipayNotify.aspx
"
;
//
服務器返回url(AlipayReturn.aspx文件所在路經(jīng)),必須是完整的路徑地址
string
returnurl
=
"
http://localhost:8978/directvs2005utf/AlipayReturn.aspx
"
;
//
構(gòu)造數(shù)組;
//
以下數(shù)組即是參與加密的參數(shù),若參數(shù)的值不允許為空,若該參數(shù)為空,則不要成為該數(shù)組的元素
string
[] para
=
{
"
service=
"
+
service,
"
partner=
"
+
partner,
"
selleremail=
"
+
selleremail,
"
outtradeno=
"
+
outtradeno,
"
subject=
"
+
subject,
"
body=
"
+
body,
"
totalfee=
"
+
totalfee,
"
showurl=
"
+
showurl,
"
paymenttype=1
"
,
"
notifyurl=
"
+
notifyurl,
"
returnurl=
"
+
returnurl,
"
inputcharset=
"
+
inputcharset };
//
支付URL生成
string
aliayurl
=
AliPay.CreatUrl(
//
gateway,
//
GET方式傳遞參數(shù)時請去掉注釋
para, inputcharset, signtype, key );
//
以下是GET方式傳遞參數(shù)
//
Response.Redirect(aliayurl);
//
以下是POST方式傳遞參數(shù)
Response.Write(
"
"
); Response.Write(
"
"
+
service
+
"
>
"
); Response.Write(
"
"
+
partner
+
"
>
"
); Response.Write(
"
"
+
selleremail
+
"
>
"
); Response.Write(
"
"
+
outtradeno
+
"
>
"
); Response.Write(
"
"
+
subject
+
"
>
"
); Response.Write(
"
"
+
body
+
"
>
"
); Response.Write(
"
"
+
totalfee
+
"
>
"
); Response.Write(
"
"
+
showurl
+
"
>
"
); Response.Write(
"
"
+
returnurl
+
"
>
"
); Response.Write(
"
"
+
notifyurl
+
"
>
"
); Response.Write(
"
"
); Response.Write(
"
"
+
aliayurl
+
"
>
"
); Response.Write(
"
"
+
signtype
+
"
>
"
); Response.Write(
"
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

