• 微信公众号支付


    1.设置JS安全域名

     

    2.开通微信支付,并在商户端设置支付安全域名

     3.获取JSAPI权限参数

            /// <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.发送模板消息

    /// <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);
            }
    纸上得来终觉浅,绝知此事要躬行
  • 相关阅读:
    robotframework安装与配置--学习第一天
    Google chrome浏览器打不开网页,显示ERR_Failed...等问题的解决方法
    解决dos窗口乱码问题
    打印风车旋转效果
    spring Security 得到认证用户名的方法
    spring requestmapping 拦截多个请求
    github多人协同使用。
    Spring boot Security 用于权限管理,用户添加等。
    spring boot上传 下载图片。
    mysql修改数据库编码(数据库字符集)和表的字符编码的方法
  • 原文地址:https://www.cnblogs.com/zhaoshang/p/9174682.html
Copyright © 2020-2023  润新知