微信JS-SDK]微信公众号JS开发之卡券领取功能详解

js sdk:

http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.952-.E6.89.80.E6.9C.89JS.E6.8E.A5.E5.8F.A3.E5.88.97.E8.A1.A8


微信团队在2015年初改革了微信JS的API,本文主要详细说明其中用到的卡券领取功能.



微信卡券需要认证过的公众号才能申请开通,而且创建的卡券也是要审核才能投放的.微信的卡券对于用户体验上来说比较好,以前促销活动的优惠券,会通过手机短信等方式发送给用户,现在有了"微信卡包"这个将卡券集中管理展示的功能,对于商家来说确实是能很好的拉动线下消费.



卡券管理入口在微信公众号管理后台的功能菜单里,本文先不提如何创建卡券,主要是讲述如何实现将已经生成好的卡券放到自己页面上让用户去领取.



首先要提到目前公众号开发中需要记住的3个重要的需要全局缓存的安全加密凭证:

第一个是:access_token 什么是access_token呢?看介绍.(转载请注明出处:猿资猿味)

1、为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;
2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出的依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。

如果第三方不使用中控服务器,而是选择各个业务逻辑点各自去刷新access_token,那么就可能会产生冲突,导致服务不稳定。

接口调用请求说明

http请求方式: GEThttps://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数说明

参数 是否必须 说明
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

返回说明

正常情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
参数 说明
access_token 获取到的凭证
expires_in 凭证有效时间,单位:秒


第二个是:jsapi_ticket 介绍如下.

jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

  1. 参考上面介绍获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)
  2. 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi


成功返回如下JSON:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}

获得jsapi_ticket之后,就可以用来生成JS-SDK权限验证的签名了,也需要全局缓存下来。



第三个是:卡券 api_ticket 介绍如下.

卡 券 api_ticket 是用于调用卡券相关接口的临时票据,有效期为 7200 秒,通过 access_token 来获取。这里要注意与 jsapi_ticket 区分开来。由于获取卡券 api_ticket 的 api 调用次数非常有限,频繁刷新卡券 api_ticket 会导致 api 调用受限,影响自身业务,开发者必须在自己的服务全局缓存卡券 api_ticket 。

  1. 参考上面介绍获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)
  2. 用第一步拿到的access_token 采用http GET方式请求获得卡券 api_ticket(有效期7200秒,开发者必须在自己的服务全局缓存卡券 api_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card


卡券扩展字段cardExt说明

cardExt本身是一个JSON字符串,是商户为该张卡券分配的唯一性信息,包含以下字段:

字段 是否必填 说明
code 指定的卡券code码,只能被领一次。use_custom_code字段为true的卡券必须填写,非自定义code不必填写。
openid 指定领取者的openid,只有该用户能领取。bind_openid字段为true的卡券必须填写,非自定义openid不必填写。
timestamp 时间戳,商户生成从1970年1月1日00:00:00至今的秒数,即当前的时间,且最终需要转换为字符串形式;

由商户生成后传入。

signature 签名,商户将接口列表中的参数按照指定方式进行签名,签名方式使用SHA1,具体签名方案参见下文;由商户按照规范签名后传入。
balance 红包余额,以分为单位。红包类型必填(LUCKY_MONEY),其他卡券类型不填。


在得到上面这3个凭证之后就可以开始接下来的第二步:网站引入微信的JS文件,注入config配置.这一步操作需要注意的是,网站的域名必须在微信公众号后台添加到了"设置"->"公众号设置"->"功能设置"->"JS接口安全域名"里.

好了,开始引入JS文件.(转载请注明出处:猿资猿味)

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载



通过config接口注入权限验证配置

所 有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: ‘‘, // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: ‘‘, // 必填,生成签名的随机串
    signature: ‘‘,// 必填,签名,见附录1
    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});

上面的jsApiList内填的是要使用的JS接口,我们是要让用户领取卡券,所以需要用到的JS接口方法:addCard

在html文件中加入以下javascript:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

        <script>

                wx.config({

                    debug: true,

                    appId: "{$signature[‘appid‘]}",

                    timestamp: {$signature[‘timestamp‘]},

                    nonceStr: "{$signature[‘noncestr‘]}",

                    signature: "{$signature[‘signature‘]}",

                    jsApiList: [

                            ‘addCard‘

                            ]

                });

            wx.ready(function(){

                                //添加卡券

                document.querySelector(‘#addCard‘).onclick = function () {

                    wx.addCard({

                      cardList: [

                        {

                          cardId: "xxxxxxxxxxxxxxxxxxxxxx",

                          cardExt: ‘{"timestamp":"1426222398","signature":"fdd892770eb681e925f92acb9015c75107b2227a"}‘

                        }

                      ],

                      success: function (res) {

                        alert(‘已添加卡券:‘ + JSON.stringify(res.cardList));

                      }

                    });

                };

            });

    </script>

上面这段代码里重要的参数是:wx.config 这个配置要通过后台计算好后印射前端html里面才行,是动态的.签名算法需要用到的是上面介绍的jsapi_ticket,详细生成规则算法如下:

