天天看點

微信支付---微信公衆号支付

背景

  public actionresult wxaddvoucher_center(double money)

        {

            int money= int.parse((money * 100).tostring());

            string ip = request.userhostaddress;

            //随機商品id

            string id = "";

            random rd = new random();

            for (int i = 1; i < 16; i++)

            {

                id += (rd.next(0, 9)).tostring();

            }

payment pm=new payment();

            string weixinapi = pm.jsapipayment("商品描述", openid, ip, money, id);

            return content(weixinapi);

        }

配置微信支付的必須參數

public class wxconfig{

        public const string appid = "";//公衆号id

        public const string secret = "";//微信公衆号的secret

        public const string url = "";//回調url

        public const string mch_id = "";//商戶号

        public const string paysignkey = "";//證書密匙

}

//  定義傳回json資料類型的微信支付方法

public class payment

    /// <summary>

        /// 微信支付

      /// </summary>

      /// <param name="boby">商品描述</param>

      /// <param name="mch_id">商戶号</param>

      /// <param name="openid">使用者openid</param>

      /// <param name="spbill_create_ip">終端ip</param>

      /// <param name="total_fee">金額</param>

      /// <param name="out_trade_no">商戶訂單号</param>

      /// <returns></returns>

       public string jsapipayment( string boby,  string openid, string spbill_create_ip, int total_fee, string out_trade_no)

       {

           unifiedorder order = new unifiedorder();

           order.appid = wxconfig.appid;

           order.attach = "vinson";

           order.body = boby;

           order.device_info = "";

           order.mch_id = wxconfig.mch_id;

           order.nonce_str = tenpayutil.getnoncestr();

           order.notify_url = wxconfig.url;

           order.openid = openid;

           order.out_trade_no = out_trade_no;

           order.trade_type = "jsapi";

           order.spbill_create_ip = spbill_create_ip;

           order.total_fee = total_fee;

           tenpayutil tenpay = new tenpayutil();

           string paysignkey = wxconfig.paysignkey;

           string prepay_id = tenpay.getprepay_id(order, paysignkey);       

           string timestamp = tenpayutil.gettimestamp();

           string noncestr = tenpayutil.getnoncestr();

           sorteddictionary<string, object> sparams = new sorteddictionary<string, object>();

           sparams.add("appid", wxconfig.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);

           string package = "prepay_id=" + prepay_id;

           return md5util.tojson(wxconfig.appid, timestamp, noncestr, package, "md5", paysign);

       }

//-------tenpayutil類

  public    class tenpayutil

    {

        /// <summary>

        /// 統一支付接口

        /// </summary>

        const string unifiedpayurl = "https://api.mch.weixin.qq.com/pay/unifiedorder";        

        /// 随機串

        public static string getnoncestr()

            random random = new random();

            return md5util.getmd5(random.next(1000).tostring(), "gbk").tolower().replace("s", "s");

        /// 時間截,自1970年以來的秒數

        public static string gettimestamp()

            timespan ts = datetime.utcnow - new datetime(1970, 1, 1, 0, 0, 0, 0);

            return convert.toint64(ts.totalseconds).tostring();

        /// 擷取微信簽名

        /// <param name="sparams"></param>

        /// <returns></returns>

        public string getsign(sorteddictionary<string, object> sparams, string key)

            int i = 0;

            string sign = string.empty;

            stringbuilder sb = new stringbuilder();

            foreach (keyvaluepair<string, object> temp in sparams)

                if (temp.value.tostring() == "" || temp.value == null || temp.key.tolower() == "sign")

                {

                    continue;

                }

                i++;

                sb.append(temp.key.trim() + "=" + temp.value.tostring() + "&");

            sb.append("key=" + key.trim() + "");

            string signkey = sb.tostring();

            sign = md5util.getmd5(signkey, "utf-8");

            //utf-8

            return sign;

        /// post資料到指定接口并傳回資料

        public string postxmltourl(string url, string postdata)

            string returnmsg = "";

            //byte[] temp = encoding.utf8.getbytes(postdata);

            //string datagbk = encoding.getencoding("gbk").getstring(temp);

            using (system.net.webclient wc = new system.net.webclient())

                returnmsg = wc.uploadstring(url, "post", postdata);

            return returnmsg;

        /// 擷取prepay_id

        public string getprepay_id(unifiedorder order, string key)

            string prepay_id = "";

                string post_data = getunifiedorderxml(order, key);

                string request_data = postxmltourl(unifiedpayurl, post_data);

           //log.writelog1(request_data);

                sorteddictionary<string, object> requestxml = getinfofromxml(request_data);

                foreach (keyvaluepair<string, object> k in requestxml)

                    if (k.key == "prepay_id")

                    {

                        prepay_id = k.value.tostring();

                        break;

                    }

                }          

            return prepay_id;

        /// 把xml資料轉換為sorteddictionary<string, string>集合

        /// <param name="strxml"></param>

        protected sorteddictionary<string, object> getinfofromxml(string xmlstring)

            sorteddictionary<string, object> sparams = new sorteddictionary<string, object>();

            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;

        /// 微信統一下單接口xml參數整理

        /// <param name="order">微信支付參數執行個體</param>

        /// <param name="key">密鑰</param>

        protected string getunifiedorderxml(unifiedorder order, string key)

            string return_string = string.empty;

            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);

            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, object> 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);

            byte[] temp = encoding.utf8.getbytes(return_string);

            string datagbk = encoding.getencoding("utf-8").getstring(temp);         

            return return_string;

            //  gbk

    }

