微信公衆號支付

1.設置JS安全域名css

 

 

2.開通微信支付,並在商戶端設置支付安全域名html

 3.獲取JSAPI權限參數jquery

        /// <summary>
        /// jsapi獲取簽名
        /// </summary>
        private config QuerySignature(string access_token,string ticket,string ticket_time,int weixin_id,string appid)
        {
            //須要簽名的頁面的url
            string urlstr = Util.getServerPath() + "/Home/TemplateView";
            //獲取最新的jsapi_tiket與accesstoken
            WeixinJsAPI jsAPi = new WeixinJsAPI(access_token, ticket, ticket_time, weixin_id);
            string jsapi = jsAPi.Ticket;
            //取簽名的時間戳能夠是隨機數
            long timestamp = Util.getLongTime();
            //隨機字符串(能夠寫方法隨機生成)
            string nonceStr = sys.getRandomCode(26);
            //簽名算法
            string signature = GetSignature(jsapi, nonceStr, timestamp, urlstr);

            return new config() {appId= appid,nonceStr= nonceStr,timestamp= timestamp,signature= signature }; 
        }
        /// <summary>
        /// 簽名算法
        /// </summary>
        /// <param name="jsapi">ticket</param>
        /// <param name="nonceStr">隨機字符串</param>
        /// <param name="timestamp">時間戳</param>
        /// <param name="urlstr">須要簽名的url</param>
        private string GetSignature(string jsapi, string nonceStr, long timestamp, string urlstr)
        {
            StringBuilder str = new StringBuilder();
            string string1 = "jsapi_ticket=" + jsapi + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + urlstr;
            return FormsAuthentication.HashPasswordForStoringInConfigFile(string1, "SHA1").ToLower();
        }
        /*產生驗證碼*/
        public static string getRandomCode(int codeLength)
        {

            string so = "2,3,5,6,7,8,9,A,B,C,D,E";
            string[] strArr = so.Split(',');
            string code = "";
            Random rand = new Random();
            for (int i = 0; i < codeLength; i++)
            {
                code += strArr[rand.Next(0, strArr.Length)];
            }
            return code;
        }

  還須要獲取微信公衆號的JSAPI的ticket算法