参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里 需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

即signature=sha1(string1)。

示例:

  • noncestr=Wm3WZYTPz0wzccnW
  • jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
  • timestamp=1414587457
  • url=http://mp.weixin.qq.com?params=value

步骤1.

对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

步骤2. 对string1进行sha1签名,得到signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

注意事项

  1. 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  2. 签名用的url必须是调用JS接口页面的完整URL。
  3. 出于安全考虑,开发者必须在服务器端实现签名的逻辑。


用php写一个满足此条件的签名函数:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

function getJsSign($jsapi_ticket,$url$timestamp=0, $noncestr=‘‘){

        if (!$timestamp)

            $timestamp = time();

        if (!$noncestr)

            $noncestr = generateNonceStr();

        $ret strpos($url,‘#‘);

        if ($ret)

            $url substr($url,0,$ret);

        $url = trim($url);

        if (empty($url))

            return false;

        $arrdata array("timestamp" => $timestamp"noncestr" => $noncestr"url" => $url"jsapi_ticket" => $jsapi_ticket);

        ksort($arrdata);

        $paramstring "";

        foreach($arrdata as $key => $value){

            if(strlen($paramstring) == 0)

                $paramstring .= $key "=" $value;

            else

                $paramstring .= "&" $key "=" $value;

        }

        $sign = sha1($paramstring);

        if (!$sign)

            return false;

        return $sign;

}

function generateNonceStr($length=16){

    // 密码字符集,可任意添加你需要的字符

    $chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    $str "";

    for($i = 0; $i $length$i++)

    {

    $str .= $chars[mt_rand(0, strlen($chars) - 1)];

    }

    return $str;

}

用 generateNonceStr函数生成随机字符串,再传入时间戳,当前页面的url,以及之前缓存好的jsapi_ticket这4个参数经过 getJsSign函数处理即可得到相应的签名了,把这些参数映射给js的wx.config,就完成了.这里的签名如果不通过是没办法调用JS API的,调试前打开debug模式,确保弹出的信息是OK再进行.



JS的签名通过后,就可以调试卡券领取接口JS了.方法是addCard  需要注入到wx.ready(function(){})里面.


1

2

3

4

5

6

7

8

9

10

11

wx.addCard({

    cardList: [

                    {

                cardId: "xxxxxxxxxxxxxxxxxxxxxx",

                cardExt: ‘{"timestamp":"1426222398","signature":"fdd892770eb681e925f92acb9015c75107b2227a"}‘

             }

            ],

    success: function (res) {

              alert(‘已添加卡券:‘ + JSON.stringify(res.cardList));

        }

    });

addCard 方法可以绑定到监听事件document.querySelector(‘#addCard‘).onclick上.cardId是卡券的ID,生成的时 候能够得到,也可以在后台查看;cardExt的话要注意了,如果生成的卡券没有用自定义code,那么只需要timestamp和signature这 两个字段就行了,但是如果生成的卡券是自定义code的,那么需要指定一个code给cardExt,否则在领取时按钮会显示"参数错误".这里的 signature是卡券的签名,和上面提到的JS签名不一样的,此签名的计算方法说明如下:

  1. 将 api_ticket(特别说明:api_ticket 相较 appsecret 安全性更高,同时兼容老版本文档中使用的 appsecret 作为签名凭证。)、timestamp、card_id、code、openid、balance的value值进行字符串的字典序排序。
  2. 将所有参数字符串拼接成一个字符串进行sha1加密,得到signature。
  3. signature中的timestamp和card_ext中的timestamp必须保持一致。
  4. 假 如数据示例中code=23456,timestamp=141231233,card_id=345667,api_ticket=45678则 signature=sha1(14123123323456345667456789)=4F76593A4245644FAE4E1BC940F6422A0C3EC03E。

卡券签名cardSign说明

  1. 将 api_ticket(特别说明:api_ticket 相较 appsecret 安全性更高,同时兼容老版本文档中使用的 appsecret 作为签名凭证。)、app_id、location_id、times_tamp、nonce_str、card_id、card_type的value 值进行字符串的字典序排序。
  2. 将所有参数字符串拼接成一个字符串进行sha1加密,得到cardSign。


用php写一个满足此条件的签名函数:


1

2

3

4

5

6

7

function getCardSign($card){

        sort($card,SORT_STRING);

        $sign = sha1(implode($card));

        if (!$sign)

            return false;

        return $sign;

}

$card是一个数组,里面必须包含时间戳,卡券 api_ticket,如果是自定义的code或者指定openid的用户才能领取,需要把这些额外参数也传到$card中,经过字典排序sha1加密后就能得到卡券签名了.

转载自:https://www.cnblogs.com/ldms/p/5241756.html

原文地址:https://www.cnblogs.com/heroljy/p/9755348.html

时间: 2024-10-04 18:04:37

微信JS-SDK]微信公众号JS开发之卡券领取功能详解的相关文章

微信公众号支付开发全过程 --JAVA

按照惯例,开头总得写点感想 ------------------------------------------------------------------ 业务流程 这个微信官网说的还是很详细的,还配了图.我还要再说一遍. 用户点击一个支付按钮-->{后台一大推处理}-->用户看到了一个输入密码的界面,包含金额等一些信息-->用户输入密码后出来一个支付成功的页面(这部分流程都是微信自己完成的,我们什么都不用做)-->返回系统自己的页面(总不能让用户一直看着一个支付完成的页面吧

微信公众号退款开发

博主是小菜鸟,这篇文章仅是自己开发的随笔记录,不足博友可以指出来,一起进步 1.[微信支付]公众号支付开发者文档链接地址 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 调用微信退款接口,需要发送特定的xml格式字符串到到微信退款接口: 2.微信申请退款需要双向证书, JAVA只需要使用apiclient_cert.p12即可,证书从 https://pay.weixin.qq.com/index.php/core/hom

C#/ASP.NET MVC微信公众号接口开发之从零开发(二) 接收微信消息并且解析XML(附源码)

文章导读: C#微信公众号接口开发之从零开发(一) 接入微信公众平台 微信接入之后,微信通过我们接入的地址进行通信,其中的原理是微信用户发送消息给微信公众账号,微信服务器将消息以xml的形式发送到我们的绑定的地址上,通过解析XML数据,获取到微信用户发送的消息,让根据微信消息(文本:关键字,图片,语音等等)回复XML格式的数据给微信服务器,微信服务器再将接收到的消息返回给用户微信. 我们所需要做的:接收消息和返回消息 一.创建实体类 首先看文档http://mp.weixin.qq.com/wi

C#/ASP.NET MVC微信公众号接口开发之从零开发(三)回复消息 (附源码)

C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发(二) 接收微信消息并且解析XML(附源码) 一.拼凑回复的XML字符串 微信被动回复的形式有一下六种: 1 回复文本消息 2 回复图片消息 3 回复语音消息 4 回复视频消息 5 回复音乐消息 6 回复图文消息 分别对应不同的XML形式,这里以文本消息和图文为例,读者举一反三其他的类似,不再赘述:

C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取

一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号密码.作为微信接口开发人员我们知道网页授权可以用作微信网页用作安全登录,带参数二维码的使用用作记录用户来源,模板消息用作购物消费等消息的通知,但是很少看到有综合利用这些高级接口做出体验比较好的公众账号,这里分享一些我开发的用户绑定和验证码的一些心得.所需要的接口有基础的回复.网页授权.带参数二维码.

微信公众号定制开发

1.配置 公众号   -开发-网页服务-网页授权- 修改 网页授权获取用户基本信息 授权域名. (注: 公众号自动回复开发,需要开启  服务器配置,单独的获取用户信息则不需要. jssdk是 白名单授权管理.) 2.菜单 接入 :   http:// XXX / user/info 访问时用户授权,授权以后跳转到  http://XXX/home?code=xxx (配置)此时再次  调用 http:// XXX / user/info 获取用户信息 放入session(供以后接口获取) 代码参

Python微信公众号后台开发&lt;003&gt;:自定义菜单

有同学问道微信公众号后台开发的自定义菜单怎么实现? 这个问题本来想放到后面的,因为的确对公众号的影响挺明显的, 因为开启后台服务,公众号的自定义菜单就不见了,很影响使用, 也有同学问这个问题,就提前了,后面如果有进展会进行更新. 开发文档: https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Explanation_of_interface_privileges.html 订阅号账号分类及权限 订阅号分为个人号和企业订

如果微信营销离开了公众号

微信营销,是时下的网络营销主流.很多企业都在通过微信的渠道宣传自己的产品.在微信营销上应用的最多的便是公众号.公众号好比微信的核心灵魂,当微信离开了公众号,微信就好比将死之鱼,食之便无味. 公众号是企业和个人的自媒体平台.同时具有营销,客户管理,互动交流,以及品牌建设集于一体的功能.微信公众号也在慢慢与传统行业接轨,智能硬件设备接入微信公众号,将微信公众号万千宠爱于一身.我们设想一下,假如微信不再有公众平台,你们还觉得微信好玩吗?你们还认为微信能够游刃有余的让营销变得简单吗?微信公众号之自媒体建

利用图灵机器人为公众号添加智能问答,知识库功能

1.绪论 订阅号很早就有了,我最近闲了无事就像探索探索可以怎么玩.首先联想到就是微软小冰智能问答系统,还有很早时候有一个公众号提供了,根据c.c++函数名返回API具体用法的功能.那么这两个类似的功能如何实现呢. 2.接入智能问答系统 首先个人需要申请一个公众号,接着在图灵机器人的官网:http://www.tuling123.com/ 注册一个号,选择添加微信公众号,直接扫码关联,ok,智能问答系统接入成功! 其实这个呢,是图灵机器人获取了微信的第三方接口,替你管理了微信号的消息回复功能,并且