//---微信統一接口請求實體對象

/// <summary>

    /// 微信統一接口請求實體對象

    /// </summary>

    [serializable]

    public class unifiedorder

        /// 公衆号id(微信配置設定的公衆賬号 id)

        public string appid = "";

        /// 商戶号(微信支付配置設定的商戶号)

        public string mch_id = "";

        /// 微信支付配置設定的終端裝置号

        public string device_info = "";

        /// 随機字元串,不長于 32 位

        public string nonce_str = "";

        /// 簽名

        public string sign = "";

        /// 商品描述

        public string body = "";

        /// 附加資料,原樣傳回

        public string attach = "";

        /// 商戶系統内部的訂單号,32個字元内、可包含字母,確定在商戶系統唯一,詳細說明

        public string out_trade_no = "";

        /// 訂單總金額,機關為分,不能帶小數點

        public int total_fee = 0;

        /// 終端ip

        public string spbill_create_ip = "";

        /// 訂 單 生 成 時 間 , 格 式 為yyyymmddhhmmss,如 2009 年12 月 25 日 9 點 10 分 10 秒表示為 20091225091010。時區為 gmt+8 beijing。該時間取自商戶伺服器

        public string time_start = "";

        /// 交易結束時間

        public string time_expire = "";

        /// 商品标記 商品标記,該字段不能随便填,不使用請填空,使用說明詳見第 5 節

        public string goods_tag = "";

        /// 接收微信支付成功通知

        public string notify_url = "";

        /// jsapi、native、app

        public string trade_type = "";

        /// 使用者辨別 trade_type 為 jsapi時,此參數必傳

        public string openid = "";

        /// 隻在 trade_type 為 native時需要填寫。

        public string product_id = "";

  // 轉json對象

        /// json

        public static  string tojson(string appid, string timestamp, string noncestr, string packagea, string signtype, string paysign)

            string json = "{";

            json += "\"appid\":" + "\"" + appid + "\",";

            json += "\"timestamp\":" + "\"" + timestamp + "\",";

            json += "\"noncestr\":" + "\"" + noncestr + "\",";

            json += "\"package\":" + "\"" + packagea + "\",";

            json += "\"signtype\":" + "\"" + signtype + "\",";

            json += "\"paysign\":" + "\"" + paysign + "\"";

            json += "}";

            return json;

前端代碼

 <input id="btn" type="button" value="充值"/>

<script>

  $("#btn").click(function () {

 $.get(url,data, function (t) {//其中url是背景位址,data是金額

 var r = $.parsejson(t);

callpay(r);

})

 //支付功能

    function jsapicall(r) {

        weixinjsbridge.invoke(

         'getbrandwcpayrequest', r,

       function (res) {

           //alert(res.err_code + res.err_desc);

           //alert(res.err_msg);

           if (res.err_msg == "get_brand_wcpay_request:ok") {

          alert(”支付成功”);     

           } else {

               alert("交易取消");          

           }

   );

    function callpay(r) {

        if (typeof weixinjsbridge == "undefined") {

            if (document.addeventlistener) {

                document.addeventlistener('weixinjsbridgeready', jsapicall, false);

            } else if (document.attachevent) {

                document.attachevent('weixinjsbridgeready', jsapicall);

                document.attachevent('onweixinjsbridgeready', jsapicall);

        } else {

            jsapicall(r);

</script>

繼續閱讀