微信小程序怎么發(fā)紅包?首先你需要一個公眾號和小程序。在小程序中發(fā)送必須先關(guān)注公眾號。這樣你就可以使用公眾號的紅包接口給用戶發(fā)送紅包。
原理:
當(dāng)小程序和公眾號關(guān)聯(lián)時,每一個用戶在小程序和公眾號共有一個union_id,但open_id是不同的,所以在需要發(fā)紅包是首先獲得小程序的open_id和union_id,根據(jù)union_id的唯一性獲取公眾號的open_id,再調(diào)用公眾號的紅包接口(https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack)就可以實現(xiàn).
附上參數(shù)對象代碼:
//創(chuàng)建參數(shù)Map public static SortedMap<Object, Object> getWithdrawParam(String openid, int value) { SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); parameters.put("mch_appid", PropertyUtil.getInstance().getProperty("wx.appid"));//公眾號appid parameters.put("mchid", PropertyUtil.getInstance().getProperty("wx.mchid"));//綁定的商戶號 parameters.put("nonce_str", StringUtil.getRandomString(16));隨機(jī)字符串16位 parameters.put("partner_trade_no", RandomStringUtils.randomAlphanumeric(20));//商戶訂單號 parameters.put("openid", openid);//用戶open_id parameters.put("check_name", "NO_CHECK");//是否對用戶實名認(rèn)證,NO_CHECK表示否。 parameters.put("amount", value);//金額 parameters.put("desc", "紅包");//描述信息 parameters.put("spbill_create_ip", PropertyUtil.getInstance().getProperty("wx.requestUrl"));//Ip地址,這個IP必須在公眾號的白名單中,否則會失敗!!! return parameters; }//創(chuàng)建sign ,參數(shù)為UTF-8編碼和上面的參數(shù)Map
public static String createSign(String characterEncoding, SortedMap<String, Object> parameters) { StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + PropertyUtil.getInstance().getProperty("wx.key")); String sign = Md5Util.md5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; }將上面得到的sign放到Map中,param.put("sign", sign);
將Map轉(zhuǎn)換為XML
public static String getRequestXml(SortedMap<String, Object> param) { StringBuffer sb = new StringBuffer(); sb.append("<xml>"); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = "" + entry.getKey(); String v = "" + entry.getValue(); if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k)) { sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">"); } else { sb.append("<" + k + ">" + v + "</" + k + ">"); } } sb.append("</xml>"); return sb.toString(); }發(fā)送post請求到https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack,參數(shù)為上面的XML即可。
要實現(xiàn)上面的紅包功能,最好還有個定時任務(wù),可以把公眾號的用戶列表和用戶數(shù)據(jù)實時新增到數(shù)據(jù)庫中,以便根據(jù)唯一的union_id查找對應(yīng)的兩個open_id.
附上同步代碼
獲取access_token,最好和公眾號共享一個,因為access_token每天限定獲取2000次,每次過期時間為2小時,發(fā)生變動時的5分鐘內(nèi)新舊access_token都可以使用。
public String getAccessToken(){ String tokenUrl = PropertyUtil.getInstance().getProperty("wx.tokenURL") + "?appid=" + PropertyUtil.getInstance().getProperty("red.wx.appid") + "&secret=" + PropertyUtil.getInstance().getProperty("red.wx.appSecret") + "&grant_type=client_credential"; JSONObject tokenResult = JSONObject.parseObject(HttpUtils.get(tokenUrl)); if (tokenResult.getString("errmsg") != null) { log.info("獲取AccessToken失敗,請檢查失敗原因, {}", tokenResult.getString("errmsg")); return null; } log.info("tokenResult="+tokenResult.toString()); String access_token = tokenResult.getString("access_token"); stringRedisTemplate.opsForValue().set(redisKey, access_token, 100*60, TimeUnit.SECONDS); return access_token; }有了access_token就可以獲取用戶列表了,限定一次最多獲取10000個,可以根據(jù)next_openid設(shè)置起始位置。
地址:https://api.weixin.qq.com/cgi-bin/user/get,參數(shù)access_token和next_openid
String userListUrl = PropertyUtil.getInstance().getProperty("wx.userListURL") + "?access_token=" + access_token + "&next_openid=" + next_openid; JSONObject userListResult = JSONObject.parseObject(HttpUtils.get(userListUrl))得到open_id集合就可以繼續(xù)獲取用戶詳細(xì)信息,可以單獨(dú)也可以批量,批量最多100個一次。
批量獲取地址:https://api.weixin.qq.com/cgi-bin/user/info/batchget,參數(shù)user_list(100個用戶的openid)和access_token代碼就不加了,基本操作。
在分享個按指定大小,分隔集合,將集合按規(guī)定個數(shù)分為n個部分的方法,用來分隔10000個open_id為100的list,方便批量獲取public static List<List<String>> splitList(List<String> list, int len) { if (list == null || list.size() == 0 || len < 1) { return null; } List<List<String>> result = new ArrayList<List<String>>(); int size = list.size(); int count = (size + len - 1) / len; for (int i = 0; i < count; i++) { List<String> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1))); result.add(subList); } return result; }好了,具體就這么多了,詳細(xì)的可以根據(jù)開發(fā)文檔和本文參考對照完成。