此为原文转载!作者技术支持QQ:806693619
最近开发手机app需要实现移动支付功能,由于考虑支付安全将微信支付生成签名写到了服务器端,官网给的demo是在客户端的,纠结了几天终于实现了。
注本教程不对微信支付申请,移动开发配置做解释。
开发思路:下载微信移动支付demo,根据demo的代码重新写服务器端,然后将生成的签名信息替换demo里面参数测试服务器端的代码是否成功,然后在写服务器端的返回成功处理程序。
废话不多说了直接上代码吧
1、C#生成支付签名代码
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
|
/// <summary>
/// 生成微信支付签名,生成结果直接在可以端提交即可
/// </summary>
/// <returns></returns>
public
static
string
partnerid =
""
;
//PartnerID
public
static
string
partnerkey =
""
;
//PartnerKey
public
static
string
mchid =
""
;
//mchid
public
static
string
appId =
""
;
//appid
public
static
string
appsecret =
""
;
//appsecret
public
static
string
appkey =
""
;
//paysignkey(非appkey 在微信商户平台设置 (md5)111111111111)
public
static
string
timeStamp =
""
;
//时间戳
public
static
string
nonceStr =
""
;
//随机字符串
public
static
string
notify_url =
"http://api.kwstu.com/Pay/WxNotifyUrl"
; //支付完成后的回调处理页面,*替换成notify_url.asp所在路径
public
static
string
prepayId =
""
;
//预支付ID
public
static
string
sign =
""
;
//为了获取预支付ID的签名
public
static
string
paySign =
""
;
//进行支付需要的签名
public
static
string
package =
""
;
//进行支付需要的包
public
HttpResponseMessage PostWxConfirmPay()
{
//生成订单业务逻辑代码
//创建支付应答对象
var packageReqHandler =
new
RequestHandler();
//初始化
packageReqHandler.init();
timeStamp = TenpayUtil.getTimestamp();
nonceStr = TenpayUtil.getNoncestr();
//设置package订单参数
packageReqHandler.setParameter(
"appid"
, appId);
packageReqHandler.setParameter(
"body"
, unitBase.NAME +
"于"
+ DateTime.Now.ToString(
"yyyy-MM-dd"
) +
"在线预订“"
+ zphBase.ZPHNAME +
"”的"
+ zphZwService.ZWID +
"号展位,缴费"
+ price +
"元。"
);
//商品信息 127字符
packageReqHandler.setParameter(
"mch_id"
, mchid);
packageReqHandler.setParameter(
"nonce_str"
, nonceStr.ToLower());
packageReqHandler.setParameter(
"notify_url"
, notify_url);
packageReqHandler.setParameter(
"out_trade_no"
, checkId);
//商家订单号
packageReqHandler.setParameter(
"spbill_create_ip"
, HttpContext.Current.Request.UserHostAddress);
//用户的公网ip,不是商户服务器IPHttpContext.Current.Request.UserHostAddress
packageReqHandler.setParameter(
"total_fee"
, (
int
.Parse(price)*100).ToString());
//商品金额,以分为单位(money * 100).ToString()
packageReqHandler.setParameter(
"trade_type"
,
"APP"
);
//获取package包
sign = packageReqHandler.CreateMd5Sign(
"key"
, appkey);
packageReqHandler.setParameter(
"sign"
, sign);
string
data = packageReqHandler.parseXML();
//获取预支付ID
var xdoc =
new
XmlDocument();
xdoc.LoadXml(prepayXml);
XmlNode xn = xdoc.SelectSingleNode(
"xml"
);
XmlNodeList xnl = xn.ChildNodes;
if
(xnl.Count > 7)
{
prepayId = xnl[7].InnerText;
package =
string
.Format(
"prepay_id={0}"
, prepayId);
}
//设置支付参数
var paySignReqHandler =
new
RequestHandler();
paySignReqHandler.setParameter(
"appid"
, appId);
paySignReqHandler.setParameter(
"noncestr"
, nonceStr.ToLower());
paySignReqHandler.setParameter(
"package"
,
"Sign=WXPay"
);
paySignReqHandler.setParameter(
"partnerid"
, partnerid);
paySignReqHandler.setParameter(
"prepayid"
, prepayId);
paySignReqHandler.setParameter(
"timestamp"
, timeStamp);
paySign = paySignReqHandler.CreateMd5Sign(
"key"
, appkey);
var reList =
new
List<WxPayListModel>();
var reModel =
new
WxPayListModel();
reModel.appid = appId;
reModel.noncestr = nonceStr.ToLower();
reModel.package =
"Sign=WXPay"
;
reModel.partnerid = partnerid;
reModel.prepayid = prepayId;
reModel.timestamp = timeStamp;
reModel.sign = paySign;
reList.Add(reModel);
}
|
最终返回Json样例:
{"success":true,"msg":"操作成功","infor":[{"appid":"****","noncestr":"a532400ed62e772b9dc0b86f46e583ff","package":"Sign=WXPay","partnerid":"****","prepayid":"wx201511131946145c0b1467a10409581615","timestamp":"1447415119","sign":"3C2DC5263023BA69A268E353171DB0A0"}]}
替换客户端demo支付参数进行测试
1
2
3
4
5
6
7
8
9
10
11
|
private
void
sendPayReq() {
msgApi.registerApp(Constants.APP_ID);
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
req.prepayId =
"wx201511131946145c0b1467a10409581615"
;
req.packageValue =
"Sign=WXPay"
;
req.nonceStr =
"a532400ed62e772b9dc0b86f46e583ff"
;
req.timeStamp =
"1447415119"
;
req.sign =
"3C2DC5263023BA69A268E353171DB0A0"
;
msgApi.sendReq(req);
}
|
服务端支付成功处理代码
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
ResponseHandler resHandler =
new
ResponseHandler(
null
);
//if (!resHandler.IsTenpaySign())//验证签名
//{
// LogUtil.WriteLog("sign error");
// return;
//}
//resHandler.SetKey(PayConfig.AppKey);
ClassesLib.InsertLog(
"微信支付成功1"
);
#region 解析参数
//SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查
string
return_code = resHandler.GetParameter(
"return_code"
);
ClassesLib.InsertLog(
"微信支付成功2"
+ return_code);
//返回信息,如非空,为错误原因签名失败参数格式校验错误
string
return_msg = resHandler.GetParameter(
"return_msg"
);
ClassesLib.InsertLog(
"微信支付成功3"
+ return_msg);
if
(return_code.ToUpper() !=
"SUCCESS"
)
{
//LogUtil.WriteLog("return_code faild:" + return_msg);
return
Content(
"验证失败"
);
}
#region 以下字段在 return_code 为 SUCCESS 的时候有返回
//业务结果 SUCCESS/FAIL
string
result_code = resHandler.GetParameter(
"result_code"
);
ClassesLib.InsertLog(
"微信支付成功4"
+ result_code);
//微信分配的公众账号 ID
string
appid = resHandler.GetParameter(
"appid"
);
ClassesLib.InsertLog(
"微信支付成功5"
+ appid);
//微信支付分配的商户号
string
mch_id = resHandler.GetParameter(
"mch_id"
);
ClassesLib.InsertLog(
"微信支付成功6"
+ mch_id);
//微信支付分配的终端设备号
string
device_info = resHandler.GetParameter(
"device_info"
);
ClassesLib.InsertLog(
"微信支付成功7"
+ device_info);
//随机字符串
string
nonce_str = resHandler.GetParameter(
"nonce_str"
);
ClassesLib.InsertLog(
"微信支付成功8"
+ nonce_str);
string
sign = resHandler.GetParameter(
"sign"
);
ClassesLib.InsertLog(
"微信支付成功9"
+ sign);
//错误代码
string
err_code = resHandler.GetParameter(
"err_code"
);
ClassesLib.InsertLog(
"微信支付成功4"
+ err_code);
//结果信息描述
string
err_code_des = resHandler.GetParameter(
"err_code_des"
);
ClassesLib.InsertLog(
"微信支付成功10"
+ err_code_des);
#endregion
if
(result_code.ToUpper() !=
"SUCCESS"
)
{
//LogUtil.WriteLog("result_code faild:错误代码" + err_code + "结果信息描述" + err_code_des);
return
Content(
"验证失败"
);
}
#region 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
//用户在商户 appid 下的唯一标识
string
openid = resHandler.GetParameter(
"openid"
);
ClassesLib.InsertLog(
"微信支付成功11"
+ openid);
//用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
string
is_subscribe = resHandler.GetParameter(
"is_subscribe"
);
ClassesLib.InsertLog(
"微信支付成功12"
+ is_subscribe);
//JSAPI、NATIVE、MICROPAY、APP
string
trade_type = resHandler.GetParameter(
"trade_type"
);
ClassesLib.InsertLog(
"微信支付成功13"
+ trade_type);
//银行类型,采用字符串类型的银行标识
string
bank_type = resHandler.GetParameter(
"bank_type"
);
ClassesLib.InsertLog(
"微信支付成功14"
+ bank_type);
//订单总金额,单位为分
string
total_fee = resHandler.GetParameter(
"total_fee"
);
ClassesLib.InsertLog(
"微信支付成功15"
+ total_fee);
//现金券金额
string
coupon_fee = resHandler.GetParameter(
"coupon_fee"
);
ClassesLib.InsertLog(
"微信支付成功16"
+ coupon_fee);
//货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
string
fee_type = resHandler.GetParameter(
"fee_type"
);
ClassesLib.InsertLog(
"微信支付成功17"
+ fee_type);
//微信支付订单号
string
transaction_id = resHandler.GetParameter(
"transaction_id"
);
ClassesLib.InsertLog(
"微信支付成功18"
+ transaction_id);
//商户系统的订单号,与请求一致。
string
out_trade_no = resHandler.GetParameter(
"out_trade_no"
);
ClassesLib.InsertLog(
"微信支付成功19"
+ out_trade_no);
//商家数据包,原样返回
string
attach = resHandler.GetParameter(
"attach"
);
ClassesLib.InsertLog(
"微信支付成功20"
+ attach);
//支 付 完 成 时 间 , 格 式 为yyyyMMddhhmmss,如 2009 年12 月27日 9点 10分 10 秒表示为 20091227091010。时区为 GMT+8 beijing。该时间取自微信支付服务器
string
time_end = resHandler.GetParameter(
"time_end"
);
ClassesLib.InsertLog(
"微信支付成功21"
+ time_end);
#endregion
#endregion
//LogUtil.WriteLog("4.total_fee= " + total_fee + "、err_code_des=" + err_code_des + "、result_code=" + result_code);
if
(!out_trade_no.Equals(
""
))
{
//LogUtil.WriteLog("5.success");
ClassesLib.InsertLog(
"微信支付成功业务逻辑"
);
Response.Write(
"success"
);
/**
* 这里输入用户逻辑操作,比如更新订单的支付状态
*
* **/
return
Content(
"支付成功!"
);
}
return
Content(
"验证失败"
);
}
catch
(Exception ex)
{
//LogUtil.WriteLog("Notify 页面 发送异常错误:" + ex.Message);
return
Content(
"支付失败"
);
}
|
相关资料获取地址:https://item.taobao.com/item.htm?spm=686.1000925.0.0.AlZkml&id=524281028471