转自: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