微信公众号开发-微信卡券-小程序端打通-小程序内领取卡券-获取签名

[微信官方文档](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/card/wx.addCard.html)

小程序端添加卡券时需要提供签名进行校验,需要提供signature参数,建议从后端获取该参数

生成签名需要四个参数:nonceStr-随机字符串,timestamp以秒为单位的时间戳(记住一定是以秒为单位,否则会签名失败),ticket(生成方法见下面),cardId(微信端提供)

1.生成ticket

private String getTicketFromWx() {
        String accessToken = getAccessToken();
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<ApiTicket> forEntity = restTemplate.getForEntity("https://api.weixin.qq" +
                        ".com/cgi-bin/ticket/getticket?type=wx_card&access_token=" + accessToken,
                ApiTicket.class);
        logger.info("getTicketFromWx_ApiTicket:{}", JSON.toJSONString(forEntity));
        ApiTicket apiTicket = forEntity.getBody();
        if (apiTicket == null || StringUtils.isBlank(apiTicket.getTicket())) {
            logger.info("getTicketFromWx_error:获取ApiTicket出错");
            return null;
        }
        String key = "wxTicketForWxCard_";
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(apiTicket));
        return apiTicket.getTicket();
    }

url的type一定是wx_card,否则生成的ticket无效

2.生成随机字符串nonceStr

static String createNonceStr() {
        return UUID.randomUUID().toString();
    }

3.生成时间戳timestamp

static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

核心代码

public Map<String, String> getCardSign(String cardId) {
        //获取ticket
        String apiTicket = getTicketForCard();
        if (StringUtils.isBlank(apiTicket)) {
            logger.info("getCardSign_error:获取到的ticket为空");
            return new HashMap<>(1);
        }
        //生成领取卡券需要的签名,并返回相关的参数
        Map<String, String> ret = new HashMap<>(6);
        String nonceStr = createNonceStr();
        String timestamp = createTimestamp();
        String signature;
        String[] param = new String[4];
        param[0] = nonceStr;
        param[1] = timestamp;
        param[2] = apiTicket;
        param[3] = cardId;
        //对参数的value值进行字符串的字典序排序
        Arrays.sort(param);
        StringBuilder sb = new StringBuilder();
        Arrays.stream(param).forEach(sb::append);
        //对上面拼接的字符串进行sha1加密,得到signature
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(sb.toString().getBytes(StandardCharsets.UTF_8));
            signature = byteToHex(crypt.digest());
        } catch (NoSuchAlgorithmException e) {
            logger.info("getCardSign_error:", e);
            return ret;
        }
        //返回领取卡券需要的参数,其中nonceStr和timestamp必须和签名中的保持一致
        ret.put("card_id", cardId);
        ret.put("apiTicket", apiTicket);
        ret.put("nonceStr", nonceStr);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        return ret;
    }

字节转换方法

static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

[源码地址](https://github.com/shengshengshengsheng/wx_card_demo.git)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值