转自:http://www.kwstu.com/ArticleView/netmvc_201511132050268716

最近开发手机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();
                    string prepayXml = HttpUtil.Send(data, "https://api.mch.weixin.qq.com/pay/unifiedorder");
                    //获取预支付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

微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)的更多相关文章

  1. 支付宝移动支付开发详细教程服务端采用.net mvc webapi(C#)

    转自:http://www.kwstu.com/ArticleView/netmvc_201511132005431321 最近开发手机app需要实现移动支付功能,由于考虑支付安全将支付宝生成签名写到 ...

  2. 微信app支付android客户端以及.net服务端实现

    由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...

  3. Java支付宝PC网站支付功能开发(详细教程)

    一.前言 本案例使用的是Java实现的.使用支付宝的沙盒环境示例.发布需要换成正式环境.这里就不作详细说明了 本代码适合用来做参考,不要直接复制去使用. 没有账号的需要去平台注册一个: 登录支付宝开发 ...

  4. 微信支付 V3 开发教程(一):初识 Senparc.Weixin.TenPayV3

    前言 我在 9 年前发布了 Senparc.Weixin SDK 第一个开源版本,一直维护至今,如今 Stras 已经破 7K,这一路上得到了 .NET 社区的积极响应和支持,也受到了非常多的宝贵建议 ...

  5. 微信小程序-云开发实战教程

    微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...

  6. 适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

    本文由“yuanrw”分享,博客:juejin.im/user/5cefab8451882510eb758606,收录时内容有改动和修订. 0.引言 站长提示:本文适合IM新手阅读,但最好有一定的网络 ...

  7. ubuntu下安装 gSOAP 用于C/C++开发web service服务端与客户端

    昨天在ubuntu下进行安装gSOAP,费了很多时间,没成功,今天又来找了大量教程资料,终于一次成功,这里写下自己的安装步骤和方法,供大家参考. 首先下载gsoap,我下载的是gsoap-2.8.1. ...

  8. 转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端

    from: http://ybak.iteye.com/blog/1853335 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端 游戏服 ...

  9. 网络编程之TCP客户端开发和TCP服务端开发

    开发 TCP 客户端程序开发步骤 创建客户端套接字对象 和服务端套接字建立连接 发送数据 接收数据 关闭客户端套接字 import socket if __name__ == '__main__': ...

随机推荐

  1. linux_常用命令_(ls, lsof,nslookup)_查看文件按照时间排序

    平时收集些用到的命令 方便使用 1:  ls -lrt 按时间排序  展示 2:nslookup  查看dns解析 3:lsof -p 进程号 lsof `which httpd` //那个进程在使用 ...

  2. Robot Framework + appium 启动手机浏览器的两个方法(1)

    一.Open Browser启动 使用Selenium2Library的Open Browser方法,例子如下: browser=手机浏览器类型,如chrome 二.Open Application启 ...

  3. 【地图API】为何您的坐标不准?如何纠偏?

    原文:[地图API]为何您的坐标不准?如何纠偏? 摘要:各种坐标体系之间如何转换?到底有哪些坐标体系?什么是火星坐标?为什么我的坐标,在地图上显示会有偏移?本文详细解答以上问题.最后给出坐标拾取工具. ...

  4. [ Bubble Sort ]& block

    [ Bubble Sort ] 冒泡排序!“预处理.block.预编译”!<环境:Terminal的gcc编译器> 简述:冒泡排序就是把小的元素往前调或者把大的元素往后调.比较是相邻的两个 ...

  5. JavaScript两种方法来定义一个函数

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. Java之final、finalize、finally的区别

    一.性质不同(1)final为关键字:(2)finalize()为方法:(3)finally为为区块标志,用于try语句中:二.作用(1)final为用于标识常量的关键字,final标识的关键字存储在 ...

  7. POJ 2553 The Bottom of a Graph (强连通分量)

    题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假 ...

  8. avalonjs 1.3.7发布

    avalonjs 1.3.7发布 又到每个月的15号了,现在avalon已经固定在每个月的15号发布新版本.这次发布又带来许多新特性,让大家写码更加轻松,借助于“操作数据即操作DOM”的核心理念与双向 ...

  9. leetcode第38题--Combination Sum

    题目: Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C  ...

  10. 【Android中Broadcast Receiver组件具体解释 】

    BroadcastReceiver(广播接收器)是Android中的四大组件之中的一个. 以下是Android Doc中关于BroadcastReceiver的概述: ①广播接收器是一个专注于接收广播 ...