4.統一下單數據庫

        /// <summary>
        /// codebook_hifun_net的統一下單,主要是朗誦與筆順
        /// </summary>
        /// <param name="orderform_id"></param>
        /// <param name="openid"></param>
        /// <param name="appcode"></param>
        /// <returns></returns>
        private chooseWXPay GetHifunNetData(int orderform_id,string openid,string appcode,string seedName, string notifyUrl,weixin_net weixin,
            string weixin_applet_path,out double money,out string orderform_number)
        {
            money = 0;
            orderform_number = "";
            DataHelper db = new DataHelper();
            orderform_net orderform = db.GetModelById<orderform_net>("orderform", orderform_id.ToString());
            if (orderform.status == "S99")
            {
                LogHelper.Info("已支付訂單,不須要重複支付");
                return new chooseWXPay() { timestamp=0,signType="0",nonceStr="0",paySign="0",package="0",is_pay = true };
            }
            LogHelper.Info("orderform數據:" + Newtonsoft.Json.JsonConvert.SerializeObject(orderform));
            //weixin_net weixin = db.GetModelById<weixin_net>("weixin", "334");
            weixin_applet_net weixin_applet = db.GetModelBySql<weixin_applet_net>($@"select * from weixin_applet where appcode='{appcode}'");
            //微信公衆號統一下單 (須要將數據庫weixin的信息補全)
            WeixinPay weixinPay = new WeixinPay(System.Web.HttpContext.Current, weixin.appid, weixin.appsecret, weixin.pay_mch_id, weixin.pay_partner_key);
            string payNumber = Common.Orderform.Orderform.getNewPayNumer(orderform.uid.ToString());
            //微信支付,統一下單(與微信支付訂單同樣)
            UnifiedOrder unifiedOrder = new UnifiedOrder();
            int total_fee = int.Parse(((orderform.money + orderform.freight) * 100).To<double>().ToString("F0"));
            money = orderform.money??0 + orderform.freight??0;
            unifiedOrder.nonce_str = sys.getRandomCode(26);
            unifiedOrder.body = seedName + "(" + appcode + "-Applet)";
            unifiedOrder.out_trade_no = payNumber;//商戶單號使用支付單號
            unifiedOrder.total_fee = total_fee;
            unifiedOrder.spbill_create_ip = Util.GetUserIp();
            unifiedOrder.notify_url = notifyUrl; //回調
            unifiedOrder.trade_type = "JSAPI";
            unifiedOrder.openid = openid;
            orderform_number = payNumber;
            //得到統一下單返回的支付單信息
            UnifiedOrderReturn unifiedOrderReturn = weixinPay.UnifiedOrder(unifiedOrder);
            LogHelper.Info("統一下單返回的支付單信息:" + Newtonsoft.Json.JsonConvert.SerializeObject(unifiedOrderReturn));
            if ("SUCCESS".Equals(unifiedOrderReturn.return_code))
            {
                //準備獲取支付信息的簽名參數
                Hashtable parameter = new Hashtable();
                parameter.Add("appId", unifiedOrderReturn.appid);
                parameter.Add("timeStamp", Util.getLongTime().ToString());
                parameter.Add("nonceStr", unifiedOrderReturn.nonce_str);
                parameter.Add("package", "prepay_id=" + unifiedOrderReturn.prepay_id);
                parameter.Add("signType", "MD5");
                string paysign = weixinPay.Sign(parameter);
                chooseWXPay weixinPayInfo = new chooseWXPay()
                {
                    //appId = unifiedOrderReturn.appid,
                    timestamp = Util.getLongTime(),
                    nonceStr = unifiedOrderReturn.nonce_str,
                    package = "prepay_id=" + unifiedOrderReturn.prepay_id,
                    signType = "MD5",
                    paySign = paysign,
                    is_pay = false
                    //orderformId = orderform.id
                };
                LogHelper.Info("得到了統一下單數據:" + Newtonsoft.Json.JsonConvert.SerializeObject(weixinPayInfo));
                // //建立支付記錄(未支付狀態),便於通知回調Update
                pay_record_net payRecord = new pay_record_net
                {
                    pay_number = payNumber,
                    unionnumber = orderform.unionnumber,
                    pay_code = "WEIXIN_APPLET",
                    pay_sales_id = weixin_applet.id,
                    pay_money = (orderform.money + orderform.freight).To<double>(),
                    pay_uid = orderform.uid??0,
                    space_id = 0,
                    channel_id = 0,
                    createtime = DateTime.Now,
                    prepay_id = unifiedOrderReturn.prepay_id
                };
                db.Insert("pay_record", payRecord);
                //添加支付成功後的模板消息
                weixin_template_success_pay_net weixin_template_success_pay = new weixin_template_success_pay_net()
                {
                    pay_number = payNumber,
                    is_send_success = 0,
                    error_message = "",
                    create_time = DateTime.Now,
                    openid = openid,
                    weixin_applet_appid = weixin_applet.appid,
                    weixin_applet_page = weixin_applet_path,
                    weixin_id = weixin.id,
                    seed_name=seedName,
                };
                db.Insert("weixin_template_success_pay", weixin_template_success_pay);
                return weixinPayInfo;
            }
            else
            {
                //刪除訂單
                orderform.isdelete = 1;
                orderform.remarks = "小程序統一下單失敗,自動刪除";
                db.Update("orderform", orderform, "id="+orderform_id);
            }
            return null;
        }

5.返回給頁面小程序

@model Tlkjbase.Models.WeixinH5Pay
@{
    Layout = null;
    var config = Model.config;
    var chooseWXPay = Model.chooseWXPay;
}

<!DOCTYPE html>

