zoukankan      html  css  js  c++  java
  • 微信支付笔记

        一、开发前的准备:

            开发前需要配置支付授权目录,支付相关的页面全部要在这个指定的目录中,不能在子目录中。测试授权目录和测试白名单可以不用管。

        二、微信支付开发前需要这几个参数:

           1、AppID    在微信公众号管理后台(https://mp.weixin.qq.com/)的开发者中心获取

           2、微信支付商户号  在微信公众号管理后台(https://mp.weixin.qq.com/)的 微信支付 菜单下可以看到

           3、商户密匙   微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

        三、微信公众号支付的逻辑是这样的:

             1. 我们自己的系统生成待支付订单信息 [订单号、金额、商品名称、说明等信息]

             2. 将系统的订单信息使用统一下单的数据格式提交到微信服务器 ,微信服务器会返回一个预支付交易会话标识 prepay_id

                  统一下单的API文档: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

             3. 使用公众号APPID和第二部返回的预支付交易会话标识 prepay_id,加上时间戳 timeStamp、 随机字符串nonceStr ,签名 paySign 生成js参数,在HTML页面里完成支付

         网页端调起支付API文档:   https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

             4. 微信服务器异步通知我们服务器上的回调地址,完成支付

        从第三部分的HTML页面讲起,我们看到官方文档中微信的网页支付的代码是这样的:

    function onBridgeReady() {
        WeixinJSBridge.invoke('getBrandWCPayRequest', {
            "appId":"wx2421b1c4370ec43b",
            //公众号名称,由商户传入     
            "timeStamp":" 1395712654",
            //时间戳,自1970年以来的秒数     
            "nonceStr":"e61463f8efa94090b1f366cccfbbb444",
            //随机串     
            "package":"prepay_id=u802345jgfjsdfgsdg888",
            "signType":"MD5",
            //微信签名方式:     
            "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
        },
        function(res) {
            if (res.err_msg == "get_brand_wcpay_request:ok") {}
        });
    }
    if (typeof WeixinJSBridge == "undefined") {
        if (document.addEventListener) {
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        } else if (document.attachEvent) {
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    } else {
        onBridgeReady();
    }

        注意:这个JS需要在微信浏览器里面直接调用,无需引用其他js文件,其他浏览器是不行的.

        第一次看到这个js脚本的时候比较奇怪,这里怎么没有支付的金额、商品名称、订单号呢,后来才知道订单的信息是需要提前提交给微信服务器的,这个提交的过程就叫统一下单

        支付页面的Javascript代码很简单,只有这几个参数需要我们自己根据实际情况进行替换:

            "appId":"wx2421b1c4370ec43b",  //公众号名称,由商户传入  |  这个参数已知           
            "timeStamp":" 1395712654",     //时间戳,自1970年以来的秒数 | 写个函数生成下即可,简单           
            "nonceStr":"e61463f8efa94090b1f366cccfbbb444",       //随机串 | 写个函数生成下        
            "package":"prepay_id=u802345jgfjsdfgsdg888",    //prepay_id 就是前面提到的支付交易会话标识,具体怎么生成在后面讲
            "signType":"MD5",                                    //微信签名方式:固定的,填写MD5即可             
    
    //微信签名 签名生成方法可见API文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3,我在文章后面会给出代码
    "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89"

        我们先搞定最简单的部分:随机字符串和时间戳的生成C#实现

            /// <summary>
            /// 随机串 
            /// </summary>
            public static string getNoncestr()
            {
                Random random = new Random();
                return MD5Util.GetMD5(random.Next(1000).ToString(), "utf-8").ToLower().Replace("s", "S");
            }
    
            /// <summary>
            /// 时间截,自1970年以来的秒数
            /// </summary>
            public static string getTimestamp()
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
    View Code

       现在只有prepay_idpaySign目前不知道怎么产生的,另外几个参数都搞定了。

       prepay_id需要通过统一下单接口https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1获取到,我们看这个接口要传的参数有不少,新建一个UnifiedOrder类:

        /// <summary>
        /// 微信统一接口请求实体对象
        /// </summary>
        [Serializable]
        public class UnifiedOrder
        {
            /// <summary>
            /// 公共号ID(微信分配的公众账号 ID)
            /// </summary>
            public string appid = "";
            /// <summary>
            /// 商户号(微信支付分配的商户号)
            /// </summary>
            public string mch_id = "";
            /// <summary>
            /// 微信支付分配的终端设备号
            /// </summary>
            public string device_info = "";
            /// <summary>
            /// 随机字符串,不长于 32 位
            /// </summary>
            public string nonce_str = "";
            /// <summary>
            /// 签名
            /// </summary>
            public string sign = "";
            /// <summary>
            /// 商品描述
            /// </summary>
            public string body = "";
            /// <summary>
            /// 附加数据,原样返回
            /// </summary>
            public string attach = "";
            /// <summary>
            /// 商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一,详细说明
            /// </summary>
            public string out_trade_no = "";
            /// <summary>
            /// 订单总金额,单位为分,不能带小数点
            /// </summary>
            public int total_fee = 0;
            /// <summary>
            /// 终端IP
            /// </summary>
            public string spbill_create_ip = "";
            /// <summary>
            /// 订 单 生 成 时 间 , 格 式 为yyyyMMddHHmmss,如 2009 年12 月 25 日 9 点 10 分 10 秒表示为 20091225091010。时区为 GMT+8 beijing。该时间取自商户服务器
            /// </summary>
            public string time_start = "";
            /// <summary>
            /// 交易结束时间
            /// </summary>
            public string time_expire = "";
            /// <summary>
            /// 商品标记 商品标记,该字段不能随便填,不使用请填空,使用说明详见第 5 节
            /// </summary>
            public string goods_tag = "";
            /// <summary>
            /// 接收微信支付成功通知
            /// </summary>
            public string notify_url = "";
            /// <summary>
            /// JSAPI、NATIVE、APP
            /// </summary>
            public string trade_type = "";
            /// <summary>
            /// 用户标识 trade_type 为 JSAPI时,此参数必传
            /// </summary>
            public string openid = "";
            /// <summary>
            /// 只在 trade_type 为 NATIVE时需要填写。
            /// </summary>
            public string product_id = "";
        }
    View Code

       用参数填充这个对象

            //统一下单
            UnifiedOrder order = new UnifiedOrder();
            order.appid = "1111111111111111";                   //公众账号ID,请替换成公众号实际的appid
            order.mch_id = "111111111111111";                   //调用接口提交的商户号,请替换成真实的商户号 
            order.device_info = "WEB";                          //终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"  固定值
            order.nonce_str = TenpayUtil.getNoncestr();         //随机字符串,不长于32位,见前面的随机字符串函数 TenpayUtil代码后面给出
            order.body = "xxxxxxx设备充值";                      //商品或支付单简要描述
            order.attach = "这是一个支付测试订单";                 //附加数据
            order.out_trade_no = "11111111111111111111111";     //商户系统内部的订单号,32个字符内、可包含字母,请替换成真实的订单号
            order.total_fee = 0.01 * 100;                       //int类型,订单总金额,单位为分,请填写实际订单金额
            order.spbill_create_ip = Page.Request.UserHostAddress;              //用户端ip  11.11.11.11 格式
            order.notify_url = "http://baidu.com/notify_url.aspx";  //接收微信支付异步通知回调地址,请替换成真实的回调地址,回调页面文章后面会给出例子
            order.openid = "111111111111111111111111111111";      //trade_type=JSAPI,此参数必传,请替换成用户在商户appid下的唯一标识,用户的openid怎么获取请参考微信开发的API文档
            order.trade_type = "JSAPI";                         //交易类型 JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付

          将这些信息提交给微信服务器就能获取到临时支付交易会话标识 prepay_id了,下面代码里的paySignKey是商户密匙。

            //得到 prepay_id 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
            string prepay_id = tenpay.getPrepay_id(order, paySignKey);    //tenapy代码文章末尾给出
            string timeStamp = TenpayUtil.getTimestamp();   //时间戳 
            string nonceStr = TenpayUtil.getNoncestr();     //随机字符串

         签名参数paySign的获取:

            // 4.根据得到的prepay_id计算paySign 签名
            SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
            sParams.Add("appId", "1111111111111111111");        //请替换成真实的APPID
            sParams.Add("timeStamp", timeStamp);
            sParams.Add("nonceStr", nonceStr);
            sParams.Add("package", "prepay_id=" + prepay_id);
            sParams.Add("signType", "MD5");
            string paySign = tenpay.getsign(sParams, paySignKey);   //得到 paySign 签名  paySingKey 是商户密匙

          这样paySign和prepay_id参数都成功获取到了,将这些参数替换掉HTML页面的js参数就可以弹出微信支付窗口:

                              

    需要用到的一些代码:

    TenpayUtil

        public class TenpayUtil
        {
            /// <summary>
            /// 统一支付接口
            /// </summary>
            const string UnifiedPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    
            /// <summary>
            /// 网页授权接口
            /// </summary>
            const string access_tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
    
            /// <summary>
            /// 微信订单查询接口
            /// </summary>
            const string OrderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
    
            /// <summary>
            /// 随机串
            /// </summary>
            public static string getNoncestr()
            {
                Random random = new Random();
                return MD5Util.GetMD5(random.Next(1000).ToString(), "utf-8").ToLower().Replace("s", "S");
            }
    
            /// <summary>
            /// 时间截,自1970年以来的秒数
            /// </summary>
            public static string getTimestamp()
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
    
            /// <summary>
            /// 网页授权接口
            /// </summary>
            public static string getAccess_tokenUrl()
            {
                return access_tokenUrl;
            }
    
            /// <summary>
            /// 获取微信签名
            /// 将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
            /// 格式(即key1=value1&key2=value2…)拼接成字符串stringA
            /// https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
            /// </summary>
            /// <param name="sParams">集合M</param>
            /// <param name="key">key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置</param>
            /// <returns></returns>
            public string getsign(SortedDictionary<string, string> sParams, string key)
            {
                int i = 0;
                string sign = string.Empty;
                StringBuilder sb = new StringBuilder();
                foreach (KeyValuePair<string, string> temp in sParams)
                {
                    if (temp.Value == "" || temp.Value == null || temp.Key.ToLower() == "sign")
                    {
                        continue;
                    }
                    i++;
                    sb.Append(temp.Key.Trim() + "=" + temp.Value.Trim() + "&");
                }
                sb.Append("key=" + key.Trim() + "");
                string signkey = sb.ToString();
                sign = MD5Util.GetMD5(signkey, "utf-8");
    
                return sign;
            }
    
            /// <summary>
            /// Post数据到指定接口并返回数据
            /// </summary>
            /// <param name="url">地址</param>
            /// <param name="postData">要提交的数据</param>
            /// <returns></returns>
            public string PostXmlToUrl(string url, string postData)
            {
                string returnmsg = "";
                Bird.Net.Http.HttpHelper httpHelper = new Bird.Net.Http.HttpHelper();
                httpHelper.Encoding = Encoding.UTF8;
                returnmsg = httpHelper.GetHtml(url, postData, true);
                /*
                using (System.Net.WebClient wc = new System.Net.WebClient())
                {
                    returnmsg = wc.UploadString(url, "POST", postData);
                }*/
                return returnmsg;
            }
    
            public string order_request_data = "";
            public string order_post_data = "";
    
            /// <summary>
            /// 统一下单获取prepay_id
            /// </summary>
            /// <param name="order">统一下单</param>
            /// <param name="key">商户密匙</param>
            /// <returns>prepay_id</returns>
            public string getPrepay_id(UnifiedOrder order, string key)
            {
                string prepay_id = "";
                order_post_data = getUnifiedOrderXml(order, key);
                order_request_data = PostXmlToUrl(UnifiedPayUrl, order_post_data);
                SortedDictionary<string, string> requestXML = GetInfoFromXml(order_request_data);
                foreach (KeyValuePair<string, string> k in requestXML)
                {
                    if (k.Key == "prepay_id")
                    {
                        prepay_id = k.Value;
                        break;
                    }
                }
                return prepay_id;
            }
    
            /// <summary>
            /// 获取微信订单明细
            /// </summary>
            public OrderDetail getOrderDetail(QueryOrder queryorder, string key)
            {
                string post_data = getQueryOrderXml(queryorder, key);
                string request_data = PostXmlToUrl(OrderQueryUrl, post_data);
                OrderDetail orderdetail = new OrderDetail();
                SortedDictionary<string, string> requestXML = GetInfoFromXml(request_data);
                foreach (KeyValuePair<string, string> k in requestXML)
                {
                    switch (k.Key)
                    {
                        case "retuen_code":
                            orderdetail.result_code = k.Value;
                            break;
                        case "return_msg":
                            orderdetail.return_msg = k.Value;
                            break;
                        case "appid":
                            orderdetail.appid = k.Value;
                            break;
                        case "mch_id":
                            orderdetail.mch_id = k.Value;
                            break;
                        case "nonce_str":
                            orderdetail.nonce_str = k.Value;
                            break;
                        case "sign":
                            orderdetail.sign = k.Value;
                            break;
                        case "result_code":
                            orderdetail.result_code = k.Value;
                            break;
                        case "err_code":
                            orderdetail.err_code = k.Value;
                            break;
                        case "err_code_des":
                            orderdetail.err_code_des = k.Value;
                            break;
                        case "trade_state":
                            orderdetail.trade_state = k.Value;
                            break;
                        case "device_info":
                            orderdetail.device_info = k.Value;
                            break;
                        case "openid":
                            orderdetail.openid = k.Value;
                            break;
                        case "is_subscribe":
                            orderdetail.is_subscribe = k.Value;
                            break;
                        case "trade_type":
                            orderdetail.trade_type = k.Value;
                            break;
                        case "bank_type":
                            orderdetail.bank_type = k.Value;
                            break;
                        case "total_fee":
                            orderdetail.total_fee = k.Value;
                            break;
                        case "coupon_fee":
                            orderdetail.coupon_fee = k.Value;
                            break;
                        case "fee_type":
                            orderdetail.fee_type = k.Value;
                            break;
                        case "transaction_id":
                            orderdetail.transaction_id = k.Value;
                            break;
                        case "out_trade_no":
                            orderdetail.out_trade_no = k.Value;
                            break;
                        case "attach":
                            orderdetail.attach = k.Value;
                            break;
                        case "time_end":
                            orderdetail.time_end = k.Value;
                            break;
                        default:
                            break;
                    }
                }
                return orderdetail;
            }
    
            /// <summary>
            /// 把XML数据转换为SortedDictionary[string, string]集合
            /// </summary>
            /// <param name="strxml">XML数据</param>
            /// <returns>集合</returns>
            public SortedDictionary<string, string> GetInfoFromXml(string xmlstring)
            {
                SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
                try
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xmlstring);
                    XmlElement root = doc.DocumentElement;
                    int len = root.ChildNodes.Count;
                    for (int i = 0; i < len; i++)
                    {
                        string name = root.ChildNodes[i].Name;
                        if (!sParams.ContainsKey(name))
                        {
                            sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
                        }
                    }
                }
                catch { }
                return sParams;
            }
    
            /// <summary>
            /// 微信统一下单接口xml参数整理
            /// </summary>
            /// <param name="order">微信支付参数实例</param>
            /// <param name="key">商户密钥</param>
            /// <returns></returns>
            protected string getUnifiedOrderXml(UnifiedOrder order, string key)
            {
                string return_string = string.Empty;
                SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
                sParams.Add("appid", order.appid);
                sParams.Add("attach", order.attach);
                sParams.Add("body", order.body);
                sParams.Add("device_info", order.device_info);
                sParams.Add("mch_id", order.mch_id);
                sParams.Add("nonce_str", order.nonce_str);
                sParams.Add("notify_url", order.notify_url);
                sParams.Add("openid", order.openid);
                sParams.Add("out_trade_no", order.out_trade_no);
                sParams.Add("spbill_create_ip", order.spbill_create_ip);
                sParams.Add("total_fee", order.total_fee.ToString());
                sParams.Add("trade_type", order.trade_type);
                order.sign = getsign(sParams, key);
                sParams.Add("sign", order.sign);
    
                //拼接成XML请求数据
                StringBuilder sbPay = new StringBuilder();
                foreach (KeyValuePair<string, string> k in sParams)
                {
                    if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
                    {
                        sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
                    }
                    else
                    {
                        sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
                    }
                }
                return_string = string.Format("<xml>{0}</xml>", sbPay.ToString());
                return return_string;
    
            }
    
            /// <summary>
            /// 微信订单查询接口XML参数整理
            /// </summary>
            /// <param name="queryorder">微信订单查询参数实例</param>
            /// <param name="key">密钥</param>
            /// <returns></returns>
            protected string getQueryOrderXml(QueryOrder queryorder, string key)
            {
                string return_string = string.Empty;
                SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
                sParams.Add("appid", queryorder.appid);
                sParams.Add("mch_id", queryorder.mch_id);
                sParams.Add("transaction_id", queryorder.transaction_id);
                sParams.Add("out_trade_no", queryorder.out_trade_no);
                sParams.Add("nonce_str", queryorder.nonce_str);
                queryorder.sign = getsign(sParams, key);
                sParams.Add("sign", queryorder.sign);
    
                //拼接成XML请求数据
                StringBuilder sbPay = new StringBuilder();
                foreach (KeyValuePair<string, string> k in sParams)
                {
                    if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
                    {
                        sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
                    }
                    else
                    {
                        sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
                    }
                }
                return_string = string.Format("<xml>{0}</xml>", sbPay.ToString().TrimEnd(','));
                return return_string;
            }
        }
    View Code

    MD5Util

        public class MD5Util
        {
            public MD5Util() { }
    
            /** 获取大写的MD5签名结果 */
            public static string GetMD5(string encypStr, string charset)
            {
                string retStr;
                MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
    
                //创建md5对象
                byte[] inputBye;
                byte[] outputBye;
    
                try
                {
                    inputBye = Encoding.UTF8.GetBytes(encypStr);
                }
                catch (Exception ex)
                {
                    inputBye = Encoding.UTF8.GetBytes(encypStr);
                }
                outputBye = m5.ComputeHash(inputBye);
    
                retStr = System.BitConverter.ToString(outputBye);
                retStr = retStr.Replace("-", "").ToUpper();
                return retStr;
            }
        }
    View Code

    OrderDetail

        /// <summary>
        /// 微信订单明细实体对象
        /// https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
        /// </summary>
        [Serializable]
        public class OrderDetail
        {
            /// <summary>
            /// 返回状态码,SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断
            /// </summary>
            public string return_code = "";
    
            /// <summary>
            /// 返回信息返回信息,如非空,为错误原因 签名失败 参数格式校验错误
            /// </summary>
            public string return_msg = "";
    
            /// <summary>
            /// 公共号ID(微信分配的公众账号 ID)
            /// </summary>
            public string appid = "";
    
            /// <summary>
            /// 商户号(微信支付分配的商户号)
            /// </summary>
            public string mch_id = "";
    
            /// <summary>
            /// 随机字符串,不长于32位
            /// </summary>
            public string nonce_str = "";
    
            /// <summary>
            /// 签名详见签名算法 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
            /// </summary>
            public string sign = "";
    
            /// <summary>
            /// 业务结果,SUCCESS/FAIL 
            /// 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
            /// </summary>
            public string result_code = "";
    
            /// <summary>
            /// 错误代码    详细参见第6节错误列表
            /// </summary>
            public string err_code = "";
    
            /// <summary>
            /// 错误代码描述
            /// </summary>
            public string err_code_des = "";
    
            /// <summary>
            /// 交易状态
            ///SUCCESS—支付成功
            ///REFUND—转入退款
            ///NOTPAY—未支付
            ///CLOSED—已关闭
            ///REVOKED—已撤销
            ///USERPAYING--用户支付中
            ///NOPAY--未支付(输入密码或确认支付超时) PAYERROR--支付失败(其他原因,如银行返回失败)
            /// </summary>
            public string trade_state = "";
    
            /// <summary>
            /// 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"
            /// </summary>
            public string device_info = "";
    
            /// <summary>
            /// 用户在商户appid下的唯一标识
            /// </summary>
            public string openid = "";
    
            /// <summary>
            /// 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
            /// </summary>
            public string is_subscribe = "";
    
            /// <summary>
            /// 交易类型,取值如下:JSAPI,NATIVE,APP,详细说明见参数规定
            /// </summary>
            public string trade_type = "";
    
            /// <summary>
            /// 银行类型,采用字符串类型的银行标识
            /// </summary>
            public string bank_type = "";
    
            /// <summary>
            /// 订单总金额,单位为分
            /// </summary>
            public string total_fee = "";
    
            /// <summary>
            /// 现金券支付金额<=订单总金额,订单总金额-现金券金额为现金支付金额
            /// </summary>
            public string coupon_fee = "";
    
            /// <summary>
            /// 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY
            /// </summary>
            public string fee_type = "";
    
            /// <summary>
            /// 微信支付订单号
            /// </summary>
            public string transaction_id = "";
    
            /// <summary>
            /// 商户系统的订单号,与请求一致。
            /// </summary>
            public string out_trade_no = "";
    
            /// <summary>
            /// 商家数据包,原样返回
            /// </summary>
            public string attach = "";
    
            /// <summary>
            /// 支付完成时间,格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。
            /// 时区为GMT+8 beijing。该时间取自微信支付服务器
            /// </summary>
            public string time_end = "";
    
        }
    View Code

    UnifiedOrder

        /// <summary>
        /// 微信统一接口请求实体对象
        /// </summary>
        [Serializable]
        public class UnifiedOrder
        {
            /// <summary>
            /// 公共号ID(微信分配的公众账号 ID)
            /// </summary>
            public string appid = "";
            /// <summary>
            /// 商户号(微信支付分配的商户号)
            /// </summary>
            public string mch_id = "";
            /// <summary>
            /// 微信支付分配的终端设备号
            /// </summary>
            public string device_info = "";
            /// <summary>
            /// 随机字符串,不长于 32 位
            /// </summary>
            public string nonce_str = "";
            /// <summary>
            /// 签名
            /// </summary>
            public string sign = "";
            /// <summary>
            /// 商品描述
            /// </summary>
            public string body = "";
            /// <summary>
            /// 附加数据,原样返回
            /// </summary>
            public string attach = "";
            /// <summary>
            /// 商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一,详细说明
            /// </summary>
            public string out_trade_no = "";
            /// <summary>
            /// 订单总金额,单位为分,不能带小数点
            /// </summary>
            public int total_fee = 0;
            /// <summary>
            /// 终端IP
            /// </summary>
            public string spbill_create_ip = "";
            /// <summary>
            /// 订 单 生 成 时 间 , 格 式 为yyyyMMddHHmmss,如 2009 年12 月 25 日 9 点 10 分 10 秒表示为 20091225091010。时区为 GMT+8 beijing。该时间取自商户服务器
            /// </summary>
            public string time_start = "";
            /// <summary>
            /// 交易结束时间
            /// </summary>
            public string time_expire = "";
            /// <summary>
            /// 商品标记 商品标记,该字段不能随便填,不使用请填空,使用说明详见第 5 节
            /// </summary>
            public string goods_tag = "";
            /// <summary>
            /// 接收微信支付成功通知
            /// </summary>
            public string notify_url = "";
            /// <summary>
            /// JSAPI、NATIVE、APP
            /// </summary>
            public string trade_type = "";
            /// <summary>
            /// 用户标识 trade_type 为 JSAPI时,此参数必传
            /// </summary>
            public string openid = "";
            /// <summary>
            /// 只在 trade_type 为 NATIVE时需要填写。
            /// </summary>
            public string product_id = "";
        }
    View Code

    回调页面测试:

    public partial class tools_WeChat_Pay_notify_url : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //接收从微信后台POST过来的数据
            System.IO.Stream s = Request.InputStream;
            int count = 0;
            byte[] buffer = new byte[1024];
            StringBuilder builder = new StringBuilder();
            while ((count = s.Read(buffer, 0, 1024)) > 0)
            {
                builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
            }
            s.Flush();
            s.Close();
            s.Dispose();
    
            TenpayUtil payUtil = new TenpayUtil();
            SortedDictionary<string, string> requestXML = payUtil.GetInfoFromXml(builder.ToString());
    
            const string paySignKey = "111111111111111111111111111111111111";
            string sing = payUtil.getsign(requestXML, paySignKey);
    
            if (requestXML.ContainsKey("return_code"))
            {
                //Response.Write(requestXML["return_code"]);
            }
    
            //成功返回
            Response.Write("<xml>");
            Response.Write("<return_code><![CDATA[SUCCESS]]></return_code>");
            Response.Write("<return_msg><![CDATA[OK]]></return_msg>");
            Response.Write("</xml>");
        }
    
        /// <summary>
        /// 从XML数据中获取值
        /// </summary>
        /// <param name="requestXML">XML数据</param>
        /// <param name="key">Key</param>
        /// <returns>Value</returns>
        public string getVal(SortedDictionary<string, string> data, string key)
        {
            if (data.ContainsKey(key))
            {
                return data[key];
            }
            return "";
        }
    }
    View Code
  • 相关阅读:
    问题建模---大纲---待补充
    塞库报表封装问题分析--一篇不太成功的问题分析报告
    哲学的根本问题--以人为本
    什么是本体论
    知行合一是做人的最高境界
    什么是问题?--人类才是最大的问题--所有的问题都是在人类认识世界和改造世界中产生的
    还原论与what、how、why
    selinux 开启和关闭
    Macbook上打开多个终端的方法
    PHPStorm 快捷键大全(Win/Linux/Mac)
  • 原文地址:https://www.cnblogs.com/relax/p/4935636.html
Copyright © 2011-2022 走看看