本文是【淺析微信支付】系列文章的第十六篇,主要講解如何使用微信公眾平台的卡券功能、如何使用HTML5在網頁展示用戶領券以及微信卡券和商戶平台代金券的關系。
淺析微信支付系列已經更新十六篇了喲~,沒有看過的朋友們可以看一下哦。
淺析微信支付:商戶平台代金券或立減優惠開通、指定用戶代金券發放、查詢等
淺析微信支付:商戶平台開通現金紅包、指定用戶發放、紅包記錄查詢
前幾篇文章主要介紹了如何在【微信商戶平台】使用代金券和滿減優惠折扣等產品功能,有不少小伙伴說到,【微信公眾平台】也有一個卡券功能,那么他們有什么差別呢?這個卡券功能該如何使用?本文會給大家一個解釋。
兩者的差別
首先,我們來解釋商戶平台和微信平台各自優惠券的區別,如果有人試過,那么應該知道,兩者是不通用的,不通用的,不通用的!!!
至於這里要重點標識不通用?因為在開通微信卡券功能后,在商戶平台也會出現微信卡券對應優惠券信息,雖然沒有發券的功能,只是展示,但如果我們走接口發券,就會出現 發券失敗,不支持發送xxx類型的優惠券
的錯誤,這時就尷尬了;
還沒完,因為平台不同,所以微信卡券和支付優惠券發送、領取的方式(接口)也是不同的,包括用戶領取時跳轉到的頁面也不相同,這個也請大家注意。
所以,我們需要將這兩種券作為兩種不同種類的券來處理就可以了。
公眾平台卡券功能開通
登陸公眾平台 https://mp.weixin.qq.com
,點擊左側[功能-添加功能插件],進入插件庫頁面,進入[卡券功能],可以開通卡券功能。
申請條件:
必須開通微信支付功能!!!!
功能介紹:
卡券功能,是提供給商戶或第三方的一套派發優惠券,經營管理會員的工具,可在公眾平台或通過接口創建卡券,多種渠道投放給用戶,用戶用券時需核銷卡券,核銷后可查看數據、進行對賬。
主要能力:
●朋友共享的優惠券——可利用社交鏈快速擴散傳播,一人領券,本人和朋友皆可看到並使用。查看視頻介紹
●普通優惠券——傳統優惠券電子版,領取后僅本人可見可用,支持多種類型:折扣券、代金券、兌換券、團購券、優惠券。
●會員卡——支持折扣、積分等玩法,並提供會員管理、數據報表等豐富工具,便於商戶高效運營會員。
●微信買單——無需進行微信支付開發,同時與會員卡,代金券,折扣券打通,為你積累用戶消費數據,用於經營參考
●儲值功能——會員卡商戶無需申請,可直接通過API接口,使用“余額展示”功能,將會員余額顯示在微信會員卡首頁。具有預付卡資質的商家可申請“儲值”功能,申請成功后,可通過API接口設置此入口,幫助會員通過微信支付為會員卡充值。
●第三方代制模式——經商戶授權后,可代子商戶快速接入並使用卡券功能,支持通過公眾平台或API接口實現該功能。
官方開發文檔地址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141229
這里就已知小伙伴們已經開通卡券功能,如何手動創建優惠券可以在公眾平台上操作,很簡單,這里就不說了,本文主要講如何使用接口的方式來創建卡券、用戶領取、查詢卡券詳情。
微信卡券指引
官方文檔地址:
https://mp.weixin.qq.com/cgi-bin/readtemplate?t=cardticket/faq_tmpl&type=info&token=&lang=zh_CN#0
下面是卡券功能開通指引
對應的申請渠道、申請條件:
有需要的小伙伴可以通讀一下上面官方文檔,讀完之后就會對微信卡券有所認識了,差不多基礎業務都能做到心中有數咯。
如果是開發者,直接看下面微信卡券接口文檔
就行,畢竟我們更關心接口相關的信息,官方文檔如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141229
下載卡券資料包:
https://mp.weixin.qq.com/zh_CN/htmledition/comm_htmledition/res/cardticket/wx_card_document.zip?token=&lang=zh_CN
根據官方文檔的步驟,需要整整七步,下面為具體步驟:
- 獲取access_token
- 上傳卡券logo
- 創建卡券
- 創建二維碼投放
- 顯示二維碼
- 設置測試白名單
- 核銷卡劵
官方的文檔主要是使用了沙箱測試賬號
來測試並驗證,關於接口測試號申請可以通過以下鏈接來取得:
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
下面我們來一步步分析接口。
獲取access_token
頁面地址:http://mp.weixin.qq.com/debug/
接口類型:基礎支持
接口列表:獲取access_token接口
注意事項:參數填寫開發者的appid和secret
點擊檢查問題,即可返回access_token,access_token的有效期是兩小時,兩小時之后須重新獲取
接口地址:獲取access_token接口 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
這里的獲取微信全局access_token接口就不講了,能看到這篇文章的小伙伴應該早就寫過了,哈哈哈。
上傳卡券logo
頁面地址:http://mp.weixin.qq.com/debug/
接口類型:基礎支持
接口列表:上傳圖片素材接口
access_token: 上一步獲得的access_token
buffer:你選擇的圖片
點擊檢查問題,即可獲取圖片url,在下一步創建卡劵的參數中需要
接口地址:上傳圖片接口 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025056
此接口就是上傳商戶logo,可以獲得一個卡券logo鏈接,基本上就用一次,如果不想使用此接口來上傳logo,可以在公眾平台手動創建優惠券時上傳logo,上傳后可以在logo圖片上鼠標右鍵-復制圖片路徑,也是一樣的(不想調接口的可以用這個歪招哈哈哈哈)。
創建卡券
頁面地址:http://mp.weixin.qq.com/debug/
接口類型:卡劵接口
接口列表:創建卡劵接口
access_token:第一步獲得的access_token
創建卡券接口地址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025056
以下為調用接口示例:
https://api.weixin.qq.com/card/create?access_token=xxx
JSON示例:
{
"card": {
"card_type": "CASH",
"cash": {
"base_info": {
"logo_url": "https://mmbiz.qlogo.cn/mmbiz_png/E5Q3G4ku9nf7UiafOetcAPLyfia7kdWWWauHukNN7ZXnggtZcTzEPGa8IUDiaLIv14EkNdPvmbCFyHibh0G8tia7Eibw/0?wx_fmt=png", // 此處是上傳logo的圖片地址
"pay_info": {
"swipe_card": {
"use_mid_list": [
"xxx" // 商戶號
],
"create_mid": "xxx", // 商戶號
"is_swipe_card": true
}
},
"brand_name": "測試代金券",
"code_type": "CODE_TYPE_NONE",
"title": "111",
"color": "Color090", // 主題顏色
"service_phone": "18888888888",
"description": "不可與其他優惠同享如需團購券發票,請在消費時向商戶提出",
"date_info": {
"type": "DATE_TYPE_FIX_TIME_RANGE",
"begin_timestamp": 1536768000, // 開始時間
"end_timestamp": 1536940800 // 結束時間
},
"can_share": false,
"center_title": "立即使用",
"center_app_brand_user_name": "gh_7195ea80d2e6@app",
"center_app_brand_pass": "pages/index/index",
"can_give_friend": false,
"sku": {
"quantity": 500000
},
"get_limit": 30,
"custom_url_name": "立即使用",
"custom_url": "http://www.qq.com",
"custom_url_sub_title": "6個漢字tips",
"promotion_url_name": "更多優惠",
"promotion_url": "http://www.qq.com"
},
"advanced_info": {
"use_condition": {
"accept_category": "鞋類",
"reject_category": "阿迪達斯",
"can_use_with_other_discount": true,
"least_cost": "51"
},
"abstract": {
"abstract": "微信餐廳推出多種新季菜品,期待您的光臨",
"icon_url_list": [
"http://mmbiz.qpic.cn/mmbiz/p98FjXy8LacgHxp3sJ3vn97bGLz0ib0Sfz1bjiaoOYA027iasqSG0sjpiby4vce3AtaPu6cIhBHkt6IjlkY9YnDsfw/0"
]
},
"text_image_list": [
{
"image_url": "http://mmbiz.qpic.cn/mmbiz/p98FjXy8LacgHxp3sJ3vn97bGLz0ib0Sfz1bjiaoOYA027iasqSG0sjpiby4vce3AtaPu6cIhBHkt6IjlkY9YnDsfw/0",
"text": "此菜品精選食材,以獨特的烹飪方法,最大程度地刺激食 客的味蕾"
},
{
"image_url": "http://mmbiz.qpic.cn/mmbiz/p98FjXy8LacgHxp3sJ3vn97bGLz0ib0Sfz1bjiaoOYA027iasqSG0sj piby4vce3AtaPu6cIhBHkt6IjlkY9YnDsfw/0",
"text": "此菜品迎合大眾口味,老少皆宜,營養均衡"
}
],
"time_limit": [
{
"type": "MONDAY",
"begin_hour": 0,
"end_hour": 10,
"begin_minute": 10,
"end_minute": 59
},
{
"type": "HOLIDAY"
}
],
"business_service": [
"BIZ_SERVICE_FREE_WIFI",
"BIZ_SERVICE_WITH_PET",
"BIZ_SERVICE_FREE_PARK",
"BIZ_SERVICE_DELIVER"
]
},
"reduce_cost": 5
}
}
}
通過以上接口和參數可以創建一個優惠券信息,json示例也可以使用官方的,這里有幾個問題需要重點說一下:
- use_mid_list 商戶號需要填寫本商戶的
- color 顏色可以根據文檔中選擇
- begin_timestamp、end_timestamp 這兩個時間非常重要,首先結束時間必須大於開始時間,並且需要大於一定的限度,測試時最好跨度大於一天;還需要注意的是時間格式必須是10位數值,例如:1536768000,其他格式會報錯。
- time_limit 下的值根據文檔中的要求填寫
- sku、get_limit 參數按要求填寫
- logo_url 使用微信官方的logo圖片地址
注意事項:date_info中用的是Unix時間戳,注意把begin_timestamp修改小於當前時間,end_timestamp修改成今天之后的時間,這樣在后面核銷卡劵測試才能成功
創建二維碼投放
頁面地址:http://mp.weixin.qq.com/debug
接口類型:卡劵接口
接口列表:創建二維碼ticket接口
access_token:第一步獲得的access_token
接口文檔地址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062
接口調用示例:
https://api.weixin.qq.com/card/qrcode/create?access_token=TOKEN
json參數:
{
"action_name":"QR_CARD",
"expire_seconds":1800,
"action_info":{
"card":{
"card_id":"pFS7Fjg8kV1IdDz01r4SQwMkuCKc",
"code":"198374613512",
"openid":"oFS7Fjl0WsZ9AMZqrI80nbIq8xrA",
"is_unique_code":false,
"outer_str":"12b"
}
}
}
顯示二維碼
在上一步的返回中點擊字段show_qrcode_url字段中的鏈接,即可顯示卡券領取二維碼。
打開微信掃一掃,然后領取卡劵,如果顯示卡劵未通過審核,那么需要下一步設置測試白名單,如果可以領取就忽略第六步。
設置測試白名單
文檔地址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062
核銷卡劵
文檔地址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025239
注意事項:僅支持審核通過且在有效期內的卡劵
HTML5網頁發券(JS-SDK)
上面通過二維碼發券的方式,我覺得官方文檔已經解釋清楚了,且接口也比較簡單,所以這里就不贅述,主要需要講的是這里的 HTML5網頁發券(JS-SDK)
,官方文檔鏈接如下:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062
看了上面的圖,小伙伴大概知道是什么意思了吧,簡單點說,就是用戶在咋們系統H5中點擊按鈕,可以彈出微信官方的領取優惠券界面,官方的頁面是微信提供的,我們無需開發,只需要關注如何調用官方的方法即可。
官方解釋如下:微信提供的addCard接口供商戶前端網頁調用,用於將一張或多張卡券添加到用戶卡包
接口地址如下(在以下頁面搜索addCard即可直達):
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
上面是添加卡券的接口,我們重點關注這幾個參數:
- cardId:卡券ID,如果是商戶平台,則是批次ID
- cardExt:卡券的擴展參數。需進行 JSON 序列化為字符串傳入
- cardExt>openid:指定領取者的 openid,只有該用戶能領取。 bind_openid 字段為 true 的卡券必須填寫,bind_openid 字段為 false 不可填寫。
- cardExt>code:用戶領取的 code,僅自定義 code 模式的卡券須填寫,非自定義 code 模式卡券不可填寫
- cardExt>nonce_str:隨機字符串,由開發者設置傳入,加強安全性(若不填寫可能被重放請求)。隨機字符串,不長於 32 位。推薦使用大小寫字母和數字,不同添加請求的 nonce_str 須動態生成,若重復將會導致領取失敗。
- cardExt>signature:簽名,商戶將接口列表中的參數按照指定方式進行簽名,簽名方式使用 SHA1,具體簽名方案參見:卡券簽名
- cardExt>timestamp:時間戳,東八區時間,UTC+8,單位為秒
- cardExt>outer_str:領取渠道參數,用於標識本次領取的渠道值。
- cardExt>fixed_begintimestamp:卡券在第三方系統的實際領取時間,為東八區時間戳(UTC+8,精確到秒)。當卡券的有效期類為 DATE_TYPE_FIX_TERM 時專用,標識卡券的實際生效時間,用於解決商戶系統內起始時間和領取微信卡券時間不同步的問題。
根據代金券批次ID得到組合的cardList
首先,獲取cardList接口需要先獲取access_token,再獲取api_ticket,最后組裝成想要的集合,下面是示例代碼。
根據代金券批次ID得到組合的cardList:
/**
* 根據代金券批次ID得到組合的cardList
*
* @param cardId 卡包ID
* @return cardList
* @author yclimb
* @date 2018/9/21
*/
public JSONArray getCardList(String cardId) {
if (StringUtils.isBlank(cardId)) {
return null;
}
try {
// 獲取[商戶名稱]公眾號的 access_token
String accessToken = this.getAccessToken(WXConstants.WX_MINI_PROGRAM_CODE);
String timestamp = String.valueOf(WXPayUtil.getCurrentTimestamp());
String nonce_str = WXPayUtil.generateNonceStr();
// 卡券的擴展參數。需進行 JSON 序列化為字符串傳入
JSONObject cardExt = new JSONObject();
//cardExt.put("code", "");
//cardExt.put("openid", "");
//cardExt.put("fixed_begintimestamp", "");
//cardExt.put("outer_str", "");
cardExt.put("timestamp", timestamp);
cardExt.put("nonce_str", nonce_str);
/**
* 1.將 api_ticket、timestamp、card_id、code、openid、nonce_str的value值進行字符串的字典序排序。
* 2.將所有參數字符串拼接成一個字符串進行sha1加密,得到signature。
* 3.signature中的timestamp,nonce字段和card_ext中的timestamp,nonce_str字段必須保持一致。
*/
Map<String, String> map = new HashMap<>(8);
//map.put("code", "");
//map.put("openid", "");
map.put("api_ticket", this.getWxCardApiTicket(accessToken));
map.put("timestamp", timestamp);
map.put("card_id", cardId);
map.put("nonce_str", nonce_str);
cardExt.put("signature", WXPayUtil.SHA1(WXPayUtil.dictionaryOrder(map, 2)));
// 卡券對象
JSONObject cardInfo = new JSONObject();
cardInfo.put("cardId", cardId);
cardInfo.put("cardExt", cardExt.toJSONString());
// 需要添加的卡券列表
JSONArray cardList = new JSONArray(1);
cardList.add(cardInfo);
return cardList;
} catch (Exception e) {
WXPayUtil.getLogger().error(e.getMessage(), e);
}
return null;
}
獲取微信全局accessToken:
/**
* 獲取微信全局accessToken
*
* @param code 標識
* @return accessToken
*/
public String getAccessToken(String code) {
// 取redis數據
String key = WXConstants.WECHAT_ACCESSTOKEN + code;
String accessToken = (String) redisTemplate.opsForValue().get(key);
if (accessToken != null) {
return accessToken;
}
// 通過接口取得access_token
JSONObject jsonObject = restTemplate.getForObject(MessageFormat.format(WXURL.BASE_ACCESS_TOKEN, WXPayConstants.APP_ID, WXPayConstants.SECRET), JSONObject.class);
String token = (String) jsonObject.get("access_token");
if (StringUtils.isNotBlank(token)) {
// 存儲redis
redisTemplate.opsForValue().set(key, token, 7000, TimeUnit.SECONDS);
return token;
} else {
log.error("獲取微信accessToken出錯,微信返回信息為:[{}]", jsonObject.toString());
}
return null;
}
獲取卡券 api_ticket 的 api:
/**
* 獲取卡券 api_ticket 的 api
* 請求路徑:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=wx_card
*
* @param access_token token
* @return api_ticket json obj
* @author yclimb
* @date 2018/9/21
*/
public String getWxCardApiTicket(String access_token) {
if (StringUtils.isBlank(access_token)) {
return null;
}
try {
// redis key
String redisKey = RedisKeyUtil.keyBuilder(RedisKeyEnum.IMALL_WXCARD_APITICKET, access_token);
// 從redis中獲取緩存
Object obj = redisTemplate.opsForValue().get(redisKey);
if (obj != null) {
return obj.toString();
}
// 獲取卡券 api_ticket
String api_ticket = restTemplate.getForObject(WXURL.BASE_API_TICKET, String.class, access_token);
WXPayUtil.getLogger().info("getWxCardApiTicket:api_ticket:{}", api_ticket);
if (StringUtils.isBlank(api_ticket)) {
return null;
}
JSONObject jsonObject = JSON.parseObject(api_ticket);
if (0 != jsonObject.getIntValue("errcode")) {
return null;
}
// 設置到redis中,下次取直接拿緩存即可,防止多次生成
String ticket = jsonObject.getString("ticket");
redisTemplate.opsForValue().set(redisKey, ticket, jsonObject.getIntValue("expires_in"), TimeUnit.SECONDS);
return ticket;
} catch (Exception e) {
WXPayUtil.getLogger().error(e.getMessage(), e);
}
return null;
}
以上代碼可以獲取cardList,將此參數替換到微信官方方法中即可喚起領券頁面;需要注意的是,公眾平台和商戶平台的券領取的方式不同,這里是以公眾平台為例子,如果小伙伴要用商戶平台這樣為用戶發券,是無法成功的喲。
查看卡券詳情
開發者可以調用該接口查詢某個card_id的創建信息、審核狀態以及庫存數量。
接口調用:
HTTP請求方式:POST
URL:https://api.weixin.qq.com/card/get?access_token=TOKEN
參數:card_id,卡券ID
接口文檔(進入鏈接后查詢 查看卡券詳情
可快速定位):
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272
此接口官方介紹已經很詳細,這里就不細講了,大家參考官方文檔即可。
結語
以上為微信公眾平台-卡券功能
相關的解釋和源碼,小伙伴們一定要注意看看官方文檔哦,具體的源碼可以看作者的github,里面對每個方法有詳細的注釋。
如果小伙伴有遇到解決不了的問題,可以關注作者微信公眾號,加入討論群中發出疑問,和小伙伴們一起解決哦~
預告:下一篇文章會講發放獎勵的另一種方式 公眾平台-社交立減金活動
,敬請期待!!!
如果想要提前一覽源碼的小伙伴,可以先看看我的 github,地址如下:
https://github.com/YClimb/wxpay-sdk/blob/master/README.md
關注作者微信公眾號,點擊下方討論群
,掃碼即可加入微信支付討論群
與小伙伴一起探討哦~
到此本文就結束了,關注公眾號查看更多推送!!!