最近两个月在重构公司的一个商城项目,小程序端,PC端,后台部分也大部分是我做的。比较忙,所以博客写的比较少。这两天在调试微信支付之后个用户发送一个模板消息的功能。一直出现errcode: 41028, errmsg: “invalid form id hint:的错误。在网上看了一个基本没有一个正确的答案,基本都是照搬微信的文档,并没有说出调试的细节。关于文档,大家可以直接看微信的文档-小程序模板消息。下面写下我的整个开发过程,首先请详细阅读微信相关的文档。

选择模板

1.登录小程序的微信公众平台-模板库

选择你需要的模板。
2.设置那你需要的字段

3.获取模板消息ID
在完成上面两步之后,在我的模板里面就可以看见了。复制模板ID即可。

获取ACCESS_TOKEN

注意点

关于ACCESS_TOKEN这块大家注意两点即可:
1.access_token 是全局唯一接口调用凭据,开发者调用各接口时都需使用 access_token,请妥善保存。access_token 的存储至少要保留512个字符空间。
2.access_token 的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效。
微信给了一种access_token的解决办法:

我没有使用中继服务器。我是保存在本地数据库,给一个接口去获取这个access_token。具体的业务逻辑:
1.调用后端写的获取access_token接口,
2.数据库没有access_token记录,就向腾讯获取一个保存数据库并返回,
3.数据库有记录且最新一天记录的保存时间距离现在时间小于1小时55分,就直接把这个access_token返回给前台,
4.数据库有记录,但最新一条的保存时间距离现在时间大于1小时55分,就重复步骤2.
为什么是1小时55分呢?上面的截图第2点
目前 access_token 的有效期通过返回的 expires_in 来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新 access_token。在刷新过程中,中控服务器对外输出的依然是老 access_token,此时公众平台后台会保证在刷新短时间内,新老 access_token 都可用,这保证了第三方业务的平滑过渡这我预留5分钟,以避免这个问题。

代码实现

