前端代码:
api.createRechargeOrder(this.data.selectedOptionId, this.data.bookId, this.data.chapterIndex).then(res => {
const payParams = res.data;
// 虚拟支付
wx.requestVirtualPayment({
signData: payParams.signData,
mode: 'short_series_goods',
paySig: payParams.paySig,
signature: payParams.signature,
success() {
// xxxxxxxxxxxxxxxxxxx
},
fail(e) {
// xxxxxxxxxxxxxxxxxxxxxxxxxx
},
})
})
后端Java代码(createRechargeOrder 调用的方法):
public WxVirtualPayResultDto createVirtualPayOrder(Long productId, BigDecimal goodsPrice, String orderNo, Long userId, String sessionKey) {
String signData = getSignData(productId, goodsPrice, orderNo, userId);
String paySig = getPaySig(signData);
String signature = getSignature(sessionKey, signData);
WxVirtualPayResultDto wxVirtualPayResultDto = new WxVirtualPayResultDto();
wxVirtualPayResultDto.setSignature(signature);
wxVirtualPayResultDto.setPaySig(paySig);
wxVirtualPayResultDto.setSignData(signData);
wxVirtualPayResultDto.setOrderNo(orderNo);
return wxVirtualPayResultDto;
}
private String getSignData(Long productId, BigDecimal goodsPrice, String orderNo, Long userId) {
int priceInCent = goodsPrice.multiply(new BigDecimal("100"))
.setScale(0, RoundingMode.HALF_UP)
.intValue();
String signData = "{\"offerId\":\"%s\",\"buyQuantity\":1,\"env\":%d,\"currencyType\":\"CNY\",\"productId\":\"%d\",\"goodsPrice\":%d,\"outTradeNo\":\"%s\",\"attach\":\"%s\"}";
return signData.formatted(offerId, env, productId, priceInCent, orderNo, userId);
}
private String getPaySig(String signData) {
try {
String dataToSign = "uri=requestVirtualPayment&signData=" + signData;
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(
env == 0 ? appKey.getBytes(StandardCharsets.UTF_8) : sandboxAppKey.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
);
mac.init(secretKeySpec);
byte[] hmacBytes = mac.doFinal(dataToSign.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hmacBytes);
} catch (Exception e) {
throw new RuntimeException("HMAC-SHA256 签名失败", e);
}
}
private String getSignature(String sessionKey, String signData) {
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(
sessionKey.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
);
mac.init(secretKeySpec);
byte[] hmacBytes = mac.doFinal(signData.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hmacBytes);
} catch (Exception e) {
throw new RuntimeException("HMAC-SHA256 签名失败", e);
}
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
前端报错:
errCode: -15005
errMsg: "requestVirtualPayment:fail SIGNATURE_INVALID"
errno: -15005
是用户态签名signature错误
但我不清楚我 signature 哪里有问题,请教大佬们帮我检查一下。

解决了吗?PHP也是报的这个
解决了嘛