官网API
微信支付-开发者文档
1. 创建支付
<!--微信支付-->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.11</version>
</dependency>
/**
* 获取5分钟后超时时间
* @return
*/
public static String getTimeExpire() {
// 当前时间
LocalDateTime now = LocalDateTime.now();
// 5分钟前的时间
LocalDateTime fifteenMinutesAgo = now.plusMinutes(5);
// 获取时区信息(以北京时间为例)
ZoneId zoneId = ZoneId.of("Asia/Shanghai"); // 东八区时区
// 将LocalDateTime转换为ZonedDateTime
ZonedDateTime zonedDateTime = fifteenMinutesAgo.atZone(zoneId);
// 创建一个符合RFC 3339的DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
// 格式化日期时间
String formattedDateTime = zonedDateTime.format(formatter);
return formattedDateTime;
}
/**
* Native支付下单,获取支付地址
* @return 微信支付二维码 base64图片
*/
public static String nativePay(String title, String orderId, Integer totalMoney){
// 使用自动更新平台证书的RSA配置
Config config =
new RSAAutoCertificateConfig.Builder()
.merchantId("1xxxxxxxx1") // 商户号,10位数字
.privateKeyFromPath("D:\\AH\\apiclient_key.pem") // API证书地址(此处的路径自己调试一下,能找到就行)
.merchantSerialNumber("2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3") // API证书序列号
.apiV3Key("_xxxxxxxxxxxxxxxx__") // API密匙
.build();
// 构建service
NativePayService service = new NativePayService.Builder().config(config).build();
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal(totalMoney); // 付款总金额, 传10为 0.1元, 传100元为 1元
request.setAmount(amount);
request.setAppid("wxxxxxxxxxxxxxxxxb"); // APPID
request.setMchid("1xxxxxxxx1"); // 商户号,10位数字
request.setTimeExpire(getTimeExpire()); // 超时时间
request.setDescription(title);// 商品的描述
request.setNotifyUrl("https://xxxx/account/pay/" + orderId);// 支付成功的回调地址(接口要为POST)
request.setOutTradeNo(orderId);// 本地订单号
// 调用下单方法,得到应答
try {
// 发送请求
PrepayResponse response = service.prepay(request);
// 使用微信扫描 code_url 对应的二维码,即可体验Native支付
BufferedImage bufferedImage = builderQrCodeImage(generateQRCode(response.getCodeUrl(), 330, 330));
// 将支付二维码返回
return imageToBase64(bufferedImage);
}catch (Exception e){
throw new SearchException(e.getMessage());
}
}
/**
* 生成二维码
* @param text
* @param width
* @param height
* @return
* @throws WriterException
*/
public static BufferedImage generateQRCode(String text, int width, int height) throws WriterException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, ErrorCorrectionLevel> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置错误纠正级别为H
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
return MatrixToImageWriter.toBufferedImage(bitMatrix);
}
/**
* 将BufferdImage转为base64图片
* @param image
* @return
* @throws IOException
*/
public static String imageToBase64(BufferedImage image) throws IOException {
// 将BufferedImage转换为字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos); // 或者使用 "png" 或 "bmp" 等其他图片格式
byte[] imageBytes = baos.toByteArray();
// 将字节数组转换为Base64编码的字符串
String encodedImage = Base64.getEncoder().encodeToString(imageBytes);
return "data:image/jpeg;base64," + encodedImage;
}
/**
* 二维码设置自定义的边框
* @param image
* @return
*/
public static BufferedImage builderQrCodeImage(BufferedImage image) {
try {
File file = new File("边框文件路径");
BufferedImage borderImage = ImageIO.read(new File(file.getPath()));
BufferedImage image1 = new BufferedImage(image.getWidth() + 100, image.getHeight() + 100, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image1.createGraphics();
//消除文字锯齿
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//消除图片锯齿
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//放入二维码
graphics.drawImage(image, 50, 50, image.getWidth(), image.getHeight(), null);
//放入边框
graphics.drawImage(borderImage, 0, 0, image.getWidth() + 100, image.getHeight() + 100, null);
return image1;
} catch (IOException e) {
return image;
}
}
2. 查询支付订单
public static AccountRechargePayResultDTO queryOrder(String rechargeOrderId){
// 使用自动更新平台证书的RSA配置
Config config =
new RSAAutoCertificateConfig.Builder()
.merchantId("1xxxxxxxx1") // 商户号,10位数字
.privateKeyFromPath("D:\\AH\\apiclient_key.pem") // API证书地址(此处的路径自己调试一下,能找到就行)
.merchantSerialNumber("2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3") // API证书序列号
.apiV3Key("_xxxxxxxxxxxxxxxx__") // API密匙
.build();
// 构建service
NativePayService service = new NativePayService.Builder().config(config).build();
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid("1xxxxxxxx1") // 商户号,10位数字
request.setOutTradeNo(rechargeOrderId);
AccountRechargePayResultDTO dto = new AccountRechargePayResultDTO();// 自定义对象
// 调用下单方法,得到应答
try {
// 发送请求
Transaction response = service.queryOrderByOutTradeNo(request);
String order = response.getTransactionId(); // 取出第三方订单号
Transaction.TradeStateEnum status = response.getTradeState(); // 支付状态
TransactionAmount amount = response.getAmount();
dto.setMoney(amount.getPayerTotal()); // 订单支付总金额
String time = response.getSuccessTime(); // 支付成功时间
dto.setAccountRechargeId(rechargeOrderId);
dto.setOrderSuccessTime(status.name().equals("SUCCESS") ? convertToFormattedString(time) : "");
dto.setOrderId(order);
dto.setOrderStatus(status.name().equals("SUCCESS") ? "1" : "0");
}catch (Exception e){
throw new SearchException(e.getMessage());
}
return dto;
}
/**
* 时间格式转换
* @param inputDateTime
* @return
*/
public static String convertToFormattedString(String inputDateTime) {
// 将字符串解析为ZonedDateTime对象
ZonedDateTime zonedDateTime = ZonedDateTime.parse(inputDateTime);
// 将ZonedDateTime对象转换为指定的格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return zonedDateTime.format(formatter);
}
3. 关闭支付订单
public static void closeOrder(String rechargeOrderId){
// 使用自动更新平台证书的RSA配置
Config config =
new RSAAutoCertificateConfig.Builder()
.merchantId("1xxxxxxxx1") // 商户号,10位数字
.privateKeyFromPath("D:\\AH\\apiclient_key.pem") // API证书地址(此处的路径自己调试一下,能找到就行)
.merchantSerialNumber("2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3") // API证书序列号
.apiV3Key("_xxxxxxxxxxxxxxxx__") // API密匙
.build();
// 构建service
NativePayService service = new NativePayService.Builder().config(config).build();
// request.setXxx(val)设置所需参数,具体参数可见Request定义
CloseOrderRequest request = new CloseOrderRequest();
request.setMchid("1xxxxxxxx1") // 商户号,10位数字
request.setOutTradeNo(rechargeOrderId);
AccountRechargePayResultDTO dto = new AccountRechargePayResultDTO();
// 调用下单方法,得到应答
try {
// 发送请求
service.closeOrder(request);
}catch (Exception e){
throw new SearchException(e.getMessage());
}
}