微信小程序页面使用wx.addcard
onLoad: function (options) {
var that = this;
wx.request({
url: that.data.getdataUrl, //获取所需的数据的接口地址
data: { cardId:"pN_xS1rQhJzL4F_7-OzRcTUuVuTe"}, //卡券id
header: {
'content-type': 'application/json' //默认值
},
success: function (res) {
let cardExt = {
timestamp: res.data.timestamp, //时间戳,以秒为单位
nonce_str: res.data.nonceStr, //随机字符串
signature: res.data.signature, //签名
api_ticket: res.data.ticket, //apiticket
}
console.log(JSON.stringify(cardExt));
wx.addCard({
cardList: [{
cardId: res.data.cardId,
cardExt: JSON.stringify(cardExt),
}],
success(res) {
console.log(res.cardList) // 卡券添加结果
}
})
}
});
}
在小程序里用wx.addcard不需要wx.config
服务端
@Autowired
private RedisDao redisDao;
/**
* 获取token
* @param region
* @param appid
* @param AppSecret
* @return
*/
@Override
public String getToken(String appid, String AppSecret) {
try {
String httpsURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+AppSecret;
byte[] bytes = HttpsUtil.doGet(httpsURL);
String Str = new String(bytes);
JSONObject jsonObject = JSONObject.fromObject(Str);
return jsonObject.getString("access_token");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 获取apiticket
* @param token
* @return
*/
@Override
public String getApiTicket(String token) {
try {
String httpsURL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=wx_card";
byte[] bytes = HttpsUtil.doGet(httpsURL);
String Str = new String(bytes);
JSONObject jsonObject = JSONObject.fromObject(Str);
return jsonObject.getString("ticket");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 领取卡券
*/
@Override
public Map<String, Object> receiveCard(String cardId) {
//从redis取出token
String token = redisDao.get(BreakGoldEggConst.TOKEN_KEY);
//若redis中没有token,则访问微信接口获取token
if(StringUtils.isBlank(token)) {
token = this.getToken(BreakGoldEggConst.WX_APPID, BreakGoldEggConst.WX_APPSECRET);
redisDao.addString(BreakGoldEggConst.TOKEN_KEY, token, BreakGoldEggConst.TOKEN_TIMEOUT);
}
//从redis取出apiticket
String ticket = redisDao.get(BreakGoldEggConst.TICKET_KEY);
//若redis中没有apiticket,则访问微信接口获取apiticket
if(StringUtils.isBlank(ticket)) {
ticket = this.getApiTicket(token);
redisDao.addString(BreakGoldEggConst.TICKET_KEY, ticket, BreakGoldEggConst.TICKET_TIMEOUT);
}
//添加需要进行签名的参数
ArrayList<String> m_param_to_sign = new ArrayList<String>();
m_param_to_sign.add(ticket);
String nonceStr = UuidUtil.get32UUID();
m_param_to_sign.add(nonceStr);
String timestamp = String.valueOf(System.currentTimeMillis()/1000);
m_param_to_sign.add(timestamp);
m_param_to_sign.add(cardId);
//获取签名
String signature = GetSignature(m_param_to_sign);
Map<String,Object> resultMap = new HashMap<String, Object>();
resultMap.put("ticket", ticket);
resultMap.put("nonceStr", nonceStr);
resultMap.put("timestamp", timestamp);
resultMap.put("signature", signature);
resultMap.put("cardId", cardId);
return resultMap;
}
/**
* 获取签名
* @param m_param_to_sign
* @return
*/
public String GetSignature(ArrayList<String> m_param_to_sign)
{
Collections.sort(m_param_to_sign);
StringBuilder string_to_sign = new StringBuilder();
for (String str : m_param_to_sign)
{
string_to_sign.append(str);
}
System.out.println("string_to_sign:" + string_to_sign);
try
{
MessageDigest hasher = MessageDigest.getInstance("SHA-1");
byte[] digest = hasher.digest(string_to_sign.toString().getBytes());
return ByteToHexString(digest);
} catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
return "";
}
}
public String ByteToHexString(byte[] data)
{
StringBuilder str = new StringBuilder();
for (byte b : data)
{
String hv = Integer.toHexString(b & 0xFF);
if( hv.length() < 2 )
str.append("0");
str.append(hv);
}
return str.toString();
}
这里只提供大概的逻辑进行参考,工具类不做提供。
1、需要注意的是,token和apiticket的有效期只有两小时,所以这里我是把它们存在redis,设置过期时间。
2、需要用到的是apiticket!!!!!!!不是jsapiticket!!!!!!
apiticket获取的接口是https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=wx_card
3、制作签名的方法代码是从微信公众平台下载的demo复制的。
4、制作签名的参数中的时间戳,是以秒为单位的!!!!!! 千万要注意!!!!!!!