Wechat cash red packet jump pit version

Keywords: ascii xml JSON Windows

The official gives the early steps of opening the cash red envelope

1. It is worth noting that the calling IP address (public IP) needs to be configured in wechat payment merchant platform product center cash red packet product settings

2. Integrated business development thinking
Official account official account No. 1) official account is not concerned about the official account.
2) the user pays attention to the official account number - the cash bonus on the official account.

In this case, the small program has its own openid, and the official account has its own openid. Don't confuse. The only connection is a common unionid. (for how to have unionid, see the figure below. The same account can be bound according to unionid)

Small programs are associated with official account numbers, so calling the corresponding authorized login interface has corresponding UnionId. The official account also needs to be added to this page.

3, the official account provides API to detect whether the current user is concerned about the current official account number.

Wechat interface, basic need this access_token, as for openid, you can find it in your official account configuration.
There is a very important problem in the official account. Ip white list is needed.


Own code

 @ApiOperation(value = "Check whether official account is concerned.", notes = "Check whether official account is concerned.")
    @GetMapping(value = "/checkAttention")
    public Result<Object> checkAttention(HttpServletRequest request){
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=*******&secret=*********";
        String token = HttpUtil.doGetJson(url).getString("access_token");
        JSONObject json = new JSONObject();
        String uid = getUid(request);
        SysUser sysUser =userService.getById(uid);
        String uus = CHECK+token+"&openid="+sysUser.getMpOpenId()+"&lang=zh_CN";
        String infoStr = HttpUtil.getResponseByGet(uus);
        JSONObject info= JSONObject.parseObject(infoStr);
        MPBaseInfo baseInfo = (MPBaseInfo)JSONObject.toJavaObject(info, MPBaseInfo.class);
        if(StringUtils.isBlank(baseInfo.getSubscribe()) || "0".equals(baseInfo.getSubscribe())){
            return  Result.error("Users have not yet paid attention to official account number.");
        return  Result.ok();


    public static JSONObject doGetJson(String url) {
        JSONObject jsonObject = null;
        String result = "";
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                result = EntityUtils.toString(httpEntity, "UTF-8");
                jsonObject = JSONObject.parseObject(result);
                log.info("Return result:"+jsonObject);
        } catch (IOException e) {
            log.error("doGet error by:{}", url, e);
        } finally {
        return jsonObject;
    public static  String getResponseByGet(String url){
        String result="";
        try {
            URL url1 = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) url1.openConnection();
            // Tencent maps using GET
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            // Get address resolution results
            while ((line = in.readLine()) != null) {
                result += line + "\n";
        } catch (Exception e) {
        return  result;

The above is to get the user token and check whether the official account is concerned. The next is the play.

4. Api certificate preparation and placement


Code up

    public void sendRedPackets(String mpOpendId,String  money) {
        RequestHandler rh = new RequestHandler();
        rh.setParameter("nonce_str", getRandomString(30));//Random string, no longer than 32 bits
        rh.setParameter("mch_billno", getRandomString(28));//Merchant order number (each order number must be unique) composition: mch_id+yyyymmdd+10 digits that cannot be repeated in a day. The interface supports reentry according to the merchant's order number, and can be called again in case of timeout.
        rh.setParameter("mch_id", APP_ID);//Account id of wechat merchant platform
        rh.setParameter("wxappid", MP_APP_ID);//appid of the official account
        rh.setParameter("send_name", "Altman beat the little monster");//Merchant name
        rh.setParameter("re_openid", mpOpendId);//id of user official account
        rh.setParameter("total_amount", money);//Unit of payment amount
        rh.setParameter("total_num", "1");//Total number of red packets issued
        rh.setParameter("wishing", "Welcome to visit next time");//Red envelope blessing
        rh.setParameter("client_ip", ip);//Ip white list
        rh.setParameter("act_name", "Activity red envelope");//Activity name
        rh.setParameter("remark", "Activity red envelope");//remarks
        log.info("Red packet request parameters,{}",rh);
 public static String getRandomString(int length) {
        //Generating random numbers
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        //Cycle length times
        for (int i = 0; i < length; i++) {
            //Generating 0-2 random numbers is related to A-Z, A-Z and 0-9
            int number = random.nextInt(3);
            long result = 0;
            switch (number) {
                //If number produces the number 0;
                case 0:
                    //Generate A-Z ASCII code
                    result = Math.round(Math.random() * 25 + 65);
                    //Convert ASCII code to characters
                    sb.append(String.valueOf((char) result));
                case 1:
                    //Generating a-z ASCII code
                    result = Math.round(Math.random() * 25 + 97);
                    sb.append(String.valueOf((char) result));
                case 2:
                    //Generate numbers 0-9
                            (new Random().nextInt(10)));
        return sb.toString();
   public void sendRedPacket(RequestHandler rh) {
        // TODO Auto-generated method stub
        Map<String, String> result = new HashMap<String, String>();
        String path = "/usr/apiclient_cert.p12";//The API certificate path mentioned above
        try {
            String sign = rh.createMd5Sign("key", key);//Key, secret key and value are encrypted and signed according to wechat encryption rules
            rh.setParameter("sign", sign);//Set signature to request parameters
            String data = rh.parseXML();//XML format of data needed for calling cash red packet interface
            String xmlResult = doPostByWXSSL("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", data, path, APP_ID);//xml and app returned by cash red packet interface_ ID is the same as above
            log.info("Call wechat interface to return data:" + xmlResult);
        } catch (Exception e) {
public String doPostByWXSSL(String url, String data, String certPath, String mchId) {
        StringBuffer message = new StringBuffer();
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(certPath));//Certificate used
            keyStore.load(instream, mchId.toCharArray());
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, mchId.toCharArray())
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    new String[]{"TLSv1"},
            CloseableHttpClient httpclient = HttpClients.custom()
            HttpPost httpost = new HttpPost(url);

            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
//            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            log.info("executing request" + httpost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                log.info("--------------------Start sending wechat receiving parameters--------------------");
                log.info("Request response status:" + response.getStatusLine());
                if (entity != null) {
                    log.info("Total response byte length: " + entity.getContentLength());
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                    String text;
                    while ((text = bufferedReader.readLine()) != null) {
                log.info("--------------------End of sending wechat receiving parameters--------------------");
            } catch (IOException e) {
            } finally {
        } catch (Exception e1) {
            log.error("Error in wechat red packet request",e1.fillInStackTrace());
        return message.toString();


Think it's over? No, no, the key is to get openid

Official term: the web authorization process is divided into four steps:

1. Guide the user to enter the authorization page, agree to authorize, and obtain the code

2. Exchange access for web page authorization through code_ Token (and access in basic support_ Different token)

3. Access can refresh the web page if necessary_ Token to avoid expiration

4. Authorization of access through web pages_ Token and openid get user basic information (UnionID mechanism supported)

code access requires the official account to first configure the web page authorization page and the second step to issue the certificate. Call back the domain name on the server

In the end, we have the only UNIONID and openid of the official account of the user. The cash bonus is also completed. The code is a little ugly. Don't spray

Posted by nevynev on Tue, 30 Jun 2020 00:04:16 -0700