精华内容
下载资源
问答
  • 微信支付之微信模板消息推送 今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐。原因在哪?就是因为它是依赖微信生存的呀,所以他能不牛逼吗?现在的社会,人多多少少都...
    微信支付之微信模板消息推送
     
            
            今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐。原因在哪?就是因为它是依赖微信生存的呀,所以他能不牛逼吗?现在的社会,人多多少少都有或轻或重的“强迫症”。就是,看到有未读消息,都要去看一下。特别是现在的微信,大部分可以几个小时不看手机QQ有没有新消息来,但是这大部分人绝对做不到一个小时不看微信有没有消息来。现在的微信,真特么是神一样的存在,几乎人人手机上都会有微信。而且,如果你的公众号是服务号的话,这个推送消息会显示在首页列表中(如果有新的消息,会把公众号显示在最顶端,并提示有新消息),不像订阅好,会放在一个小盒子里面。成熟的例子也有许多,例如一些商业银行的刷卡消费提醒这些。好,这方面是他微信的优势,就是,you can't miss it.另外一个优势就是:只要你给他推送了,他的到达率是非常的高,几乎可以保证,100%送达(鉴于天朝的相关法规,这种100%的东西,是没人敢说的,所以,一般都和谐的说99.97%的样子)。所以,以这样的送达率,秒杀传统的短信通知。更有甚者,就是,他的推送,完全免费,完全免费,完全免费!而且,速度极快,速度极快,速度极快。。。好了,再说下去,估计等下你们以为我是腾讯的员工了。好了,这些我就不多说了,下面,我们进入主题吧。
     
            首先,新建一个MVC的项目,如下图(在第二个页面里面,身份认证,改为不需要身份验证):
     
     
            然后我们去把官方demo(demo地址: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1)中的business和lib拷贝到我们的项目中,并新建一个文件夹WxLib,放到里面去,如下图:
     
     
            然后我们再“重新生成”以下项目,或者快捷键:ctrl+shift+b,这时候,会提下如下错误:
     
     
    这时候,我们去添加引用,把 WxLib/ lib文件夹中的 LitJson.dll 添加上即可,如下图:
     
     
     
    到这里,我们就基本把官方的demo的环境给搭建好了,接下来,我们就要开始编写代码了。
     
    首先,我们来看看官方文档,怎么介绍这个模板消息的,查看步骤(这个是需要登录公众平台才能看到的),如下图:
     
     
     
            通过API文档,我们得知,我们推送模板消息,有三个必须要获取到的参数,他们分别是: ACCESS_TOKEN和OPENID,以及template_id,
    ACCESS_TOKEN和OPENID,我们前面的额公众号支付已经演示过如何获取,如果忘了,可以回头看看( 微信支付教程系列之公众号支付),
            
            下面,我来讲讲怎么获取这个template_id。template_id是模板消息的ID,我们推送消息,不像我们发短信一样,可以随意编辑内容,想说啥就说啥,必须要符合模板消息的规则。例如,我们这次选择一个“帐户资金变动提醒”,添加操作如下:
    点击”添加“之后,就会在”我的模板”里面出现,如下图:
     
     
    这个“lypG1jYyOEfYsr*********jOK7-LhEwpPeVNHHxemSI”就是我们的模板ID了,也就是:template_id。
     
            好,现在,我们知道 ACCESS_TOKEN和OPENID以及template_id了,理论上,我们就有了可以发送推送消息的前提了。下面,我们来进入代码部分,如下:
     
     
            首先,新建一个HomeController.cs,代码如下:
    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    namespace 微信支付之模板消息推送.Controllers
    {
        public class HomeController : Controller
        {
            // GET: Home
            public ActionResult Index()
            {
                return View();
            }
        }
    } 
    复制代码

     

     
     
            然后添加一个View,代码如下:
             
    复制代码
    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
    </head>
    <body>
        <div> 
        </div>
    </body>
    </html>
    复制代码

     

     
     
     
     
     
            再说多几句,我们这次选的是一个“帐户资金变动提醒”,他的传参类型如下:
     
    在此之前:由于我们这里面的文字,还可以设定颜色,我们从这里(模板里面看不到,但是可以从官方的demo)可以看出来:
    但是,我们本次用的模板不是这个,是“帐户资金变动提醒”,但是道理相同,所以,我们也要新建一个类,文件名字就叫做:DataFontStyle.cs吧,代码如下:
    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    namespace 微信支付之模板消息推送.Models
    {
        public class DataFontStyle
        {
            public string value { get; set; }
            public string color { get; set; }
        }
    }  
    复制代码

     

    再分析他的参数,分别有:first,date,adCharge,type,cashBalance以及remark,所以,我们给他新建一个Model,到时候会用到的,新建的Model的文件名字就叫做:CashModel.cs,代码如下:
    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
     
    namespace 微信支付之模板消息推送.Models
    {
        /// <summary>
        /// 帐户资金变动提醒Model
        /// </summary>
        public class CashModel
        {
            public DataFontStyle first { get; set; }
            public DataFontStyle date { get; set; }
            public DataFontStyle adCharge { get; set; }
            public DataFontStyle type { get; set; }
            public DataFontStyle cashBalance { get; set; }
            public DataFontStyle remark { get; set; }
        }
    }  
     
    复制代码

     

     
     
     
     
    此外,还有最后一个,那就是这个推送的Model,也要新建一个类,文件名,我们就叫做PushMess.cs吧,代码如下:
     
    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    namespace 微信支付之模板消息推送.Models
    {
        public class PushMessage
        {
            public string touser { get; set; }
            public string template_id { get; set; }
            public string url { get; set; }
            public string topcolor { get; set; }
            /// <summary>
            /// 注意,这里是CashModel,你如果要通用,有多个推送模板要用,那你就用object
            /// </summary>
            public CashModel data { get; set; }
       
        }
    }  
    复制代码

     

    漏了一个类,现在补回来,我们命名为:WxResult.cs,代码如下:
     
       public class WxResult
        {
            public int? errcode { get; set; }
            public string errmsg { get; set; }
            public int? msgid { get; set; }
        }  

     

     
     
    文件物理路径逻辑如下,检查一下,看看有无偏差,如下图:
     
            说明一下:一些推送必须的代码,我就直接贴出(例如后去Access_token和推送代码),不再说明了,因为在前面几篇都有说明,如果看不懂,请翻阅前面的教程。
     
            现在,我们来编辑一下前后端的代码,前端的代码的逻辑,还是跟往常一样,我代码尽量精简,本次,那个推送,我只传一个参数到后台,那就是first,其他的,都是在后台固定,实际项目中应用,到时候,你们再行修改即可,前台代码:
     
     
     
    复制代码
    @{
        Layout = null;
    }
     
    <!DOCTYPE html>
     
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>身份认证</title>
        <link href="~/Scripts/jquery-easyui-1.4.5/themes/bootstrap/easyui.css" rel="stylesheet" />
        <link href="~/Scripts/jquery-easyui-1.4.5/themes/mobile.css" rel="stylesheet" />
        <link href="~/Scripts/jquery-easyui-1.4.5/themes/icon.css" rel="stylesheet" />
        <style type="text/css">
     
            .line {
                width: 100%;
                float: left;
                height: auto;
                text-align: center;
                margin-top: 15pt;
                font-size: x-large;
            }
     
            .lineText {
                width: 100%;
                float: left;
                height: auto;
                text-indent: 5%;
                text-align: left;
                font-size: x-large;
                margin: 0;
            }
     
            a {
                text-decoration: none;
                color: white;
            }
     
            .input {
                height: 30pt;
                width: 90%;
                font-size: x-large;
                border-radius: 10px;
                margin: 0;
                padding: 0;
            }
     
            .btn {
                width: 90%;
                height: 35pt;
                font-size: x-large;
                background-color: green;
                color: white;
                border: none;
                border-radius: 10px;
            }
        </style>
    </head>
    <body>
        <div style="width: 100%; text-align: center;">
            <form id="form1">
                <div class="line">
                    <div class="lineText">*接收者openid:</div>
                </div>
                <div class="line">
                    <input type="text" id="openid" name="openid" class="input" />
                </div>
                <div class="line">
                    <div class="lineText">*first.DATA:</div>
                </div>
                <div class="line">
                    <input type="text" id="first" name="first" class="input" />
                </div>
            </form>
     
        </div>
        <div class="line">
            <input type="button" id="btnSave" class="btn" value="推送" οnclick="fPush()" />
        </div>
        <script src="~/Scripts/jquery-easyui-1.4.5/jquery.min.js"></script>
        <script src="~/Scripts/jquery-easyui-1.4.5/jquery.easyui.min.js"></script>
        <script src="~/Scripts/jquery-easyui-1.4.5/jquery.easyui.mobile.js"></script>
        <script src="~/Scripts/jquery-easyui-1.4.5/easyloader.js"></script>
        <script type="text/javascript">
            $(function () {
                var vCode = getQueryString("code");
                if (vCode != "" && vCode != null) {
                    $.ajax({
                        type: 'post',
                        data: {
                            code: vCode
                        },
                        url: '/Home/getWxInfo',
                        success: function (sjson) {
                            $.messager.show({
                                title: '提示',
                                msg: '欢迎您的到来(看到这个提示,代表已经成功获取openid和access_token了)。'
                            });
                            $("#openid").val(sjson.openid);
                        }
                    })
                }
                else {
                    $.ajax({
                        type: 'post',
                        url: '/Home/getCode',
                        success: function (sjson) {
                            location.href = sjson;
                        }
                    })
                }
            })
            //获取url的参数
            function getQueryString(name) {
                var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
                var r = window.location.search.substr(1).match(reg);
                if (r != null) return unescape(r[2]); return null;
            }
     
            //推送
            function fPush() {
                var vTtile = $("#first").val();
                $.ajax({
                    type: 'post',
                    data: {
                        first: vTtile
                    },
                    url: '/Home/Push',
                    success: function (sjson) {
                        if (sjson.result) {
                            $.messager.alert("提示", sjson.msg, 'info');
                        }
                        else {
                            $.messager.alert("提示", sjson.msg, 'warning');
                        }
                    }
                })
            }
        </script>
    </body>
    </html>
    复制代码

     

     
     
    后台代码:
     
    复制代码
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Script.Serialization;
    using WxPayAPI;
    using 微信支付之模板消息推送.Models;
     
    namespace 微信支付之模板消息推送.Controllers
    {
        public class HomeController : Controller
        {
            JsApiPay jsApiPay = new JsApiPay();
     
            JavaScriptSerializer JsonHelper = new JavaScriptSerializer();
            /// <summary>
            /// 最后更新Access_token的时间
            /// </summary>
            public static DateTime dtAccess_token;
            /// <summary>
            /// Access_token的值
            /// </summary>
            public static string strAccess_token;
            // GET: Home
            public ActionResult Index()
            {
                if (Session["openid"] == null)
                {
                    try
                    {
                        //调用【网页授权获取用户信息】接口获取用户的openid和access_token
                        GetOpenidAndAccessToken();
     
                    }
                    catch (Exception ex)
                    {
                        //Response.Write(ex.ToString());
                        //throw;
                    }
                }
                return View();
            }
     
            /**
            * 
            * 网页授权获取用户基本信息的全部过程
            * 详情请参看网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
            * 第一步:利用url跳转获取code
            * 第二步:利用code去获取openid和access_token
            * 
            */
            public void GetOpenidAndAccessToken()
            {
                if (Session["code"] != null)
                {
                    //获取code码,以获取openid和access_token
                    string code = Session["code"].ToString();
                    Log.Debug(this.GetType().ToString(), "Get code : " + code);
                    jsApiPay.GetOpenidAndAccessTokenFromCode(code);
                }
                else
                {
                    //构造网页授权获取code的URL
                    string host = Request.Url.Host;
                    string path = Request.Path;
                    string redirect_uri = HttpUtility.UrlEncode("http://" + host + path);
                    WxPayData data = new WxPayData();
                    data.SetValue("appid", WxPayConfig.APPID);
                    data.SetValue("redirect_uri", redirect_uri);
                    data.SetValue("response_type", "code");
                    data.SetValue("scope", "snsapi_base");
                    data.SetValue("state", "STATE" + "#wechat_redirect");
                    string url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + data.ToUrl();
                    Log.Debug(this.GetType().ToString(), "Will Redirect to URL : " + url);
                    Session["url"] = url;
                }
            }
     
     
            /// <summary>
            /// 获取code
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public ActionResult getCode()
            {
                object objResult = "";
                if (Session["url"] != null)
                {
                    objResult = Session["url"].ToString();
                }
                else
                {
                    objResult = "url为空。";
                }
                return Json(objResult);
            }
     
            /// <summary>
            /// 通过code换取网页授权access_token和openid的返回数据
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public ActionResult getWxInfo()
            {
                object objResult = "";
                string strCode = Request.Form["code"];
                string strAccess_Token = "";
                string strOpenid = "";
                if (Session["access_token"] == null || Session["openid"] == null)
                {
                    jsApiPay.GetOpenidAndAccessTokenFromCode(strCode);
                    strAccess_Token = Session["access_token"].ToString();
                    strOpenid = Session["openid"].ToString();
                }
                else
                {
                    strAccess_Token = Session["access_token"].ToString();
                    strOpenid = Session["openid"].ToString();
                }
                objResult = new { openid = strOpenid, access_token = strAccess_Token };
                return Json(objResult);
            }
     
            /// <summary>
            /// 推送
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public ActionResult Push()
            {
                object objResult = "";
                string strFirst = Request.Form["first"];
                string strMsg = "";
                bool bResult = false;
                //这个是推送消息的类
                PushMessage aPushMessage = new PushMessage()
                {
                    template_id = "lypG1jYyOEfY********OK7-LhEwpPeVNHHxemSI",//模板ID
                    //data=,//暂时不赋值
                    topcolor = "#FF0000",//头部颜色
                    touser = Session["openid"].ToString(),//用户的Openid
                    url = "http://www.baidu.com"//用途是当用户点击推送消息的时候,会进入这个页面,具体用途,自己拓展
                };
     
                //构造要推送的内容
                CashModel aCachData = new CashModel()
                {
                    adCharge = new DataFontStyle()
                    {
                        color = "#589E63",
                        value = "对应变动金额"
                    },
                    cashBalance = new DataFontStyle()
                    {
                        color = "#589E63",
                        value = "对应帐户余额"
                    },
                    date = new DataFontStyle()
                    {
                        color = "#589E63",
                        value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    first = new DataFontStyle()
                    {
                        color = "#589E63",
                        value = strFirst
                    },
                    remark = new DataFontStyle()
                    {
                        color = "#589E63",
                        value = "对应:点击“查看详情“立即查阅您的帐户财务记录。"
                    },
                    type = new DataFontStyle()
                    {
                        color = "#589E63",
                        value = "对应“现金”"
                    }
                };
                //这时候,把要推送的内容,赋值给push,这样,我们要推送的内容就完成了。
                aPushMessage.data = aCachData;
     
                string strUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + GetLatestAccess_token();
                
                string strJsonData = JsonHelper.Serialize(aPushMessage);
                string strResult = HttpPost(strUrl, strJsonData);
                WxResult aResult = JsonHelper.Deserialize<WxResult>(strResult);
                if (aResult != null)
                {
                    if (aResult.errcode == 0)
                    {
                        bResult = true;
                    }
                    else
                    {
                        bResult = false;
                        strMsg = aResult.errmsg;
                    }
                }
                else
                {
                    bResult = false;
                    strMsg = "通讯失败,请重试。";
                }
     
                objResult = new { result = bResult, msg = strMsg };
                return Json(objResult);
            }
     
     
     
            /// <summary>
            /// HttpPost
            /// </summary>
            /// <param name="Url"></param>
            /// <param name="postDataStr"></param>
            /// <returns></returns>
            public static string HttpPost(string Url, string postDataStr)
            {
                byte[] postData = Encoding.UTF8.GetBytes(postDataStr);//编码,尤其是汉字,事先要看下抓取网页的编码方式   
                WebClient webClient = new WebClient();
                webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");//采取POST方式必须加的header,如果改为GET方式的话就去掉这句话即可  
                byte[] responseData = webClient.UploadData(Url, "POST", postData);//得到返回字符流             
                string srcString = Encoding.UTF8.GetString(responseData);//解码 
                return srcString;
               
            }
     
     
            /// <summary>
            /// 返回最新的Access_token
            /// </summary>
            /// <returns></returns>
            public string GetLatestAccess_token()
            {
                if (dtAccess_token == null || dtAccess_token <= DateTime.Now.AddHours(-1) || string.IsNullOrWhiteSpace(strAccess_token))
                {
                    string strUrl = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", WxPayConfig.APPID, WxPayConfig.APPSECRET);
                    string strAccess_tokenData = HttpGet(strUrl, "");
                    ModelForAccess_token aToken = JsonHelper.Deserialize<ModelForAccess_token>(strAccess_tokenData);
                    dtAccess_token = DateTime.Now;
                    strAccess_token = aToken.access_token;
                    return strAccess_token;
                }
                else
                {
                    return strAccess_token;
                }
            }
     
            /// <summary>
            /// WebGet
            /// </summary>
            /// <param name="Url"></param>
            /// <param name="postDataStr"></param>
            /// <returns></returns>
            public static string HttpGet(string Url, string postDataStr)
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
                request.Method = "GET";
                request.ContentType = "text/html;charset=UTF-8";
     
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                string retString = myStreamReader.ReadToEnd();
                myStreamReader.Close();
                myResponseStream.Close();
     
                return retString;
            }
     
            public class ModelForAccess_token
            {
                public string access_token { get; set; }
                public int? expires_in { get; set; }
            }
        }
    } 
    复制代码

     

     
     
    代码已完整提供,如果有缺漏的,请在评论中指出或者进群来告诉我。如果代码提供正常,应该就能推送到的了,目前这个代码,只能给自己推送。实际应用中,可以通过这个页面,然后绑定用户,这样,我们就可以通过用户名字,给他们的openid推送消息。下面贴出推送的截图
     
     
     
    对了,忘记了一点,这个要发布到IIS上,然后你发布的域名,要在公众平台里面,那个获取用户权限(前面博文提及到)的网址里面,改成你发布的网址,例如:push.lmx.ren ,否则是获取不到用户信息的。
     

    转载于:https://www.cnblogs.com/zhangxiaolei521/p/6251775.html

    展开全文
  • pc端支持微信支付 [ Native支付官方API] && 支付宝支付 [电脑网站支付官方API ] 订单生成逻辑:前端请求后端提交订单,后端去和微信或者支付宝对接生成订单(后续支付都是这个逻辑进行的对接) 一、vue中pc...

    业务场景介绍:

    pc端支持微信支付 [ Native支付官方API] && 支付宝支付 [电脑网站支付官方API ]

    订单生成逻辑:前端请求后端提交订单,后端去和微信或者支付宝对接生成订单(后续支付都是这个逻辑进行的对接)

    一、vue中pc端微信支付怎么去玩?

    这里大部分工作量是后端的事情,订单的生成由后端去和腾讯对接的,前端只需要负责将后端返回来的支付二维码(由后端生成的,有些情况也可以前端去对接订单生成之后由前端自己生成二维码,这种情况比较少)展示在终端供用户扫码即可:
    1.二维码展现窗口
    在这里插入图片描述
    2.请求后端的支付二维码接口
    在这里插入图片描述
    3.唤起二维码支付页面
    在这里插入图片描述
    4.扫码完成支付即可,后续完成支付就是项目中的业务逻辑了。至此微信PC端支付已完成,前端的工作量是不是很少~

    二、vue中pc端支付宝支付怎么玩?

    上述微信支付这么简单,同理pc端的支付宝支付也很简单,因为业务层与支付宝做订单交互还是后端处理的,所以前端的工作量就相当简单。
    1.这里需要一个承载页面,来承载后端与支付宝完成交互之后,请求后端支付接口会返回一个from表单,前端只需要负责把它展现给用户扫码即可,承接页面如下(为了方便ctrl+c这里贴代码):

    <template>
        <div v-html="html"></div>
    </template>
    
    <script>
      import { videoPay } from '@/api/pay.js'
      export default {
        data(){
          return{
            html:''
          }
        },
        methods:{
          fetchVideoPay(){
            let param={
              orderId: this.$route.query.orderId
            };
            videoPay(param).then( res => {
              this.html = res.data;
              this.$nextTick(() => {
                document.forms[0].submit()
              })
            })
          }
        },
        mounted(){
          this.fetchVideoPay()
        }
      }
    </script>
    
    

    2.到达承载页面之后会出来支付宝的二维码页面:
    在这里插入图片描述
    3.用户扫码完成之后,进入支付宝倒计时页面后续就是业务逻辑处理了,至此支付宝PC支付也已经完成。

    移动端H5支付(微信+支付宝)点击查看

    展开全文
  • html5微信支付 页面效果
  • 小程序web-view使用方法是子恒老师《子恒说小程序开发》视频...详细讲解了小程序web-view组件的使用,内容包含web view打开网页,网页与小程序之间的跳转,在web view中实现微信支付等等。欢迎反馈,微信号:QQ68183131
  • 我使用了官网的demo,扫描后成功支付了,还是停留在这个页面,请问支付成功了怎么跳转到我指定的信息提示页面呢?我应该在哪里处理才行?回复讨论(解决方案)不是有支付成功后的回调函数,在那个函数里面操作,跳转到...

    我使用了官网的demo,扫描后成功支付了,还是停留在这个页面,请问支付成功了怎么跳转到我指定的信息提示页面呢?我应该在哪里处理才行?

    回复讨论(解决方案)

    不是有支付成功后的回调函数,在那个函数里面操作,跳转到你的页面。

    有一个回调地址设置的。

    有一个回调地址设置的。

    回调地址设置

    我notify_url.php的代码如下

    /** * 通用通知接口demo * ==================================================== * 支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL, * 商户接收回调信息后,根据需要设定相应的处理流程。 * * 这里举例使用log文件形式记录回调信息。*/include_once("./log_.php");include_once("../WxPayPubHelper/WxPayPubHelper.php"); //使用通用通知接口$notify = new Notify_pub();//存储微信的回调$xml = $GLOBALS['HTTP_RAW_POST_DATA'];$notify->saveData($xml);if($notify->checkSign() == FALSE){$notify->setReturnParameter("return_code","FAIL");//返回状态码$notify->setReturnParameter("return_msg","签名失败");//返回信息}else{$notify->setReturnParameter("return_code","SUCCESS");//设置返回码}$returnXml = $notify->returnXml();echo $returnXml;//==商户根据实际情况设置相应的处理流程,此处仅作举例=======//以log文件形式记录回调信息$log_ = new Log_();$log_name="./notify_url.log";//log文件路径$log_->log_result($log_name,"【接收到的notify通知】:\n".$xml."\n");if($notify->checkSign() == TRUE){if ($notify->data["return_code"] == "FAIL") {//此处应该更新一下订单状态,商户自行增删操作$log_->log_result($log_name,"【通信出错】:\n".$xml."\n");}elseif($notify->data["result_code"] == "FAIL"){//此处应该更新一下订单状态,商户自行增删操作$log_->log_result($log_name,"【业务出错】:\n".$xml."\n");}else{//此处应该更新一下订单状态,商户自行增删操作$log_->log_result($log_name,"【支付成功】:\n".$xml."\n");} $myfile = fopen("sfq.txt", "w") or die("Unable to open file!"); fwrite($myfile, $returnXml); fclose($myfile); header("Location: http://www.bjp51.net/"); //商户自行增加处理流程,//例如:数据库操作}

    上面的代码为何无法跳转到http://www.bjp51.net/ 首页呢?

    不知道我理解得对不?

    有一个回调地址设置的。

    已回复,麻烦版主帮看下

    PC 端 用 微信 扫码支付。。。成功后。

    PC 端的WEB 页面,肯定不会自然跳转。

    支付成功后,微信会通知你的服务器,说支付成功了。然后你的服务器,进行相应的数据更改

    你的PC 端的支付页面呢。做一个 JS ajax 请求 ,查询是否支付成功。每10秒一次,查到成功后,就跳转。

    PC 端 用 微信 扫码支付。。。成功后。

    PC 端的WEB 页面,肯定不会自然跳转。

    支付成功后,微信会通知你的服务器,说支付成功了。然后你的服务器,进行相应的数据更改

    你的PC 端的支付页面呢。做一个 JS ajax 请求 ,查询是否支付成功。每10秒一次,查到成功后,就跳转。

    谢谢,我就是按照你的方法做的,现在成功了

    但另一个问题又来了,就是jsasp的方法 用UC浏览器怎么支付成功呢?

    大家可以看我另一个微信支付问题 http://bbs.csdn.net/topics/391926831

    本文原创发布php中文网,转载请注明出处,感谢您的尊重!

    展开全文
  • Java调用微信支付

    万次阅读 多人点赞 2020-06-17 02:04:46
    Java 使用微信支付 一. 准备工作 1.

    Java 使用微信支付

    前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用。
    因为涉及二维码的前端显示,所以有前端的内容

    一. 准备工作

    所需微信公众号信息配置

    • APPID:绑定支付的APPID(必须配置)
    • MCHID:商户号(必须配置)
    • KEY:商户支付密钥,参考开户邮件设置(必须配置)
    • APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)

    我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供

    二. 构建项目架构

    1.新建maven项目

    在这里插入图片描述

    2.导入依赖

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.1.RELEASE</version>
        </parent>
        <dependencies>
            <!--spring boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--微信提供的sdk-->
            <dependency>
                <groupId>com.github.wxpay</groupId>
                <artifactId>wxpay-sdk</artifactId>
                <version>0.0.3</version>
            </dependency>
            <!--发送http请求-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </dependency>
            <!--模板引擎-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
        </dependencies>
    

    在这里插入图片描述
    依赖中需要注意的是我导入了微信提供的sdk,以及freemarker模板引擎

    3.编写配置文件application.properties

    # 服务端口
    server.port=8081
    # 微信开放平台 appid
    wx.pay.app_id=
    #商户号
    wx.pay.partner=
    #商户key
    wx.pay.partnerkey=
    #回调地址
    wx.pay.notifyurl:
    
    spring.freemarker.tempalte-loader-path=classpath:/templates
    #        关闭缓存,及时刷新,上线生产环境需要修改为true
    spring.freemarker.cache=false
    spring.freemarker.charset=UTF-8
    spring.freemarker.check-template-location=true
    spring.freemarker.content-type=text/html
    spring.freemarker.expose-request-attributes=true
    spring.freemarker.expose-session-attributes=true
    spring.freemarker.request-context-attribute=request
    spring.freemarker.suffix=.ftl
    spring.mvc.static-path-pattern: /static/**
    

    在这里插入图片描述

    4.编写启动类

    @SpringBootApplication
    @ComponentScan(basePackages = {"com.haiyang.wxpay"})
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    

    在这里插入图片描述

    5.创建常用包controller,service,impl,utils

    在这里插入图片描述

    6.创建两个前端需要的文件夹 static和templates

    在这里插入图片描述

    三. 代码实现

    1. 创建工具类读取配置文件的参数

    @Component
    public class WxPayUtils implements InitializingBean {
    
        @Value("${wx.pay.app_id}")
        private String appId;
    
        @Value("${wx.pay.partner}")
        private String partner;
    
        @Value("${wx.pay.partnerkey}")
        private String partnerKey;
        @Value("${wx.pay.notifyurl}")
        private String notifyUrl;
    
    
        public static String WX_PAY_APP_ID;
        public static String WX_PAY_PARTNER;
        public static String WX_PAY_PARTNER_KEY;
        public static String WX_OPEN_NOTIFY_URL;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            WX_PAY_APP_ID = appId;
            WX_PAY_PARTNER = partner;
            WX_PAY_PARTNER_KEY = partnerKey;
            WX_OPEN_NOTIFY_URL = notifyUrl;
        }
    
    }
    

    在这里插入图片描述

    2. 构建工具类发送http请求

    /**
     * http请求客户端
     * 
     * @author qy
     * 
     */
    public class HttpClient {
    	private String url;
    	private Map<String, String> param;
    	private int statusCode;
    	private String content;
    	private String xmlParam;
    	private boolean isHttps;
    
    	public boolean isHttps() {
    		return isHttps;
    	}
    
    	public void setHttps(boolean isHttps) {
    		this.isHttps = isHttps;
    	}
    
    	public String getXmlParam() {
    		return xmlParam;
    	}
    
    	public void setXmlParam(String xmlParam) {
    		this.xmlParam = xmlParam;
    	}
    
    	public HttpClient(String url, Map<String, String> param) {
    		this.url = url;
    		this.param = param;
    	}
    
    	public HttpClient(String url) {
    		this.url = url;
    	}
    
    	public void setParameter(Map<String, String> map) {
    		param = map;
    	}
    
    	public void addParameter(String key, String value) {
    		if (param == null)
    			param = new HashMap<String, String>();
    		param.put(key, value);
    	}
    
    	public void post() throws ClientProtocolException, IOException {
    		HttpPost http = new HttpPost(url);
    		setEntity(http);
    		execute(http);
    	}
    
    	public void put() throws ClientProtocolException, IOException {
    		HttpPut http = new HttpPut(url);
    		setEntity(http);
    		execute(http);
    	}
    
    	public void get() throws ClientProtocolException, IOException {
    		if (param != null) {
    			StringBuilder url = new StringBuilder(this.url);
    			boolean isFirst = true;
    			for (String key : param.keySet()) {
    				if (isFirst)
    					url.append("?");
    				else
    					url.append("&");
    				url.append(key).append("=").append(param.get(key));
    			}
    			this.url = url.toString();
    		}
    		HttpGet http = new HttpGet(url);
    		execute(http);
    	}
    
    	/**
    	 * set http post,put param
    	 */
    	private void setEntity(HttpEntityEnclosingRequestBase http) {
    		if (param != null) {
    			List<NameValuePair> nvps = new LinkedList<NameValuePair>();
    			for (String key : param.keySet())
    				nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
    			http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
    		}
    		if (xmlParam != null) {
    			http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
    		}
    	}
    
    	private void execute(HttpUriRequest http) throws ClientProtocolException,
    			IOException {
    		CloseableHttpClient httpClient = null;
    		try {
    			if (isHttps) {
    				SSLContext sslContext = new SSLContextBuilder()
    						.loadTrustMaterial(null, new TrustStrategy() {
    							// 信任所有
    							public boolean isTrusted(X509Certificate[] chain,
    									String authType)
    									throws CertificateException {
    								return true;
    							}
    						}).build();
    				SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
    						sslContext);
    				httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
    						.build();
    			} else {
    				httpClient = HttpClients.createDefault();
    			}
    			CloseableHttpResponse response = httpClient.execute(http);
    			try {
    				if (response != null) {
    					if (response.getStatusLine() != null)
    						statusCode = response.getStatusLine().getStatusCode();
    					HttpEntity entity = response.getEntity();
    					// 响应内容
    					content = EntityUtils.toString(entity, Consts.UTF_8);
    				}
    			} finally {
    				response.close();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			httpClient.close();
    		}
    	}
    
    	public int getStatusCode() {
    		return statusCode;
    	}
    
    	public String getContent() throws ParseException, IOException {
    		return content;
    	}
    
    }
    
    

    额~有点长就不放图片了 代码都一样

    3. 新建controller

    @Controller
    @RequestMapping("/wxpay")
    public class WxPayController {
        @RequestMapping("/pay")
        public String createPayQRcode(Model model) throws Exception{
    
            String price = "0.01";
            String no = getOrderNo();
            Map m = new HashMap();
            m.put("appid", WxPayUtils.WX_PAY_APP_ID);
            m.put("mch_id", WxPayUtils.WX_PAY_PARTNER);
            m.put("nonce_str", WXPayUtil.generateNonceStr());
            m.put("body","微信支付测试"); //主体信息
            m.put("out_trade_no", no); //订单唯一标识
            m.put("total_fee", getMoney(price));//金额
            m.put("spbill_create_ip", "127.0.0.1");//项目的域名
            m.put("notify_url", WxPayUtils.WX_OPEN_NOTIFY_URL);//回调地址
            m.put("trade_type", "NATIVE");//生成二维码的类型
    
            //3 发送httpclient请求,传递参数xml格式,微信支付提供的固定的地址
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
            //设置xml格式的参数
            //把xml格式的数据加密
            client.setXmlParam(WXPayUtil.generateSignedXml(m, WxPayUtils.WX_PAY_PARTNER_KEY));
            client.setHttps(true);
            //执行post请求发送
            client.post();
            //4 得到发送请求返回结果
            //返回内容,是使用xml格式返回
            String xml = client.getContent();
            //把xml格式转换map集合,把map集合返回
            Map<String,String> resultMap = WXPayUtil.xmlToMap(xml);
            //最终返回数据 的封装
            Map map = new HashMap();
            map.put("no", no);
            map.put("price", price);
            map.put("result_code", resultMap.get("result_code"));
            map.put("code_url", resultMap.get("code_url"));
    
            model.addAttribute("map",map);
            return "pay";
    
        }
    
        @GetMapping("queryorder/{no}")
        @ResponseBody
        public String queryPayStatus(@PathVariable String no) throws Exception{
            //1、封装参数
            Map m = new HashMap<>();
            m.put("appid", WxPayUtils.WX_PAY_APP_ID);
            m.put("mch_id", WxPayUtils.WX_PAY_PARTNER);
            m.put("out_trade_no", no);
            m.put("nonce_str", WXPayUtil.generateNonceStr());
    
            //2 发送httpclient
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            client.setXmlParam(WXPayUtil.generateSignedXml(m, WxPayUtils.WX_PAY_PARTNER_KEY));
            client.setHttps(true);
            client.post();
    
            //3.得到订单数据
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
    
            //4.判断是否支付成功
            if(resultMap.get("trade_state").equals("SUCCESS")) {
                /*
                      改变数据库中的数据等操作
                 */
                return "支付成功";
            }
            return "支付中";
        }
    
        @GetMapping("success")
        public String success(){
            return "success";
        }
        @RequestMapping("test")
        public String test(){
            return "pay";
        }
        /**
         * 生成订单号
         * @return
         */
        public static String getOrderNo() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String newDate = sdf.format(new Date());
            String result = "";
            Random random = new Random();
            for (int i = 0; i < 3; i++) {
                result += random.nextInt(10);
            }
            return newDate + result;
        }
        /**
         * 元转换成分
         * @param amount
         * @return
         */
        public static String getMoney(String amount) {
            if(amount==null){
                return "";
            }
            // 金额转化为分为单位
            // 处理包含, ¥ 或者$的金额
            String currency =  amount.replaceAll("\\$|\\¥|\\,", "");
            int index = currency.indexOf(".");
            int length = currency.length();
            Long amLong = 0l;
            if(index == -1){
                amLong = Long.valueOf(currency+"00");
            }else if(length - index >= 3){
                amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
            }else if(length - index == 2){
                amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
            }else{
                amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
            }
            return amLong.toString();
        }
    }
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    值得一提的是 这里我们用的是controller而不是restcontroller,因为我们需要展示二维码

    4. 在templates文件中新建 订单支付页面(二维码生成的页面)

    注意:文件名必须和生成二维码方法中返回的字符串名称一样 我这里叫 pay

    先新建html页面,然后再将后缀改成ftl(freemarker模板引擎的后缀名)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/qrcode.js"></script>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    </head>
    <center>
        <div id="qrcode"></div>
    </center>
    <script type="text/javascript">
        new QRCode(document.getElementById("qrcode"), "${map.code_url}");  // 设置要生成二维码的链接
    </script>
    <script type="text/javascript">
        var int=self.setInterval("querystatus()",3000);
        function querystatus() {
            $.get("/wxpay/queryorder/${map.no}",function(data,status){
                if (data==="支付中"){
                    console.log("支付中");
                } else {
                    clearInterval(int)
                    window.location.href="/wxpay/success"
                }
            })
        }
    </script>
    </body>
    </html>
    

    在这里插入图片描述
    再创建支付成功跳转的页面 文件名要与支付成功方法返回的文件名一样

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>支付成功</h1>
    </body>
    </html>
    

    在这里插入图片描述
    引入 qrcode 生成二维码的依赖,放入static文件中
    这里我提供下载链接
    链接: https://pan.baidu.com/s/15-E3KpRCenAewh0ZaBLnjQ 提取码: xhs9 复制这段内容后打开百度网盘手机App,操作更方便哦

    引入完成后
    在这里插入图片描述

    最后 我们启动项目来测试一下

    浏览器输入地址
    http://localhost:8081/wxpay/pay
    发现二维码生成成功,并且定时器也没问题
    在这里插入图片描述
    之后我们扫码支付
    成功跳转到支付成功页面 ~nice
    在这里插入图片描述

    四. 总结

    1. 首先就是生成二维码,需要的几个主要的参数,订单号,金额,购买的信息(主体信息),其余的参数除了一些可以不写的都是固定的
    2. 生成二维码然后展示在页面上,用的qrcode插件,生成
    3. 然后设置定时器,来实时查询订单是否支付
    4. 查询订单信息的写法和生成二维码的方式差不多 无非就是请求时少了几个参数,必须得带上订单号
    5. 微信提供的查询订单接口返回数据中 trade_state 代表支付状态 notpay没有支付,seccess表示已成功
    6. 定时器检测到订单支付成功就清除定时器,并且执行支付成功之后的操作

    实际项目中远没有这么简单,并且所有的数据都要从数据库中获取,在这里我为了方便把价格固定写死的

    展开全文
  • 公众号的页面会在微信环境下打开,所以默认已经有登录态。openID、AppID、AppSecret 都能拿到,申请开通商家支付之后会有 PayKey 和 mch_id (商家帐号,类似 101000000 之类的数字)。 商家要完成一次支付需要首先...
  • 包含微信支付网页内支付,微信扫码支付,支付宝即时到账,涵盖了当前主流的支付解决方案,内容简单易懂,一学就会,后台语言采用Java编写完成。在实战的过程中学会解决问题,后一堂课都有我的微信,如果不懂的话可以...
  • 微信支付开发——公众号支付

    万人学习 2016-10-27 14:33:09
    微信已经融入到人们的生活中,很多企业也...这是一部中课程,需要有学习的开发者拥有微信开发和PHP的相关基础:微信支付在项目中的位置、微信支付类型、微信支付涉及内容、微信公众号支付功能实现、微信支付安全建议。
  • 如果你不会微信支付开发,你微信公众号开发白学了!现在微商城越来越火,微信支付开发是的技术技能,也是众多网络技术公司招聘技术的条件。本课程将一步一步带你实现微信支付开发网页版。让你的公众号变现不再是梦
  • 工具类见:微信支付JAVA版本之Native付款 2.公众账号设置 3.代码实现 package com.zhrd.bussinss.platform.controller.rest; import java.io.File; import java.io.FileInputStream; import java.io.InputStream;...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。提供java版、c#版、python3版、php版课程。按照...
  • 微信支付微信扫码支付java版

    千人学习 2017-04-05 22:41:59
    现在所有的web端网页商城常用的支付方式之一。web网站开发课程,web网站要实现支付的话,必须学习微信扫码支付。内容逻辑清晰,包你一会就会
  • 1,首先,先说说用途吧,公司最近要求开发一个功能,就是给不同类型的用户...4,下面拿这个做例子,发送告警模板信息:5,代码方面,你新建一个页面,我的基础是以官方的Demo拓展的,首先,进入首页的时候,获取Openid和token,要...
  • 然后通过发起预支付将参数填入h5页面中,从而测试h5支付。 直接访问h5页面便可以在手机中弹出支付控件。完成支付。 问题:直接将参数填入static目录下的页面中,项目上线后是不可能的。 我是用freemarker模板引擎...
  • 微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等...
  • 讲解微信小程序支付V3。购课提供源程序。   购课咨询请联系九宝老师。   课程详细讲解微信小程序支付V3版的相关知识点。   九宝培训同时提供微信公众号、企业微信微信小程序、支付宝支付、支付宝小...
  • 讲解微信小程序支付V3。购课提供源程序。   购课咨询请联系九宝老师。   课程详细讲解微信小程序支付V3版的相关知识点。   九宝培训同时提供微信公众号、企业微信微信小程序、支付宝支付、支付宝小...
  • 微信支付java版v2.0_JSAPI支付支付

    千人学习 2017-04-17 08:33:12
    “程序演示和开发流程”要求必须认真学习,“开发流程”讲的是微信支付开发、部署的重要信息。 学习有技术问题请qq2326321088 建议在学习微信支付的同学具有“微信服务号”和“微信企业号”的技术基础。
  • 商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程 广泛应用微信商城的支付 完成微信网页授权以及微信JSAPI支付的实现,涉及到https,xml的生成与解析,MD5的...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...
  • 微信支付V3版系列课程详细讲解微信支付的JSAPI支付、H5支付、Native支付、申请退款、支付结果通知、退款结果通知、申请交易账单、申请资金账单、下载账单、关闭订单。 提供java版、c#版、python3版、php版课程。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,015
精华内容 1,606
关键字:

微信支付web页面模板