parent
32fe7eacfc
commit
a92790886a
@ -0,0 +1,55 @@
|
||||
package com.luoo.user.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "wx.pay")
|
||||
public class WxPayConfig {
|
||||
/**
|
||||
* appId
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 商户号
|
||||
*/
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* 商户证书序列号
|
||||
*/
|
||||
private String mchSerialNo;
|
||||
|
||||
/**
|
||||
* apiv3密钥
|
||||
*/
|
||||
private String apiV3Key;
|
||||
|
||||
/**
|
||||
* 支付回调地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
|
||||
/**
|
||||
* 微信支付请求url
|
||||
*/
|
||||
// private String wxJsapiUrl;
|
||||
|
||||
/**
|
||||
* 私钥路径
|
||||
*/
|
||||
private String privateKeyPath;
|
||||
|
||||
/**
|
||||
* 商户证书路径
|
||||
*/
|
||||
private String privateCertPath;
|
||||
|
||||
/**
|
||||
* 微信平台证书路径
|
||||
*/
|
||||
private String platformCertPath;
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.luoo.user.service;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ijpay.core.IJPayHttpResponse;
|
||||
import com.ijpay.core.enums.RequestMethodEnum;
|
||||
import com.ijpay.core.kit.AesUtil;
|
||||
import com.ijpay.core.kit.PayKit;
|
||||
import com.ijpay.core.kit.WxPayKit;
|
||||
import com.ijpay.wxpay.WxPayApi;
|
||||
import com.ijpay.wxpay.enums.WxDomainEnum;
|
||||
import com.ijpay.wxpay.enums.v3.OtherApiEnum;
|
||||
import com.luoo.user.config.WxPayConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* @program: luoo_parent
|
||||
* @description:
|
||||
* @author: yawei.huang
|
||||
* @create: 2024-11-12 12:00
|
||||
**/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class WxPayService {
|
||||
|
||||
@Resource
|
||||
private WxPayConfig wxPayConfig;
|
||||
|
||||
public void v3Get() {
|
||||
// 获取平台证书列表
|
||||
try {
|
||||
IJPayHttpResponse response = WxPayApi.v3(
|
||||
RequestMethodEnum.GET,
|
||||
WxDomainEnum.CHINA.toString(),
|
||||
OtherApiEnum.GET_CERTIFICATES.toString(),
|
||||
wxPayConfig.getMchId(),
|
||||
wxPayConfig.getMchSerialNo(),
|
||||
null,
|
||||
wxPayConfig.getPrivateKeyPath(),
|
||||
""
|
||||
);
|
||||
|
||||
String timestamp = response.getHeader("Wechatpay-Timestamp");
|
||||
String nonceStr = response.getHeader("Wechatpay-Nonce");
|
||||
String serialNumber = response.getHeader("Wechatpay-Serial");
|
||||
String signature = response.getHeader("Wechatpay-Signature");
|
||||
|
||||
String body = response.getBody();
|
||||
int status = response.getStatus();
|
||||
|
||||
log.info("serialNumber: {}", serialNumber);
|
||||
log.info("status: {}", status);
|
||||
log.info("body: {}", body);
|
||||
if (status == 200) {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(body);
|
||||
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||
// 默认认为只有一个平台证书
|
||||
JSONObject encryptObject = dataArray.getJSONObject(0);
|
||||
JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
|
||||
String associatedData = encryptCertificate.getStr("associated_data");
|
||||
String cipherText = encryptCertificate.getStr("ciphertext");
|
||||
String nonce = encryptCertificate.getStr("nonce");
|
||||
String serialNo = encryptObject.getStr("serial_no");
|
||||
final String platSerialNo = savePlatformCert(associatedData, nonce, cipherText, wxPayConfig.getPlatformCertPath());
|
||||
log.info("平台证书序列号: {} serialNo: {}", platSerialNo, serialNo);
|
||||
}
|
||||
// 根据证书序列号查询对应的证书来验证签名结果
|
||||
boolean verifySignature = WxPayKit.verifySignature(response, wxPayConfig.getPlatformCertPath());
|
||||
System.out.println("verifySignature:" + verifySignature);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {
|
||||
try {
|
||||
AesUtil aesUtil = new AesUtil(wxPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
|
||||
// 平台证书密文解密
|
||||
// encrypt_certificate 中的 associated_data nonce ciphertext
|
||||
String publicKey = aesUtil.decryptToString(
|
||||
associatedData.getBytes(StandardCharsets.UTF_8),
|
||||
nonce.getBytes(StandardCharsets.UTF_8),
|
||||
cipherText
|
||||
);
|
||||
// 保存证书
|
||||
FileWriter writer = new FileWriter(certPath);
|
||||
writer.write(publicKey);
|
||||
writer.close();
|
||||
// 获取平台证书序列号
|
||||
X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));
|
||||
return certificate.getSerialNumber().toString(16).toUpperCase();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue