SpringBoot Vue 微信 JSAPI 微信支付 签名
·
SpringBoot Vue 微信 JSAPI 微信支付 签名
payment:
wechat:
# 应用号
appid: 123456
# 商户号
mchid: 123456
# 商户证书序列号
mch-cert-no: 123456
# 商户私钥文件
private-key-path: payment/apiclient_key.pem
# 回调地址
callback: https://www.apy.com
# 服务号的 appsecret
secret: 123456
# 微信支付公钥ID
public-key-id: 123456
1 微信支付 后端 Token
/**
* 获取微信 AccessToken 接口
*/
private static final String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?appid={}&secret={}&grant_type=client_credential";
public String getAccessToken() {
String sn = IdUtils.nextIdStr();
log.info("获取微信AccessToken开始 SN:{}", sn);
try {
log.info("获取微信AccessToken请求 SN:{}, URL:{}", sn, StrUtil.format(ACCESS_TOKEN, proper.getAppid(), proper.getSecret()));
String response = HttpUtil.get(StrUtil.format(ACCESS_TOKEN, proper.getAppid(), proper.getSecret()));
log.info("获取微信AccessToken结束 SN:{}, REP:{}", sn, response);
if (!JSONUtil.isTypeJSON(response)) {
return "";
}
return JSONUtil.parseObj(response).getStr("access_token", "");
} catch (Exception e) {
log.error("获取微信AccessToken异常 SN:{}", sn, e);
}
return "";
}
2 微信支付 后端 Ticket
/**
* 获取微信 JsapiTicket 接口
*/
private static final String JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={}&type=jsapi";
public String getJsapiTicke(String token) {
String sn = IdUtils.nextIdStr();
log.info("获取微信JsapiTicket开始 SN:{}, Token:{}", sn, token);
try {
log.info("获取微信JsapiTicket请求 SN:{}, URL:{}", sn, StrUtil.format(JSAPI_TICKET, token));
String response = HttpUtil.get(StrUtil.format(JSAPI_TICKET, token));
log.info("获取微信JsapiTicket结束 SN:{}, REP:{}", sn, response);
if (!JSONUtil.isTypeJSON(response)) {
return "";
}
return JSONUtil.parseObj(response).getStr("ticket", "");
} catch (Exception e) {
log.error("获取微信JsapiTicket异常 SN:{}", sn, e);
}
return "";
}
3 微信支付 后端 签名
url就是当前H5页面的URL
public AjaxResult jsapiInitialize(String url) {
try {
// 1、获取AccessToken
String token = wechatService.getAccessToken();
// 2、获取Ticket
String ticket = wechatService.getJsapiTicke(token);
// 3、随机字符串
String string = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
// 4、时间戳
long timestamp = System.currentTimeMillis() / 1000;
// 5、将参数排序并拼接字符串
String str = StrUtil.format("jsapi_ticket={}&noncestr={}×tamp={}&url={}", ticket, string, timestamp, url);
Map<String, Object> info = new HashMap<>();
info.put("appid", payProper.getAppid());
info.put("timestamp", timestamp);
info.put("noncestr", string);
info.put("signature", PayUtil.sha1(str));
return AjaxResult.success(info);
} catch (Exception e) {
log.error("微信JSAPI初始化失败!", e);
return AjaxResult.error("微信JSAPI初始化失败!");
}
}
/**
* SHA1加密核心方法
*
* @param input 待加密字符串
* @return 40位十六进制SHA1加密结果
*/
public static String sha1(String input) {
// 空值处理
if (input == null || input.isEmpty()) {
return "";
}
try {
// 1. 获取SHA-1算法的MessageDigest实例
MessageDigest md = MessageDigest.getInstance("SHA-1");
// 2. 将字符串转换为字节数组(指定UTF-8编码,避免编码不一致)
byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
// 3. 更新摘要(传入待加密字节数组)
md.update(inputBytes);
// 4. 计算哈希摘要(生成20字节的SHA1结果)
byte[] digestBytes = md.digest();
// 5. 将字节数组转换为40位十六进制字符串
return bytesToHex(digestBytes);
} catch (Exception e) {
log.error("SHA1算法异常", e);
return "";
}
}
/**
* 字节数组转十六进制字符串(核心工具方法)
*
* @param bytes 待转换的字节数组
* @return 十六进制字符串
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder hexStr = new StringBuilder();
for (byte b : bytes) {
// 将字节转换为无符号整数(& 0xFF 避免负数)
int num = b & 0xFF;
// 转换为十六进制,不足两位补0
String hex = Integer.toHexString(num);
if (hex.length() < 2) {
hexStr.append("0");
}
hexStr.append(hex);
}
return hexStr.toString();
}
4 微信支付 前端 Vue wx.config
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appid, // 必填,服务号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳(后端生成)
nonceStr: data.noncestr, // 必填,生成签名的随机串(后端生成)
signature: data.signature, // 必填,签名(后端生成)
jsApiList: ["chooseWXPay"], // 必填,需要使用的JS接口列表
});
wx.ready(() => {
this.wxReady = true;
wx.checkJsApi({
jsApiList: ["chooseWXPay"],
success: function (res) {
console.log("初始化成功");
},
});
});
wx.error(function (res) {
console.log("初始化失败");
});
更多推荐
所有评论(0)