import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethod;
import com.ijpay.core.kit.AesUtil;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.core.utils.DateTimeZoneUtil;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxApiType;
import com.ijpay.wxpay.enums.WxDomain;
import com.ijpay.wxpay.model.v3.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.*;
/**
* 微信支付V3接口
*
*/
@Slf4j
@Controller
@RequestMapping("wechat/operation/pay")
public class WechatPayV3Controller {
@Resource
WechatPayV3Bean wechatPayV3Bean;
String serialNo;
String platSerialNo;
/**
* 获取证书序列号
*
* @return
*/
private String getSerialNumber() {
if (StrUtil.isEmpty(serialNo)) {
// 获取证书序列号
X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(wechatPayV3Bean.getCertPath()));
// X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream("D:\\Documents\\wechat\\apiclient_cert.pem"));
serialNo = certificate.getSerialNumber().toString(16).toUpperCase();
}
System.out.println("serialNo:" + serialNo);
return serialNo;
}
/**
* 获取平台证书序列号
*
* @return
*/
private String getPlatSerialNumber() {
if (StrUtil.isEmpty(platSerialNo)) {
// 获取平台证书序列号
X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(wechatPayV3Bean.getPlatformCertPath()));
platSerialNo = certificate.getSerialNumber().toString(16).toUpperCase();
}
System.out.println("platSerialNo:" + platSerialNo);
return platSerialNo;
}
/**
* 保存平台证书
*
* @param associatedData
* @param nonce
* @param cipherText
* @param certPath
* @return
*/
private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {
try {
AesUtil aesUtil = new AesUtil(wechatPayV3Bean.getApiKey3().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);
// 获取平台证书序列号
X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));
return certificate.getSerialNumber().toString(16).toUpperCase();
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
/**
* 刷新平台证书
*
* @return
*/
@RequestMapping("/get")
@ResponseBody
public String v3Get() {
// 获取平台证书列表
try {
IJPayHttpResponse response = WxPayApi.v3(
RequestMethod.GET,
WxDomain.CHINA.toString(),
WxApiType.GET_CERTIFICATES.toString(),
wechatPayV3Bean.getMchId(),
getSerialNumber(),
null,
wechatPayV3Bean.getKeyPath(),
""
);
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);
int isOk = 200;
if (status == isOk) {
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, wechatPayV3Bean.getPlatformCertPath());
log.info("平台证书序列号: {} serialNo: {}", platSerialNo, serialNo);
}
// 根据证书序列号查询对应的证书来验证签名结果
boolean verifySignature = WxPayKit.verifySignature(response, wechatPayV3Bean.getPlatformCertPath());
System.out.println("verifySignature:" + verifySignature);
return body;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 统一下单
* @param openid
* @param orderInfoId
* @return
*/
@GetMapping("/jsApiPay")
@ResponseBody
@ApiOperation(value = "统一下单")
@ApiImplicitParams({
@ApiImplicitParam(name = "openid", value = "微信用户openid", dataType = "string", required = true),
@ApiImplicitParam(name = "orderInfoId", value = "订单id", dataType = "int", required = true),
@ApiImplicitParam(name = "payType", value = "支付类型:1-零钱;2-微信", dataType = "Long", required = false)
})
@Transactional
public AjaxResult jsApiPay(@RequestParam("openid") String openid,
@RequestParam("orderInfoId") Long orderInfoId,
@RequestParam(value = "payType", required = false) Long payType) {
if (StringUtils.isEmpty(openid)) {
return AjaxResult.error("微信用户openid不能为空");
}
if (orderInfoId==null) {
return AjaxResult.error("订单编号不能为空");
}
try {
//交易结束时间�
- 1
- 2
- 3
- 4
- 5
- 6
前往页