<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="~/Content/css/wxpay1.css" rel="stylesheet" />
    <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script src="~/Scripts/wxpay.js"></script>
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <title>訂單支付</title>
</head>
<body>
    @if (Model.success)
    {
        <header class="top">微信安全支付</header>
        <div class="main-content">
            <div class="title">小程序支付</div>
            <div class="price">¥<span>@Model.money</span></div>
            <div class="pay-info">商品名稱:<div class="info-detail">@Model.seedName</div></div>
            <div class="pay-info">支付時間:<div class="info-detail">@Model.payDate</div></div>
            <div class="pay-info">支付單號:<div class="info-detail">@Model.orderform_number</div></div>
            <div class="pay-info">支付方式:<div class="info-detail">微信支付</div></div>
        </div>
        <div class="button" id="SubmitPay">確認支付</div>

        
       
        <script>

            window.onload = () => {
                var doc = document;
                var docEl = doc.documentElement;
                var width = docEl.getBoundingClientRect().width;
                var rem = width * 100 / 750;
                docEl.style.fontSize = rem + "px";
                wx.config({
                    debug: true, // 開啓調試模式,調用的全部api的返回值會在客戶端alert出來,若要查看傳入的參數,能夠在pc端打開,參數信息會經過log打出,僅在pc端時纔會打印。
                    appId: '@config.appId', // 必填,公衆號的惟一標識
                    timestamp: @config.timestamp, // 必填,生成簽名的時間戳
                    nonceStr: '@config.nonceStr', // 必填,生成簽名的隨機串
                    signature: '@config.signature',// 必填,簽名
                    jsApiList: ['chooseWXPay'] // 必填,須要使用的JS接口列表
                });

                document.getElementById('SubmitPay').onclick=function()
                {
                    submitPay();
                };
            }

            var submitPay = function(){wx.chooseWXPay({
                timestamp: @chooseWXPay.timestamp, // 支付簽名時間戳,注意微信jssdk中的全部使用timestamp字段均爲小寫。但最新版的支付後臺生成簽名使用的timeStamp字段名需大寫其中的S字符
                nonceStr: '@chooseWXPay.nonceStr', // 支付簽名隨機串,不長於 32 位
                package: '@chooseWXPay.package', // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=\*\*\*)
                signType:'@chooseWXPay.signType', // 簽名方式,默認爲'SHA1',使用新版支付需傳入'MD5'
                paySign: '@chooseWXPay.paySign', // 支付簽名
                success: function (res) {
                    // 支付成功後的回調函數
                    alert("支付成功");
                    wx.closeWindow();
                }
            })};
        </script>
    }
    else
    {
        <div class="hint">@Model.message</div>
        <script>
            window.onload = () => {
                var doc = document;
                var docEl = doc.documentElement;
                var width = docEl.getBoundingClientRect().width;
                var rem = width * 100 / 750;
                docEl.style.fontSize = rem + "px";
            }
        </script>
    }
</body>
</html>

6.發送模板消息api

/// <summary>
        /// 組織發送模板消息內容
        /// </summary>
        /// <param name="weixin">微信公衆號信息</param>
        /// <param name="templateCode">模板消息:OPENTM200654400</param>
        /// <param name="openid">用戶在公衆號下的openid</param>
        /// <param name="data">{{first.DATA}} 商家名稱:{{keyword1.DATA}} 商家電話:{{keyword2.DATA}} 訂單號:{{keyword3.DATA}} 狀態:{{keyword4.DATA}} 總價:{{keyword5.DATA}} {{remark.DATA}}</param>
        /// <returns></returns>
        public static string sendWeixinTemplate(orderform orderform, weixin weixin, string templateCode, string openid, string data, string seedName, string appcode, string weixin_applet_path)
        {
            BaseBLL<weixin_template> templateBll = new BaseBLL<weixin_template>();
            weixin_template Template = templateBll.Find(x => x.template_code == templateCode && x.weixin_id == weixin.id);
            //組織發送的數據
            string[] valueArray = data.Split(';');
            JObject _data = JObject.Parse("{}");
            for (int i = 0; i < valueArray.Length; i++)
            {
                if (i == 0)
                {
                    JObject subObject = new JObject(
                       new JProperty("value", valueArray[i]),
                       new JProperty("color", "#173177")
                    );
                    _data.Add("first", subObject);
                }
                else if (i == valueArray.Length - 1)
                {
                    JObject subObject = new JObject(
                       new JProperty("value", valueArray[i]),
                       new JProperty("color", "#173177")
                    );
                    _data.Add("remark", subObject);
                }
                else
                {
                    JObject subObject = new JObject(
                       new JProperty("value", valueArray[i]),
                       new JProperty("color", "#333")
                    );
                    _data.Add("keyword" + (i), subObject);
                }

            }

            WeixinAPI weixinXApi = new WeixinAPI(weixin.appid, weixin.appsecret, weixin.access_token, weixin.access_token_time.ToString(), weixin.id);
            JObject postData = JObject.Parse("{}");
            postData.Add("touser", openid);
            postData.Add("template_id", Template.tempid);
            postData.Add("url", "https://JS安全域名/?orderform_id=" + orderform.id + "&openid=" + openid + "&weixin_id=" + weixin.id + "&appcode=" + appcode + "&seedName=" + seedName + "&weixin_applet_path=" + weixin_applet_path + "&notifyUrl=" + Util.getServerPath());
            postData.Add("data", _data);
            return weixinXApi.sendTemplateByPublic(postData.ToString());
        }
        public string sendTemplateByPublic(string postData)
        {
            LogHelper.Info("sendTemplate:" + postData);
            string url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + AccessToken;
            return HttpHelper.HttpPost(url, postData);
        }
相關文章
相關標籤/搜索