router.get('/jkyx/access_token', function(req, res, next) {pool.getConnection(function(err, connection) {if(err){res.end(JSON.stringify({msg: '数据库连接失败',status:'101',}));}var sql = 'select * from access_token order by id desc limit 1';connection.query(sql,function (err, results) {if (err){res.end(JSON.stringify({msg: '数据库查询失败',status:'102',err: err}));}else{var resultsLen = results.length;// 首次 收据库 没数据if (resultsLen == 0) {var urlStr = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + Wx_config.AppID + '&secret='  + Wx_config.Secret;request(urlStr, function (error, response, body) {if (!error && response.statusCode == 200) {var body = JSON.parse(body);var access_token = body.access_token;var create_time = CommonJS.timestamp();var insertSql = 'insert into access_token (access_token,create_time) values (?,?)';connection.query(insertSql,[access_token,create_time],function (err, results) {connection.release();if (err){res.end(JSON.stringify({msg: '数据库查询失败',status:'103',err: err}));}else{res.end(JSON.stringify({msg: '操作成功',status:'100',access_token: access_token}));}})}})} else{ // 数据库有数据var item = results[0];var access_token = item.access_token; // 上一次的access_tokenvar create_time = item.create_time; // 上一次的获取时间var create_time2 = CommonJS.timestamp(); // 当前时间戳var spec_time = create_time2 - create_time;if (spec_time > 6900) {  // 时间戳差值  1小时55分。  余留5分钟给系统。// 再次获取时间戳var urlStr = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + Wx_config.AppID + '&secret='  + Wx_config.Secret;request(urlStr, function (error, response, body) {if (!error && response.statusCode == 200) {var body = JSON.parse(body);var access_tokenr = body.access_token;var create_timer = CommonJS.timestamp();var insertSql = 'insert into access_token (access_token,create_time) values (?,?)';connection.query(insertSql,[access_tokenr,create_timer],function (err, results) {connection.release();if (err){res.end(JSON.stringify({msg: '数据库查询失败',status:'103',err: err}));}else{res.end(JSON.stringify({msg: '操作成功',status:'100',access_token: access_tokenr}));}})}})} else{connection.release();// 取上一次的时间戳res.end(JSON.stringify({msg: '操作成功',status:'100',access_token: access_token}));}}}})})
});

发送模板消息

发送模板消息就好处理了。

这个就是一个处理POST请求参数的问题了。
这里需要注意的是:form_id 是 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
我的是支付成功的通知,这里一定保存整个支付流程都是在真机上面调试,一定不能是手机扫码调试工具上面的二维码支付,不然会一直报错:errcode: 41028, errmsg: “invalid form id hint:
小程序端发送模板消息:

sendMessage: function (prepay_id, payTime){var self = this;var url = app.baseUrl + 'access_token';var access_token = ''; // 微信支付的package 字段的格式是:// prepay_id=wx201801xxxxx// 这里截取 只需要wx201801xxxxxvar prepay_id2 = prepay_id.split('=')[1];wx.request({url: url,success: function(res){var data = res.data;if(data.status == 100){access_token = data.access_token;var accUrl = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=' + access_token;wx.request({url: accUrl,method: 'post',  data: {touser: app.getOpen_id(), template_id: '模板消息ID',page: 'pages/order/index',form_id: prepay_id2,data: {keyword1: {value: payTime, color: "#173177"},keyword2: {value: self.data.order_no,color: "#173177"},keyword3: {value: self.data.pay_amount + '元',color: "#173177"}}},success: function (res) {var data = res.data;console.log(data);},fail: function () {console.log('请求失败');}})}else{console.log('access_token请求失败');}},fail: function(){console.log('请求失败');}})},

至此发送模板消息是做完了。但是这里有存在一个缺陷,如果是线上的小程序版本,需要及时修改模板消息格式就不好了。后来我做的是后台发送模板消息。这个修改就很好做了,这里不再赘述。

注意

一定整个支付流程都是在自己的手机上面完成,一定不要去扫调试工具生成的二维码支付。

微信小程序开发(十七)模板消息相关推荐

  1. TP5之微信小程序推送模板消息

    TP5之微信小程序推送模板消息 1.获取formId并且存储起来,获取formId方法见: https://blog.csdn.net/u010481239/article/details/78239 ...

  2. 微信小程序系列--之模板消息错误提示: errcode: 41028, errmsg: invalid form id hint:如何解决...

    本人从事互联网项目java开发五年,会java,,python,nodejs,前端,爬虫等技术,对发*项目,营销活动,微信业务(公共号,支付,小程序,第三开放平台)很精通.本人也正在努力去实现一套微信 ...

  3. 2019最新微信小程序开发制作模板

    闪云科技小程序,包含多样化的模板和可视化操作页面,能够快速创建各类版本小程序. 单页版: 单页版小程序是单页面的广告墙,主要功能包括:富文本.图片展示.视频播放.地图导航.电话拨打,为创业者提供形象展 ...

  4. PHP小程序接口的模板消息,微信小程序PHP 发送模板消息通知

    注意: 首先,模板消息接口需写在后台服务器上.[追加!目前微信小程序  模板消息只能本人触发并发给本人.] 2018.4.9修改 :1次提交表单可下发1条,多次提交下发条数独立,相互不影响: 1次支付 ...

  5. 微信小程序js发送模板消息

    微信小程序的Java的的后台获取的的的access_token存储数据库并接通本更新https://blog.csdn.net/weixin_41716049/article/details/8406 ...

  6. 微信小程序开发template模板使用

    在小程序开发过程中,一个项目需要在多处页面使用类似的模块,就需要创建模板减少代码量,同时提高代码复用度.小程序通过template 标签使用模板,template 标签的 is 属性与模板的 name ...

  7. 微信小程序之发送模板消息(通过openid推送消息给用户)

    一.获取access_token  access_token是接口调用的凭证,目前有效期为两个小时,需要定时刷新,重复获取将导致上次获取的access_token失效.(注:不建议每次调用需要acce ...

  8. 微信小程序如何突破模板消息限制,获取多个formId?

    做小程序的时候,产品提出模板消息推送用服务通知的方式推送(正常情况是用公众号推送),然后去查小程序手册,发现服务通知存在着问题:(7天有效期)支付等方式只可以获取3个formID,推送3条模板消息,表 ...

  9. 微信小程序开发02(模板语法与事件绑定)

    模板语法与事件绑定

  10. 微信小程序开发导航:精品教程+网友观点+demo源码(5月9日更新)

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教程:https://mp.weixin.qq.com/debu ...

最新文章

  1. 如何看服务器java_如何查看Windows服务器运行了多长时间
  2. python输出数据到excel-如何使用python将传感器数据输出保存到excel中
  3. Scrapy-css选择器
  4. 计算机与科学应用题,计算机应用题
  5. 不是内部或外部命令也不是可运行的程序?
  6. java8 升级_java8升级
  7. 情人节找个程序员当男朋友,一般都不会太差
  8. Python机器学习:决策树003使用信息熵寻找最优划分
  9. 【洛谷习题】尼克的任务
  10. 重写报销流程,责任链模式实现
  11. html 游戏首页,30个让人玩上瘾的HTML5游戏
  12. 移动互联网时代的创业生存法则:快速试错,廉价失败
  13. 4 图像处理基础知识
  14. SylixOS 操作系统Makefile 简介
  15. python连接FTP服务器
  16. n卡驱动要下java吗_N卡驱动要下载哪一个?NVIDIA显卡驱动下载方法
  17. 小程序开发工具命令行启动配置
  18. Apple M1 开启HiDPI的新方法,无需关闭SIP,无需SwitchResX
  19. 文件系统以及硬盘分区概念
  20. could not find driver

热门文章

  1. html 自适应 音乐播放器,使用HTML5+Boostrap打造简单的音乐播放器
  2. c语言标准库函数大全用法,C 标准库函数
  3. 怎么把汉字转换成URL编码
  4. 利用UDP端口转发绕过校园网认证
  5. Talloc内存池介绍
  6. 利用BioEdit做多序列一致性比对
  7. 无需备份!!!动态磁盘转换为基本磁盘!!!绝对可用!!!
  8. 总结的iOS、mac开源项目及库,持续更新。。。。 github排名 https://github.com/trending,github搜索:https://github.com/search
  9. ubuntu1804下txt文件乱码问题
  10. windows下采用批处理命令实现 FTP文件夹下载 包含子文件夹下载 Bat