微信官方提供的生成二維碼接口得到的是當前公眾號的二維碼官方文檔(一定要先看)
目前有2種類型的二維碼:
臨時二維碼,是有過期時間的,最長可以設置為在二維碼生成后的30天(即2592000秒)后過期,但能夠生成較多數量,主要用於帳號綁定等不要求二維碼永久保存的業務場景
永久二維碼,是無過期時間的,但數量較少(目前為最多10萬個),主要用於適用於帳號綁定、用戶來源統計等場景
獲取帶參數的二維碼有兩種方法
先獲取二維碼ticket,然后憑借ticket通過接口換取二維碼圖片,但是得到ticket之前首先得獲取微信全局唯一接口調用憑據
根據微信返回二維碼中url參數自行生成二維碼
一、獲取微信全局接口調用憑證
調用接口時,請登錄“微信公開發-基本配置”提前將服務器IP地址添加到IP白名單中,否則將無法調用成功!!!
二、獲取二維碼的Ticket
/** * 創建臨時帶參數二維碼 * * @param accessToken * @param sceneId 場景Id * @return * @expireSeconds 該二維碼有效時間,以秒為單位。 最大不超過2592000(即30天),此字段如果不填,則默認有效期為30秒。 */ @Override public String createTempTicket(String accessToken, int sceneId, int expireSeconds) { TreeMap<String, String> params = new TreeMap<>(); params.put("access_token", accessToken); // output data JsonObject data = new JsonObject(); data.addProperty("action_name", QRCodeConstant.QR_SCENE); data.addProperty("expire_seconds", expireSeconds); JsonObject scene = new JsonObject(); scene.addProperty("scene_id", sceneId); JsonObject actionInfo = new JsonObject(); actionInfo.add("scene", scene); data.add("action_info", actionInfo); String result = HttpUtil.doPost(WechatQRCodeConfig.getCreateTicketUrl(), params, data.toString()); WechatQRCode qrcode = JsonUtil.fromJson(result, WechatQRCode.class); return qrcode == null ? null : qrcode.getTicket(); } /** * 創建臨時帶參數二維碼(字符串) * * @param accessToken * @param sceneStr 場景Id * @return * @expireSeconds 該二維碼有效時間,以秒為單位。 最大不超過2592000(即30天),此字段如果不填,則默認有效期為30秒。 */ @Override public String createTempTicket(String accessToken, String sceneStr, int expireSeconds) { TreeMap<String, String> params = new TreeMap<>(); params.put("access_token", accessToken); // output data JsonObject data = new JsonObject(); data.addProperty("action_name", QRCodeConstant.QR_STR_SCENE); data.addProperty("expire_seconds", expireSeconds); JsonObject scene = new JsonObject(); scene.addProperty("scene_str", sceneStr); JsonObject actionInfo = new JsonObject(); actionInfo.add("scene", scene); data.add("action_info", actionInfo); String result = HttpUtil.doPost(WechatQRCodeConfig.getCreateTicketUrl(), params, data.toString()); WechatQRCode qrcode = JsonUtil.fromJson(result, WechatQRCode.class); return qrcode == null ? null : qrcode.getTicket(); } /** * 創建永久二維碼(數字) * * @param accessToken * @param sceneId 場景Id * @return */ @Override public String createForeverTicket(String accessToken, int sceneId) { TreeMap<String, String> params = new TreeMap<>(); params.put("access_token", accessToken); // output data JsonObject data = new JsonObject(); data.addProperty("action_name", QRCodeConstant.QR_LIMIT_SCENE); JsonObject scene = new JsonObject(); scene.addProperty("scene_id", sceneId); JsonObject actionInfo = new JsonObject(); actionInfo.add("scene", scene); data.add("action_info", actionInfo); String result = HttpUtil.doPost(WechatQRCodeConfig.getCreateTicketUrl(), params, data.toString()); WechatQRCode qrcode = JsonUtil.fromJson(result, WechatQRCode.class); return qrcode == null ? null : qrcode.getTicket(); } /** * 創建永久二維碼(字符串) * * @param accessToken * @param sceneStr 場景str * @return */ @Override public String createForeverTicket(String accessToken, String sceneStr) { TreeMap<String, String> params = new TreeMap<>(); params.put("access_token", accessToken); // output data JsonObject data = new JsonObject(); data.addProperty("action_name", "QR_LIMIT_STR_SCENE"); JsonObject actionInfo = new JsonObject(); JsonObject scene = new JsonObject(); scene.addProperty("scene_str", sceneStr); actionInfo.add("scene", scene); data.add("action_info", actionInfo); String result = HttpUtil.doPost(WechatQRCodeConfig.getCreateTicketUrl(), params, data.toString()); WechatQRCode qrcode = JsonUtil.fromJson(result, WechatQRCode.class); return qrcode == null ? null : qrcode.getTicket(); }
三、二維碼長鏈接轉成短鏈接
微信返回正確的二維碼的結果,參數有個url,即二維碼圖片解析后的地址,也可以根據此URL生成需要的二維碼圖片,而不需要通過ticket去換取圖片了
/** * 長鏈接轉短鏈接 * * @param accessToken * @param longUrl 長鏈接 * @return */ private String toShortQRCodeurl(String accessToken, String longUrl) { TreeMap<String, String> params = new TreeMap<>(); params.put("access_token", accessToken); JsonObject data = new JsonObject(); data.addProperty("action", QRCodeConstant.LONG_TO_SHORT); data.addProperty("long_url", longUrl); String result = HttpUtil.doPost(WechatQRCodeConfig.getShortQrcodeUrl(), params, data.toString()); WechatQRCodeShortUrl wechatQRCodeShortUrl = JsonUtil.fromJson(result, WechatQRCodeShortUrl.class); return wechatQRCodeShortUrl == null ? null : wechatQRCodeShortUrl.getShortUrl(); }
四、通過ticket憑證直接獲取二維碼
/** * 獲取二維碼ticket后,通過ticket換取二維碼圖片展示 * * @param accessToken * @param ticket * @param isShortUrl 是否需要展示 * @return */ @Override public String showQrCode(String accessToken, String ticket, boolean isShortUrl) { String url = String.format(WechatQRCodeConfig.getShowQrcodeUrl(), EncodeUtils.urlEncode(ticket)); if (isShortUrl) { return toShortQRCodeurl(accessToken, url); } return url; }
五、掃描帶參數二維碼事件推送
推送的XML信息通過之前開發者中心處設置的服務器地址獲得,故得先接入
已關注推送XML示例
<xml><ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[qrscene_123123]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
EventKey 事件KEY值,qrscene_為前綴,后面為二維碼的參數值
未關注推送XML示例
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[SCAN]]></Event> <EventKey><![CDATA[SCENE_VALUE]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
EventKey 事件KEY值,是一個32位無符號整數,即創建二維碼時的二維碼scene_id