zoukankan      html  css  js  c++  java
  • 微信公众号发起微信支付 c#

    tenpay.dll:

    MD5Util.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    
    namespace tenpay
    {
        public class MD5Util
        {
            public MD5Util()
            {
                //
                // TODO: 在此处添加构造函数逻辑
                //
            }
    
            /** 获取大写的MD5签名结果 */
            public static string GetMD5(string encypStr, string charset)
            {
                string retStr;
                MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
    
                //创建md5对象
                byte[] inputBye;
                byte[] outputBye;
    
                //使用GB2312编码方式把字符串转化为字节数组.
                try
                {
                    inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
                }
                catch (Exception ex)
                {
                    inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
                }
                outputBye = m5.ComputeHash(inputBye);
    
                retStr = System.BitConverter.ToString(outputBye);
                retStr = retStr.Replace("-", "").ToUpper();
                return retStr;
            }
        }
    }

    OrderDetail.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace tenpay
    {
        /// <summary>
        /// 微信订单明细实体对象
        /// </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>
            /// 签名
            /// </summary>
            public string sign = "";
    
            /// <summary>
            /// 业务结果,SUCCESS/FAIL
            /// </summary>
            public string result_code = "";
    
            /// <summary>
            /// 错误代码
            /// </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>
            /// 微信支付分配的终端设备号
            /// </summary>
            public string device_info = "";
    
            /// <summary>
            /// 用户在商户appid下的唯一标识
            /// </summary>
            public string openid = "";
           
            /// <summary>
            /// 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
            /// </summary>
            public string is_subscribe = "";
    
            /// <summary>
            /// 交易类型,JSAPI、NATIVE、MICROPAY、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 = "";
    
        }
    }

    QueryOrder.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace tenpay
    {
        /// <summary>
        /// 微信订单查询接口请求实体对象
        /// </summary>
        [Serializable]
        public class QueryOrder
        {
            /// <summary>
            /// 公共号ID(微信分配的公众账号 ID)
            /// </summary>
            public string appid = "";
    
            /// <summary>
            /// 商户号(微信支付分配的商户号)
            /// </summary>
            public string mch_id = "";
    
            /// <summary>
            /// 微信订单号,优先使用
            /// </summary>
            public string transaction_id = "";
    
            /// <summary>
            /// 商户系统内部订单号
            /// </summary>
            public string out_trade_no = "";
    
            /// <summary>
            /// 随机字符串,不长于 32 位
            /// </summary>
            public string nonce_str = "";
    
            /// <summary>
            /// 签名,参与签名参数:appid,mch_id,transaction_id,out_trade_no,nonce_str,key
            /// </summary>
            public string sign = "";
        }
    }

    UnifiedOrder.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace tenpay
    {
        /// <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 = "";
        }
    }

    TenpayUtil.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    
    namespace tenpay
    {
        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(), "GBK").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>
            /// 获取微信签名
            /// </summary>
            /// <param name="sParams"></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>
            public string PostXmlToUrl(string url, string postData)
            {
                string returnmsg = "";
                using (System.Net.WebClient wc = new System.Net.WebClient())
                {
                    returnmsg = wc.UploadString(url, "POST", postData);
                }
                return returnmsg;
            }
    
            /// <summary>
            /// 获取prepay_id
            /// </summary>
            public string getPrepay_id(UnifiedOrder order, string key)
            {
                string prepay_id = "";
                string post_data = getUnifiedOrderXml(order, key);
                string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
                SortedDictionary<string, string> requestXML = GetInfoFromXml(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"></param>
            /// <returns></returns>
            protected 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());
                byte[] byteArray = Encoding.UTF8.GetBytes(return_string);
                return_string = Encoding.GetEncoding("GBK").GetString(byteArray);
                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;
            }
        }
    }

     看官网例子:

    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" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    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();
    } 

    主要是prepay_idpaySign的获取。类库tenpay.dll的作用就是获取这两个东西的。

    大致流程:获取公众号的code——》获取预定单号的openid——》获取prepay_id。

    1.根据自己的业务逻辑生成内部订单

        protected void btnPay_Click(object sender, EventArgs e)
        {
            if (Fetch.GetUserCookie() == null)
            {
                Response.Redirect("/App/Login.aspx?url=/App/indexPay.aspx");
                return;
            }
    
            int salePrice = Utility.StrToInt(OrderAmount, 0);
            OnLineOrder onlineOrder = new OnLineOrder();
            onlineOrder.ShareID = 13;
            onlineOrder.OrderID = PayHelper.GetOrderIDByPrefix("WX");
    
            #region 订单处理
    
            if (Fetch.GetUserCookie() == null)
            {
                onlineOrder.OperUserID = 0;
            }
            else
            {
                onlineOrder.OperUserID = Fetch.GetUserCookie().UserID;
            }
            onlineOrder.Accounts = Fetch.GetUserCookie().Accounts;
            onlineOrder.CardTotal = 1;
            onlineOrder.CardTypeID = salePrice / 10; //< 30 ? 1 : salePrice < 60 ? 2 : salePrice < 120 ? 3 : 4;
            onlineOrder.OrderAmount = salePrice;
            onlineOrder.IPAddress = GameRequest.GetUserIP();
    
            //生成订单
            Message umsg = treasureFacade.RequestOrder(onlineOrder);
            if (!umsg.Success)
            {
                RenderAlertInfo(true, umsg.Content, 2);
                return;
            }
            #endregion
    
            //发起微信支付
    
            Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的公众号appid&redirect_uri=http://你的网站/App/Pay/PayOrder.aspx?showwxpaytitle=1&response_type=code&scope=snsapi_base&state=" + OrderAmount + "_" + onlineOrder.OrderID + "#wechat_redirect");
    
        }

    2.进入公众号配置网页授权获取用户基本信息

    这样配置后就可以调用微信的接口获取到公众号的code

    Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的公众号appid&redirect_uri=http://你的网站/App/Pay/PayOrder.aspx?showwxpaytitle=1&response_type=code&scope=snsapi_base&state=" + OrderAmount + "_" + onlineOrder.OrderID + "#wechat_redirect");

    访问https://open.weixin.qq.com/connect/oauth2/authorize接口,成功后会跳转到设置的redirect_uri页面,其中会包含code参数,接下来就到redirect_uri页面(我这里就是PayOrder.aspx了)简单的获取code参数:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Game.Utils;
    using System.Web.Script.Serialization;
    using tenpay;
    using System.Configuration;
    using System.Text;
    
    public partial class App_Pay_PayOrder : System.Web.UI.Page
    {
        protected string code = GameRequest.GetQueryString("code");
        protected string state = GameRequest.GetQueryString("state");
        protected string OrderAmount = "";
        protected string OrderID = "";
        protected string OrderTime = "";
        protected string OrderGive = "";
        protected string ImagePath = "";
        protected string appId = "";
        protected string timeStamp = "";
        protected string nonceStr = "";
        protected string prepay_id = "";
        protected string paySign = "";
    
        protected void Page_Load(object sender, EventArgs e)
        {
        LoadOrder();
        }
    
        private void LoadOrder()
        {
            string[] values = state.Split('_');
            if (values.Length == 2)
            {
                OrderAmount = values[0];
                OrderID = values[1];
            }
            OrderTime = (new DataControl()).SelectValue("select ApplayDate from OnLineOrder where OrderId='" + OrderID + "'", "DBTreasure", "").ToString();
            ImagePath = (new DataControl()).SelectValue("select ImagePath from CartTypeImage where CardTypeId=" + OrderAmount, "DBTreasure", "").ToString();
        }
    
        public struct authorization
        {
            public string access_token { get; set; }  //属性的名字,必须与json格式字符串中的"key"值一样。
            public string expires_in { get; set; }
            public string refresh_token { get; set; }
            public string openid { get; set; }
            public string scope { get; set; }
        }
    
        protected void btnPay_Click(object sender, EventArgs e)
        {
            try
            {
                TenpayUtil tenpay = new TenpayUtil();
                string paySignKey = ConfigurationManager.AppSettings["paySignKey"].ToString();
                string AppSecret = ConfigurationManager.AppSettings["AppSecret"].ToString();
                string mch_id = ConfigurationManager.AppSettings["mch_id"].ToString();
                appId = ConfigurationManager.AppSettings["AppId"].ToString();
    
                string post_data = "appid=" + appId + "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
                string requestData = tenpay.PostXmlToUrl(TenpayUtil.getAccess_tokenUrl(), post_data);
    
                JavaScriptSerializer js = new JavaScriptSerializer();   //实例化一个能够序列化数据的类
                authorization auth = js.Deserialize<authorization>(requestData);    //将json数据转化为对象类型并赋值给auth
    
    
                UnifiedOrder order = new UnifiedOrder();
                order.appid = appId;
                order.attach = "vinson";
                order.body = OrderAmount + "拍币";
                order.device_info = "";
                order.mch_id = mch_id;
                order.nonce_str = TenpayUtil.getNoncestr();
                order.notify_url = "http://你的网站/App/Shop/pay.aspx";
                order.openid = auth.openid;
                order.out_trade_no = OrderID;
                order.trade_type = "JSAPI";
                order.spbill_create_ip = Page.Request.UserHostAddress;
                order.total_fee = int.Parse(OrderAmount) * 100;
                //order.total_fee = 1;
    
                prepay_id = tenpay.getPrepay_id(order, paySignKey);
    
                timeStamp = TenpayUtil.getTimestamp();
                nonceStr = TenpayUtil.getNoncestr();
    
                SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
                sParams.Add("appId", appId);
                sParams.Add("timeStamp", timeStamp);
                sParams.Add("nonceStr", nonceStr);
                sParams.Add("package", "prepay_id=" + prepay_id);
                sParams.Add("signType", "MD5");
                paySign = tenpay.getsign(sParams, paySignKey);
    
            }
            catch (Exception ex)
            {
                Response.Write(ex.ToString());
                return;
            }
    
            Response.Redirect("http://你的网站/App/Pay/pay.aspx?showwxpaytitle=1&appId=" + appId + "&timeStamp=" + timeStamp + "&nonceStr=" + nonceStr + "&prepay_id=" + prepay_id + "&signType=MD5&paySign=" + paySign + "&OrderID=" + OrderID);
    
        }
    }
    View Code

    上面一句

    protected string code = GameRequest.GetQueryString("code");

    就获取到了传过来的code参数。

    然后调用网页授权接口https://api.weixin.qq.com/sns/oauth2/access_token 获取openid

    这个接口返回的数据是json类型的,使用JavaScriptSerializer类和结构体把openid取出:

        public struct authorization
        {
            public string access_token { get; set; }  //属性的名字,必须与json格式字符串中的"key"值一样。
            public string expires_in { get; set; }
            public string refresh_token { get; set; }
            public string openid { get; set; }
            public string scope { get; set; }
        }
                TenpayUtil tenpay = new TenpayUtil();
                string paySignKey = ConfigurationManager.AppSettings["paySignKey"].ToString();
                string AppSecret = ConfigurationManager.AppSettings["AppSecret"].ToString();
                string mch_id = ConfigurationManager.AppSettings["mch_id"].ToString();
                appId = ConfigurationManager.AppSettings["AppId"].ToString();
    
                string post_data = "appid=" + appId + "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
                string requestData = tenpay.PostXmlToUrl(TenpayUtil.getAccess_tokenUrl(), post_data);
    
                JavaScriptSerializer js = new JavaScriptSerializer();   //实例化一个能够序列化数据的类
                authorization auth = js.Deserialize<authorization>(requestData);    //将json数据转化为对象类型并赋值给auth

    AppIdAppSecret是公众号里面给的,mch_id是通过微信支付申请后微信发邮件给的,paySignKey是自己设置的证书密阴

    
    
    TenpayUtil.getAccess_tokenUrl()="https://api.weixin.qq.com/sns/oauth2/access_token"
    
    

    这样转化后就可以得到openid

    order.openid = auth.openid;

    终于到重头戏获取prepay_id了

                UnifiedOrder order = new UnifiedOrder();
                order.appid = appId;
                order.attach = "vinson";
                order.body = OrderAmount + "拍币";
                order.device_info = "";
                order.mch_id = mch_id;
                order.nonce_str = TenpayUtil.getNoncestr();
                order.notify_url = "http://你的网站/App/Shop/pay.aspx";
                order.openid = auth.openid;
                order.out_trade_no = OrderID;
                order.trade_type = "JSAPI";
                order.spbill_create_ip = Page.Request.UserHostAddress;
                order.total_fee = int.Parse(OrderAmount) * 100;
                //order.total_fee = 1;
    
                prepay_id = tenpay.getPrepay_id(order, paySignKey);

    对象类型UnifiedOrder方便把多个参数融合一个对象中,看看tenpay.getPrepay_id(order, paySignKey)方法:

            /// <summary>
            /// 获取prepay_id
            /// </summary>
            public string getPrepay_id(UnifiedOrder order, string key)
            {
                string prepay_id = "";
                string post_data = getUnifiedOrderXml(order, key);
                string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
                SortedDictionary<string, string> requestXML = GetInfoFromXml(request_data);
                foreach (KeyValuePair<string, string> k in requestXML)
                {
                    if (k.Key == "prepay_id")
                    {
                        prepay_id = k.Value;
                        break;
                    }
                }
                return prepay_id;
            }
    接口UnifiedPayUrl="https://api.mch.weixin.qq.com/pay/unifiedorder"

    这个接口的参数是xml格式的,返回来的数据也是xml格式的

    
    
            /// <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());
                byte[] byteArray = Encoding.UTF8.GetBytes(return_string);
                return_string = Encoding.GetEncoding("GBK").GetString(byteArray);
                return return_string;
                
            }
    
    

    所有参数准备完毕,就剩下最后的微信签名paySign了:

                prepay_id = tenpay.getPrepay_id(order, paySignKey);
    
                timeStamp = TenpayUtil.getTimestamp();
                nonceStr = TenpayUtil.getNoncestr();
    
                SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
                sParams.Add("appId", appId);
                sParams.Add("timeStamp", timeStamp);
                sParams.Add("nonceStr", nonceStr);
                sParams.Add("package", "prepay_id=" + prepay_id);
                sParams.Add("signType", "MD5");
                paySign = tenpay.getsign(sParams, paySignKey);

    这里要注意了:appId这些参数的大小写一定要和js那边的参数大小写一致!稍微有所不同都会提示“商户签名错误”。

    
    
    <script type="text/javascript">
        var appId = "<%=appId %>";
        var timeStamp = "<%=timeStamp %>";
        var nonceStr = "<%=nonceStr %>";
        var prepay_id = "<%=prepay_id %>";
        var paySign = "<%=paySign %>";
        var OrderID="<%=OrderID %>";
        //alert("appId:" + appId + ",timeStamp:" + timeStamp + ",nonceStr:" + nonceStr + ",prepay_id:" + prepay_id + ",paySign:" + paySign);
        //return;
        function onBridgeReady() {
            WeixinJSBridge.invoke(
           'getBrandWCPayRequest', {
               "appId": appId,     //公众号名称,由商户传入     
               "timeStamp": timeStamp,         //时间戳,自1970年以来的秒数     
               "nonceStr": nonceStr, //随机串     
               "package": "prepay_id=" + prepay_id,
               "signType": "MD5",         //微信签名方式:     
               "paySign": paySign //微信签名 
           },
           function (res) {
               if (res.err_msg == "get_brand_wcpay_request:ok") {
                   $(function () {
                       $.ajax({
                           contentType: "application/json",
                           url: "/WS/vinson.asmx/payWeiXin",
                           data: "{OrderID:'" + OrderID + "'}",
                           type: "POST",
                           dataType: "json",
                           success: function (json) {
                               json = eval("(" + json.d + ")");
                               if (json.success == "success") {
                                   $("#tip").text("支付成功,正在跳转......");
                                   window.location = "http://你的网站/App/Shop/successful.aspx";
                               }
                               else {
                                   $("#tip").text(json.msg);
                                   alert(json.msg);
                                   window.location = "http://你的网站/App/indexPay.aspx";
                               }
                           },
                           error: function (err, ex) {
                               alert(err.responseText);
                           }
                       });
                   })
               }     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
               else {
                   alert("交易取消");
                   window.location="http://www.你的网站.cn/App/indexPay.aspx";
               }
           }
       );
        }
        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();
        } 
    </script>
    
    

    要发起微信支付,还要到公众号设置支付授权目录:

    一切准备就绪,就可以真正的发起微信支付了:

  • 相关阅读:
    用rpm安装软件的常用步骤
    将应用发布到WasLiberty的两种方法
    安装 ibm-java-x86_64-sdk-6.0-9.3.x86_64.rpm 的三步骤
    人是科技的第一生产力。不重视人的价值,不尊重人的需求,不解放人的生产力,必将被互联网时代快速淘汰。
    Java保存简单偏好的类
    实用快捷键Win+L=锁屏
    判断一件事有无技术含量的标准
    主动去平事 别等事找人
    看了某些蛊惑人心的招聘广告,实在忍不住想要提醒那些跃跃欲奉献的后生们
    ubuntu16.04在英文状态下安装中文语言包的过程(法二:命令行的方式)
  • 原文地址:https://www.cnblogs.com/vinsonLu/p/4345041.html
Copyright © 2011-2022 走看看