轉自:http://www.kwstu.com/ArticleView/netmvc_201511132005431321java
最近開發手機app須要實現移動支付功能,因爲考慮支付安全將支付寶生成簽名寫到了服務器端,官網給的demo是在客戶端的,糾結了幾天終於實現了。api
注本教程不對支付寶申請,移動開發配置作解釋,核心須要注意的地方就是在官方下載的demo中有生成私鑰跟公鑰的工具,公鑰須要在商家管理後臺跟支付寶作交換,這個很關鍵,筆者在調試的時候出現錯誤了,最後問支付寶官方客服要了這幾個信息。安全
開發思路:下載支付寶移動支付demo,根據demo的代碼從新寫服務器端,而後將生成的簽名信息替換demo裏面參數測試服務器端的代碼是否成功,而後在寫服務器端的返回成功處理程序。服務器
廢話很少說了直接上代碼吧網絡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
//第一步去支付寶付款,根據支付寶返回結果進行處理,若是成功須要生成會員記錄、充值記錄、廣告位記錄
//第一步開始
//支付類型
string
payment_type =
"1"
;
//必填,不能修改
//服務器異步通知頁面路徑
//string notify_url = "http://" + HttpContext.Request.Url.Host.ToString() + "/ZwOnLine/notifyUrl";
//需http://格式的完整路徑,不能加?id=123這類自定義參數
//頁面跳轉同步通知頁面路徑
//需http://格式的完整路徑,不能加?id=123這類自定義參數,不能寫成http://localhost/
//賣家支付寶賬戶
string
seller_id =
"***"
;
//必填
//商戶訂單號
string
out_trade_no = checkId;
//商戶網站訂單系統中惟一訂單號,必填
//訂單名稱
string
subject = unitBase.NAME +
"["
+ zphBase.ZPHNAME +
"("
+ zphZwService.ZWID +
")]"
;
//必填
//付款金額
//string total_fee = "0.1";
string
total_fee = price;
//必填
//訂單描述
string
body = unitBase.NAME +
"於"
+ DateTime.Now.ToString(
"yyyy-MM-dd"
) +
"在線預訂「"
+ zphBase.ZPHNAME +
"」的"
+ zphZwService.ZWID +
"號展位,繳費"
+ price +
"元。"
;
//防釣魚時間戳
//string anti_phishing_key = "";
//若要使用請調用類文件submit中的query_timestamp函數
//超時時間須要動態計算,而且減去2,若是超時時間小於2是否讓繼續支付。
TimeSpan time = DateTime.Now - Convert.ToDateTime(zphZwService.LOCKDATE);
int
minTmp = 10 - ((
int
)time.TotalMinutes);
string
minStr =
""
;
if
(minTmp >= 2)
minStr = (minTmp - 1) +
"m"
;
else
if
(minTmp <= 1)
return
ClassesLib.ToJson(
new
{
success =
false
,
msg =
"操做失敗,剩餘支付時間不足,請從新選擇展位!"
,
error_code =
"400"
});
////////////////////////////////////////////////////////////////////////////////////////////////
string
signStr =
"partner=\""
+ Config.Partner +
"\"&seller_id=\"****\"&out_trade_no=\""
+ out_trade_no +
"\"&subject=\""
+ subject +
"\"&body=\""
+ body +
"\"&total_fee=\"0.01\"¬ify_url=\""
+ notify_url +
"\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&return_url=\"m.alipay.com\""
;
string
retrnStr =
"partner=\""
+ Config.Partner +
"\"&seller_id=\"****\"&out_trade_no=\""
+ out_trade_no +
"\"&subject=\""
+ subject +
"\"&body=\""
+ body +
"\"&total_fee=\"0.01\"¬ify_url=\""
+ notify_url +
"\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&return_url=\"m.alipay.com\"&sign=\""
+ HttpUtility.UrlEncode(RSAFromPkcs8.sign(signStr, Config.Private_key, Config.Input_charset), System.Text.Encoding.UTF8) +
"\"&sign_type=\"RSA\""
;
|
1
2
3
|
// 完整的符合支付寶參數規範的訂單信息
//final String payInfo= orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
final
String payInfo=
"partner=\"*****\"&seller_id=\"*****\"&out_trade_no=\"ZFB_201511111751182080\"&subject=\"酷網網絡工做室[2015-11-21(週六)綜合人才招聘會(A012)]\"&body=\"酷網網絡工做室於2015-11-11在線預訂「2015-11-21(週六)綜合人才招聘會」的A012號展位,繳費200元。\"&total_fee=\"0.01\"¬ify_url=\"http://api.kwstu.com/Pay/NotifyUrl\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&return_url=\"m.alipay.com\"&sign=\"KbCV%2bHvHhGHuE%2fSxFjaXQJ9BP%2bY5m7bR9IxGKL7nk%2bz%2fxI%2fNALY21XEgAFOhGbzCTwer02FSKI2oadw9ChHYIhyC7f6o3vWl18k01o34hyrCexXfSP36ZkZ4k2V0ABaHGbrBLOPD73SewPtfxEfiJj88JJIDEbYI9CU%2bFhJWEHo%3d\"&sign_type=\"RSA\""
;
|
將final String payInfo= orderInfo + "&sign=\"" + sign + "\"&" + getSignType();代碼註釋直接賦值returnStr的值便可mvc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/// <summary>
/// 功能:服務器異步通知頁面
/// 版本:3.3
/// 日期:2012-07-10
/// 說明:
/// 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。
/// 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。
///
/// ///////////////////頁面功能說明///////////////////
/// 建立該頁面文件時,請留心該頁面文件中無任何HTML代碼及空格。
/// 該頁面不能在本機電腦測試,請到服務器上作測試。請確保外部能夠訪問該頁面。
/// 該頁面調試工具請使用寫文本函數logResult。
/// 若是沒有收到該頁面返回的 success 信息,支付寶會在24小時內按必定的時間策略重發通知
/// </summary>
public
ActionResult NotifyUrl()
{
SortedDictionary<
string
,
string
> sPara = GetRequestPost();
ClassesLib.InsertLog(
"1(notifyUrl)"
);
if
(sPara.Count > 0)
//判斷是否有帶返回參數
{
ClassesLib.InsertLog(
"2(notifyUrl)"
);
Notify aliNotify =
new
Notify();
bool
verifyResult = aliNotify.Verify(sPara, Request.Form[
"notify_id"
], Request.Form[
"sign"
]);
ClassesLib.InsertLog(
"--"
+
"notify_id:"
+ Request.Form[
"notify_id"
] +
"--"
+
"sign:"
+ Request.Form[
"sign"
]);
//——請根據您的業務邏輯來編寫程序(如下代碼僅做參考)——
//獲取支付寶的通知返回參數,可參考技術文檔中服務器異步通知參數列表
//商戶訂單號 string out_trade_no = Request.Form["out_trade_no"];
string
out_trade_no = Request.Form[
"out_trade_no"
];
ClassesLib.InsertLog(
"--"
+
"out_trade_no:"
+ Request.Form[
"out_trade_no"
]);
//支付寶交易號 string trade_no = Request.Form["trade_no"];
string
trade_no = Request.Form[
"trade_no"
];
ClassesLib.InsertLog(
"--"
+
"trade_no:"
+ Request.Form[
"trade_no"
]);
//交易狀態
string
trade_status = Request.Form[
"trade_status"
];
ClassesLib.InsertLog(
"--"
+
"trade_status:"
+ Request.Form[
"trade_status"
]);
if
(verifyResult)
//驗證成功
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//請在這裏加上商戶的業務邏輯程序代碼
if
(Request.Form[
"trade_status"
] ==
"TRADE_FINISHED"
)
{
ClassesLib.InsertLog(out_trade_no +
"訂單狀態正常(notifyUrl)"
);
//判斷該筆訂單是否在商戶網站中已經作過處理
//若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序
//若是有作過處理,不執行商戶的業務程序
//注意:
//該種交易狀態只在兩種狀況下出現
//一、開通了普通即時到帳,買家付款成功後。
//二、開通了高級即時到帳,從該筆交易成功時間算起,過了簽約時的可退款時限(如:三個月之內可退款、一年之內可退款等)後。
}
else
if
(Request.Form[
"trade_status"
] ==
"TRADE_SUCCESS"
)
{
ClassesLib.InsertLog(out_trade_no +
"訂單狀態正常(notifyUrl)"
);
//判斷該筆訂單是否在商戶網站中已經作過處理
//若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序
//若是有作過處理,不執行商戶的業務程序
//注意:
//該種交易狀態只在一種狀況下出現——開通了高級即時到帳,買家付款成功後。
}
else
{
ClassesLib.InsertLog(out_trade_no +
"狀態錯誤(notifyUrl)"
);
return
Content(
"trade_status="
+ Request.QueryString[
"trade_status"
]);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else
//驗證失敗
{
ClassesLib.InsertLog(out_trade_no +
"驗證失敗(notifyUrl)"
);
return
Content(
"驗證失敗"
);
}
}
else
{
ClassesLib.InsertLog(
"無返回參數(notifyUrl)"
);
return
Content(
"無返回參數"
);
}
}
|
開發資料獲取地址:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-8489738063.2.VrK9RN&id=524269482340app