微信小程序如何發紅包

文章開頭先提一點,如果小程序可以開通企業支付接口,那推薦直接使用企業支付接口來實現紅包的功能,小程序鏈接公衆號通過公衆號的紅包接口來實現是非常坑爹的一件事。

微信企業支付接口:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1,使用這個接口需要開通支付權限

 

本文說下如果聯通小程序和公衆號來實現發紅包。

首先你需要一個公衆號和小程序。在小程序中發送必須先關注公衆號。這樣你就可以使用公衆號的紅包接口給用戶發送紅包。

原理:

當小程序和公衆號關聯時,每一個用戶在小程序和公衆號共有一個union_id,但open_id是不同的,所以在需要發紅包是首先獲得小程序的open_id和union_id,根據union_id的唯一性獲取公衆號的open_id,再調用公衆號的紅包接口(https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack)就可以實現.

附上參數對象代碼:

//創建參數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));隨機字符串16位
    parameters.put("partner_trade_no", RandomStringUtils.randomAlphanumeric(20));//商戶訂單號
    parameters.put("openid", openid);//用戶open_id
    parameters.put("check_name", "NO_CHECK");//是否對用戶實名認證,NO_CHECK表示否。
    parameters.put("amount", value);//金額
    parameters.put("desc", "紅包");//描述信息
    parameters.put("spbill_create_ip", PropertyUtil.getInstance().getProperty("wx.requestUrl"));//Ip地址,這個IP必須在公衆號的白名單中,否則會失敗!!!
    return parameters;
}

//創建sign ,參數爲UTF-8編碼和上面的參數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轉換爲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();
}

發送post請求到https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack,參數爲上面的XML即可。

要實現上面的紅包功能,最好還有個定時任務,可以把公衆號的用戶列表和用戶數據實時新增到數據庫中,以便根據唯一的union_id查找對應的兩個open_id.

附上同步代碼

 獲取access_token,最好和公衆號共享一個,因爲access_token每天限定獲取2000次,每次過期時間爲2小時,發生變動時的5分鐘內新舊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個,可以根據next_openid設置起始位置。

地址:https://api.weixin.qq.com/cgi-bin/user/get,參數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集合就可以繼續獲取用戶詳細信息,可以單獨也可以批量,批量最多100個一次。

批量獲取地址:https://api.weixin.qq.com/cgi-bin/user/info/batchget,參數user_list(100個用戶的openid)和access_token

代碼就不加了,基本操作。

在分享個按指定大小,分隔集合,將集合按規定個數分爲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;
}

好了,具體就這麼多了,詳細的可以根據開發文檔和本文參考對照完成。 


 

 


 

 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章