微信支付、退款
parent
0fce5abc9f
commit
246c6baf52
|
|
@ -1,12 +0,0 @@
|
|||
package com.njzscloud.supervisory.order.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BindParam {
|
||||
|
||||
private Long userId;
|
||||
|
||||
private String wxCode;
|
||||
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
package com.njzscloud.supervisory.order.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 退款请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class RefundRequestDto {
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 退款金额(公司退款时使用,微信退款时忽略)
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
/**
|
||||
* 退款原因
|
||||
*/
|
||||
@Size(max = 200, message = "退款原因不能超过200个字符")
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 微信支付退款相关参数(仅微信退款时使用)
|
||||
*/
|
||||
private WechatRefundParams wechatRefundParams;
|
||||
|
||||
@Data
|
||||
public static class WechatRefundParams {
|
||||
/**
|
||||
* 商户退款单号
|
||||
*/
|
||||
@Size(max = 64, message = "商户退款单号不能超过64个字符")
|
||||
private String outRefundNo;
|
||||
|
||||
/**
|
||||
* 退款资金来源
|
||||
*/
|
||||
private String fundsAccount;
|
||||
|
||||
/**
|
||||
* 退款结果回调地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,11 +5,13 @@ import com.github.binarywang.wxpay.service.WxPayService;
|
|||
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(WxPayService.class)
|
||||
|
|
@ -26,7 +28,22 @@ public class WxPayConfiguration {
|
|||
config.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
|
||||
config.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
|
||||
config.setMchKey(StringUtils.trimToNull(this.properties.getApiKey()));
|
||||
config.setKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
|
||||
String keyPath = StringUtils.trimToNull(this.properties.getPrivateKeyPath());
|
||||
config.setKeyPath(keyPath);
|
||||
|
||||
// 优先支持以 classpath: 开头的 p12 证书路径,直接加载为内存字节,避免路径解析兼容性问题
|
||||
if (StringUtils.isNotBlank(keyPath) && keyPath.startsWith("classpath:")) {
|
||||
String classpathLocation = keyPath.substring("classpath:".length());
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(classpathLocation.startsWith("/") ? classpathLocation.substring(1) : classpathLocation);
|
||||
if (resource.exists()) {
|
||||
byte[] keyBytes = StreamUtils.copyToByteArray(resource.getInputStream());
|
||||
config.setKeyContent(keyBytes);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 忽略此处异常,保持 SDK 以文件路径方式继续尝试读取
|
||||
}
|
||||
}
|
||||
// 可以指定是否使用沙箱环境
|
||||
// config.setUseSandboxEnv(false);
|
||||
WxPayService wxPayService = new WxPayServiceImpl();
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@ public class WxPayProperties {
|
|||
*/
|
||||
private String privateKeyPath;
|
||||
|
||||
private String privateCertPath;
|
||||
|
||||
private String privateCertP12Path;
|
||||
|
||||
/**
|
||||
* 支付回调地址
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,10 +1,21 @@
|
|||
package com.njzscloud.supervisory.wxPay.controller;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
|
||||
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
||||
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
|
||||
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
||||
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.google.common.base.Strings;
|
||||
import com.njzscloud.common.core.ex.ExceptionMsg;
|
||||
import com.njzscloud.common.core.ex.Exceptions;
|
||||
import com.njzscloud.common.core.utils.R;
|
||||
import com.njzscloud.common.security.ex.UserLoginException;
|
||||
import com.njzscloud.common.wechat.WechatUtil;
|
||||
import com.njzscloud.common.wechat.param.Code2SessionParam;
|
||||
import com.njzscloud.common.wechat.result.Code2SessionResult;
|
||||
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
|
||||
import com.njzscloud.supervisory.money.pojo.entity.MoneyAccountEntity;
|
||||
import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
|
||||
|
|
@ -13,15 +24,17 @@ import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
|
|||
import com.njzscloud.supervisory.order.contant.PaymentStatus;
|
||||
import com.njzscloud.supervisory.order.contant.PaymentWay;
|
||||
import com.njzscloud.supervisory.order.contant.SettlementWay;
|
||||
import com.njzscloud.supervisory.wxPay.dto.WechatPayJsapiOrderResponseDto;
|
||||
import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto;
|
||||
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
|
||||
import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity;
|
||||
import com.njzscloud.supervisory.order.pojo.param.PaymentItemParam;
|
||||
import com.njzscloud.supervisory.order.pojo.param.PaymentParam;
|
||||
import com.njzscloud.supervisory.wxPay.param.PaymentParam;
|
||||
import com.njzscloud.supervisory.order.pojo.result.PaymentContextResult;
|
||||
import com.njzscloud.supervisory.order.service.OrderExpenseItemsService;
|
||||
import com.njzscloud.supervisory.order.service.OrderInfoService;
|
||||
import com.njzscloud.supervisory.wxPay.config.WxPayProperties;
|
||||
import com.njzscloud.supervisory.wxPay.service.WeChatPayService;
|
||||
import com.njzscloud.supervisory.wxPay.utils.RequestHolder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -29,7 +42,6 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
|
@ -49,6 +61,8 @@ public class PaymentController {
|
|||
private final MoneyAccountService moneyAccountService;
|
||||
private final MoneyChangeDetailService moneyChangeDetailService;
|
||||
private final WeChatPayService wechatPayService;
|
||||
private final WxPayService wxPayService;
|
||||
private final WxPayProperties properties;
|
||||
|
||||
/**
|
||||
* 发起支付(使用生产级微信支付SDK)
|
||||
|
|
@ -146,12 +160,13 @@ public class PaymentController {
|
|||
wxRequest.setOutTradeNo(outTradeNo);
|
||||
wxRequest.setBody("订单支付-" + ctx.getSn());
|
||||
wxRequest.setTotalFee(ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue()); // 转换为分
|
||||
wxRequest.setOpenid(getCurrentUserOpenid());
|
||||
wxRequest.setOpenid(getCurrentUserOpenid(paymentParam.getWxCode()));
|
||||
wxRequest.setTradeType("JSAPI");
|
||||
wxRequest.setNotifyUrl("https://your-domain.com/payment/wechat/notify"); // 需要配置实际的回调地址
|
||||
wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
|
||||
wxRequest.setNotifyUrl(properties.getNotifyUrl()); // 需要配置实际的回调地址
|
||||
|
||||
// 调用微信支付服务
|
||||
WechatPayJsapiOrderResponseDto response = wechatPayService.createJsapiOrder(wxRequest);
|
||||
WxPayMpOrderResult result = (WxPayMpOrderResult) wechatPayService.createJsapiOrder(wxRequest);
|
||||
|
||||
// 更新订单状态为待支付
|
||||
orderInfoService.lambdaUpdate()
|
||||
|
|
@ -163,10 +178,10 @@ public class PaymentController {
|
|||
|
||||
log.info("微信支付订单创建成功(生产级SDK),订单ID:{},微信订单号:{}", paymentParam.getOrderId(), outTradeNo);
|
||||
|
||||
return R.success(response);
|
||||
} catch (Exception e) {
|
||||
return R.success(result);
|
||||
} catch (WxPayException e) {
|
||||
log.error("微信支付订单创建失败,订单ID:{},错误信息:{}", paymentParam.getOrderId(), e.getMessage(), e);
|
||||
throw Exceptions.clierr("微信支付订单创建失败:" + e.getMessage());
|
||||
WxPayNotifyResponse.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,10 +228,16 @@ public class PaymentController {
|
|||
/**
|
||||
* 获取当前用户openid
|
||||
*/
|
||||
public String getCurrentUserOpenid() {
|
||||
// 这里需要根据实际业务逻辑获取当前用户的openid
|
||||
// 可能通过JWT token、session等方式获取
|
||||
return "test_openid"; // 临时返回测试值
|
||||
public String getCurrentUserOpenid(String wxCode) {
|
||||
// 调用微信API获取openId和unionId
|
||||
Code2SessionResult code2SessionResult = WechatUtil.code2Session(new Code2SessionParam().setJs_code(wxCode));
|
||||
Integer errcode = code2SessionResult.getErrcode();
|
||||
if (errcode != null && errcode != 0) {
|
||||
log.error("微信登录失败, errcode: {}, errmsg: {}", errcode, code2SessionResult.getErrmsg());
|
||||
throw new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "微信登录失败");
|
||||
}
|
||||
|
||||
return code2SessionResult.getOpenid();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -234,14 +255,14 @@ public class PaymentController {
|
|||
}
|
||||
|
||||
/**
|
||||
* 从商户订单号中提取订单ID
|
||||
* 从商户订单号中提取订单sn
|
||||
*/
|
||||
private Long extractOrderIdFromOutTradeNo(String outTradeNo) {
|
||||
private String extractOrderIdFromOutTradeNo(String outTradeNo) {
|
||||
try {
|
||||
if (outTradeNo != null && outTradeNo.startsWith("ORDER_")) {
|
||||
String[] parts = outTradeNo.split("_");
|
||||
if (parts.length >= 2) {
|
||||
return Long.parseLong(parts[1]);
|
||||
return parts[1];
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -254,59 +275,159 @@ public class PaymentController {
|
|||
* 微信支付回调接口
|
||||
*/
|
||||
@PostMapping("/wechat/notify")
|
||||
public String wechatPayNotify(@RequestParam String xmlData) {
|
||||
public String wechatPayNotify(@RequestBody String xmlData) {
|
||||
try {
|
||||
log.info("收到微信支付回调:{}", xmlData);
|
||||
return wechatPayService.handleNotify(xmlData);
|
||||
} catch (Exception e) {
|
||||
log.error("处理微信支付回调异常:{}", e.getMessage(), e);
|
||||
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理异常]]></return_msg></xml>";
|
||||
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
|
||||
String orderSn = extractOrderIdFromOutTradeNo(notifyResult.getOutTradeNo());
|
||||
if (orderSn != null) {
|
||||
orderInfoService.lambdaUpdate()
|
||||
.eq(OrderInfoEntity::getSn, orderSn)
|
||||
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiZhiFu)
|
||||
.set(OrderInfoEntity::getPayTime, LocalDateTime.now())
|
||||
.update();
|
||||
|
||||
log.info("微信支付成功,商户订单号:{},微信交易号:{}",
|
||||
orderSn, notifyResult.getTransactionId());
|
||||
} else {
|
||||
log.warn("无法从商户订单号中提取订单");
|
||||
}
|
||||
return WxPayNotifyResponse.success("处理成功!");
|
||||
} catch (WxPayException e) {
|
||||
log.error(e.getMessage());
|
||||
return WxPayNotifyResponse.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询微信支付订单状态
|
||||
* 统一退款接口 - 支持微信退款和公司退款
|
||||
*/
|
||||
@PostMapping("/wechat/query")
|
||||
public R<?> queryWechatOrder(@RequestParam String outTradeNo) {
|
||||
@PostMapping("/refund")
|
||||
public R<?> refund(@RequestBody RefundRequestDto refundRequest) {
|
||||
try {
|
||||
WxPayOrderQueryResult result = wechatPayService.queryOrder(outTradeNo);
|
||||
return R.success(result);
|
||||
// 验证订单存在性
|
||||
OrderInfoEntity orderInfo = orderInfoService.getById(refundRequest.getOrderId());
|
||||
if (orderInfo == null) {
|
||||
throw Exceptions.clierr("订单不存在");
|
||||
}
|
||||
|
||||
// 验证订单状态
|
||||
if (!PaymentStatus.YiZhiFu.getVal().equals(orderInfo.getPaymentStatus().getVal())) {
|
||||
throw Exceptions.clierr("订单未支付,无法退款");
|
||||
}
|
||||
|
||||
// 获取支付上下文
|
||||
PaymentContextResult ctx = orderInfoService.paymentContext(refundRequest.getOrderId());
|
||||
if (ctx == null) {
|
||||
throw Exceptions.clierr("获取支付上下文失败");
|
||||
}
|
||||
|
||||
// 根据支付方式处理退款
|
||||
if (PaymentWay.WX.getVal().equals(ctx.getPaymentCategory())) {
|
||||
// 微信退款
|
||||
//生成退款单号
|
||||
String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
|
||||
int money = ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue();
|
||||
// 微信退全款
|
||||
String notifyUrl = properties.getRefundNotifyUrl();
|
||||
wechatPayService.refund(orderInfo.getOutTradeNo(), orderSn, money, money, notifyUrl);
|
||||
return R.success("退款成功");
|
||||
} else if (PaymentWay.COMPANY.getVal().equals(ctx.getPaymentCategory())) {
|
||||
// 公司退款
|
||||
return processCompanyRefund(refundRequest, ctx);
|
||||
} else {
|
||||
throw Exceptions.clierr("不支持的支付方式");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("查询微信支付订单失败,订单号:{},错误信息:{}", outTradeNo, e.getMessage(), e);
|
||||
return R.failed();
|
||||
log.error("退款处理异常,订单ID:{}", refundRequest.getOrderId(), e);
|
||||
return R.failed(ExceptionMsg.CLI_ERR_MSG, "退款处理失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭微信支付订单
|
||||
* 处理公司退款
|
||||
*/
|
||||
@PostMapping("/wechat/close")
|
||||
public R<?> closeWechatOrder(@RequestParam String outTradeNo) {
|
||||
try {
|
||||
wechatPayService.closeOrder(outTradeNo);
|
||||
return R.success("订单关闭成功");
|
||||
} catch (Exception e) {
|
||||
log.error("关闭微信支付订单失败,订单号:{},错误信息:{}", outTradeNo, e.getMessage(), e);
|
||||
return R.failed();
|
||||
private R<?> processCompanyRefund(RefundRequestDto refundRequest, PaymentContextResult ctx) {
|
||||
if (refundRequest.getRefundAmount() == null) {
|
||||
throw Exceptions.clierr("公司退款金额不能为空");
|
||||
}
|
||||
|
||||
if (refundRequest.getRefundAmount().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw Exceptions.clierr("退款金额必须大于0");
|
||||
}
|
||||
|
||||
if (refundRequest.getRefundAmount().compareTo(ctx.getSettleMoney()) > 0) {
|
||||
throw Exceptions.clierr("退款金额不能超过订单已结算金额");
|
||||
}
|
||||
|
||||
// 如果订单再次退款,本次退款金额+已退款金额不能大于结算金额
|
||||
if (refundRequest.getRefundAmount().add(ctx.getRefundMoney()).compareTo(ctx.getSettleMoney()) > 0) {
|
||||
throw Exceptions.clierr("退款金额总和不能超过订单已结算金额");
|
||||
}
|
||||
|
||||
// 恢复公司账户余额
|
||||
restoreCompanyBalance(ctx, refundRequest.getRefundAmount(), refundRequest.getOrderId(), refundRequest.getReason());
|
||||
|
||||
// 更新订单状态为已退款
|
||||
orderInfoService.lambdaUpdate()
|
||||
.eq(OrderInfoEntity::getId, refundRequest.getOrderId())
|
||||
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
|
||||
.set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
|
||||
.update();
|
||||
|
||||
log.info("公司退款成功,订单ID:{},退款金额:{}", refundRequest.getOrderId(), refundRequest.getRefundAmount());
|
||||
return R.success("退款成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请微信支付退款
|
||||
* 恢复公司账户余额
|
||||
*/
|
||||
@PostMapping("/wechat/refund")
|
||||
public R<?> refundWechatOrder(@RequestParam String outTradeNo,
|
||||
@RequestParam String outRefundNo,
|
||||
@RequestParam int totalFee,
|
||||
@RequestParam int refundFee,
|
||||
@RequestParam(required = false) String refundDesc) {
|
||||
private void restoreCompanyBalance(PaymentContextResult ctx, BigDecimal refundAmount, Long orderId, String reason) {
|
||||
if (ctx.getCompanyUserId() == null || ctx.getCompanyAccountId() == null) {
|
||||
throw Exceptions.clierr("公司账户信息不完整,无法退款");
|
||||
}
|
||||
|
||||
// 恢复公司账户余额
|
||||
BigDecimal oldBalance = ctx.getCompanyBalance();
|
||||
BigDecimal newBalance = oldBalance.add(refundAmount);
|
||||
MoneyAccountEntity companyAccount = new MoneyAccountEntity()
|
||||
.setId(ctx.getCompanyAccountId())
|
||||
.setMoney(newBalance);
|
||||
moneyAccountService.updateById(companyAccount);
|
||||
|
||||
// 记录资金明细(这里需要实现资金明细记录功能)
|
||||
MoneyChangeDetailEntity changeDetail = new MoneyChangeDetailEntity()
|
||||
.setCompanyId(ctx.getTransCompanyId())
|
||||
.setOrderId(orderId)
|
||||
.setMoneyAccountId(companyAccount.getId())
|
||||
.setOldMoney(oldBalance)
|
||||
.setDelta(refundAmount) // 扣减为负数
|
||||
.setNewMoney(newBalance)
|
||||
.setMoneyChangeCategory(MoneyChangeCategory.DingDanTuiKuan)
|
||||
.setMemo(reason);
|
||||
|
||||
moneyChangeDetailService.save(changeDetail);
|
||||
log.info("公司账户余额恢复成功,账户ID:{},恢复金额:{}", ctx.getCompanyAccountId(), refundAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信退款回调
|
||||
*/
|
||||
@PostMapping("/wechat/refundNotify")
|
||||
public String parseRefundNotifyResult(@RequestBody String xmlData) {
|
||||
try {
|
||||
String result = wechatPayService.refund(outTradeNo, outRefundNo, totalFee, refundFee, refundDesc);
|
||||
return R.success(result);
|
||||
} catch (Exception e) {
|
||||
log.error("申请微信支付退款失败,订单号:{},错误信息:{}", outTradeNo, e.getMessage(), e);
|
||||
return R.failed();
|
||||
WxPayRefundNotifyResult result = wxPayService.parseRefundNotifyResult(xmlData);
|
||||
String orderSn = extractOrderIdFromOutTradeNo(result.getReqInfo().getOutTradeNo());
|
||||
// 更新订单状态为已退款
|
||||
orderInfoService.lambdaUpdate()
|
||||
.eq(OrderInfoEntity::getSn, orderSn)
|
||||
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
|
||||
.set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
|
||||
.update();
|
||||
return WxPayNotifyResponse.success("退款成功!");
|
||||
} catch (WxPayException e) {
|
||||
log.error(e.getMessage());
|
||||
return WxPayNotifyResponse.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.njzscloud.supervisory.wxPay.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 退款请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class RefundRequestDto {
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 退款金额(公司退款时使用,微信退款时忽略)
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
/**
|
||||
* 退款原因
|
||||
*/
|
||||
@Size(max = 200, message = "退款原因不能超过200个字符")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package com.njzscloud.supervisory.wxPay.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 微信支付JSAPI/小程序下单请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class WechatPayJsapiOrderDto {
|
||||
|
||||
/**
|
||||
* 商品描述
|
||||
*/
|
||||
@NotBlank(message = "商品描述不能为空")
|
||||
@Size(max = 127, message = "商品描述不能超过127个字符")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@NotBlank(message = "商户订单号不能为空")
|
||||
@Size(min = 6, max = 32, message = "商户订单号长度必须在6-32个字符之间")
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* 用户openid
|
||||
*/
|
||||
@NotBlank(message = "用户openid不能为空")
|
||||
private String openid;
|
||||
|
||||
/**
|
||||
* 订单金额(分)
|
||||
*/
|
||||
@NotNull(message = "订单金额不能为空")
|
||||
private Long total;
|
||||
|
||||
/**
|
||||
* 货币类型
|
||||
*/
|
||||
private String currency = "CNY";
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package com.njzscloud.supervisory.wxPay.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 微信支付JSAPI/小程序下单响应DTO
|
||||
*/
|
||||
@Data
|
||||
public class WechatPayJsapiOrderResponseDto {
|
||||
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 预支付交易会话标识
|
||||
*/
|
||||
@JsonProperty("prepay_id")
|
||||
private String prepayId;
|
||||
|
||||
/**
|
||||
* 小程序调起支付参数
|
||||
*/
|
||||
private String timeStamp;
|
||||
|
||||
/**
|
||||
* 小程序调起支付参数
|
||||
*/
|
||||
private String nonceStr;
|
||||
|
||||
/**
|
||||
* 小程序调起支付参数
|
||||
*/
|
||||
@JsonProperty("package")
|
||||
private String packageValue;
|
||||
|
||||
/**
|
||||
* 小程序调起支付参数
|
||||
*/
|
||||
private String signType;
|
||||
|
||||
/**
|
||||
* 小程序调起支付参数
|
||||
*/
|
||||
private String paySign;
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.njzscloud.supervisory.order.pojo.param;
|
||||
package com.njzscloud.supervisory.wxPay.param;
|
||||
|
||||
import com.njzscloud.supervisory.order.pojo.param.PaymentItemParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
|
@ -30,6 +31,9 @@ public class PaymentParam {
|
|||
*/
|
||||
private BigDecimal settleTotalMoney;
|
||||
|
||||
/**
|
||||
* 微信code
|
||||
*/
|
||||
private String wxCode;
|
||||
|
||||
/**
|
||||
|
|
@ -3,7 +3,6 @@ package com.njzscloud.supervisory.wxPay.service;
|
|||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
||||
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.njzscloud.supervisory.wxPay.dto.WechatPayJsapiOrderResponseDto;
|
||||
|
||||
/**
|
||||
* 微信支付服务接口
|
||||
|
|
@ -16,7 +15,7 @@ public interface WeChatPayService {
|
|||
* @param request 下单请求参数
|
||||
* @return 支付参数
|
||||
*/
|
||||
WechatPayJsapiOrderResponseDto createJsapiOrder(WxPayUnifiedOrderRequest request) throws WxPayException;
|
||||
Object createJsapiOrder(WxPayUnifiedOrderRequest request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 查询订单状态
|
||||
|
|
@ -38,30 +37,14 @@ public interface WeChatPayService {
|
|||
/**
|
||||
* 申请退款
|
||||
*
|
||||
* @param outTradeNo 商户订单号
|
||||
* @param outTradeNo 商户订单号
|
||||
* @param outRefundNo 商户退款单号
|
||||
* @param totalFee 订单总金额(分)
|
||||
* @param refundFee 退款金额(分)
|
||||
* @param refundDesc 退款描述
|
||||
* @param totalFee 订单总金额(分)
|
||||
* @param refundFee 退款金额(分)
|
||||
* @param notifyUrl 退款回调地址
|
||||
* @return 退款结果
|
||||
* @throws WxPayException 微信支付异常
|
||||
*/
|
||||
String refund(String outTradeNo, String outRefundNo, int totalFee, int refundFee, String refundDesc) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 验证支付回调签名
|
||||
*
|
||||
* @param xmlData 回调XML数据
|
||||
* @return 验证结果
|
||||
*/
|
||||
boolean verifyNotify(String xmlData);
|
||||
|
||||
/**
|
||||
* 处理支付回调
|
||||
*
|
||||
* @param xmlData 回调XML数据
|
||||
* @return 处理结果
|
||||
*/
|
||||
String handleNotify(String xmlData);
|
||||
String refund(String outTradeNo, String outRefundNo, int totalFee, int refundFee, String notifyUrl) throws WxPayException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,17 @@
|
|||
package com.njzscloud.supervisory.wxPay.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
||||
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
|
||||
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
|
||||
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.njzscloud.supervisory.wxPay.dto.WechatPayJsapiOrderResponseDto;
|
||||
import com.njzscloud.supervisory.wxPay.service.WeChatPayService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信支付服务实现类
|
||||
*/
|
||||
|
|
@ -28,49 +22,17 @@ public class WeChatPayServiceImpl implements WeChatPayService {
|
|||
|
||||
private final WxPayService wxPayService;
|
||||
|
||||
private static final String WECHAT_PAY_API_BASE = "https://api.mch.weixin.qq.com";
|
||||
private static final String JSAPI_ORDER_PATH = "/v3/pay/transactions/jsapi";
|
||||
private static final String ORDER_QUERY_PATH_PREFIX = "/v3/pay/transactions/out-trade-no/";
|
||||
private static final String ORDER_CLOSE_PATH_SUFFIX = "/close";
|
||||
private static final String REFUND_PATH = "/v3/refund/domestic/refunds";
|
||||
private static final String REFUND_QUERY_PATH_PREFIX = "/v3/refund/domestic/refunds/";
|
||||
|
||||
|
||||
@Override
|
||||
public WechatPayJsapiOrderResponseDto createJsapiOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
|
||||
try {
|
||||
log.info("开始创建微信支付JSAPI订单,商户订单号:{}", request.getOutTradeNo());
|
||||
|
||||
// 调用微信支付SDK创建订单
|
||||
WxPayUnifiedOrderResult result = wxPayService.createOrder(request);
|
||||
|
||||
if (result == null) {
|
||||
throw new WxPayException("微信支付订单创建失败,返回结果为空");
|
||||
}
|
||||
|
||||
// 构建响应DTO
|
||||
WechatPayJsapiOrderResponseDto responseDto = new WechatPayJsapiOrderResponseDto();
|
||||
responseDto.setAppId(result.getAppid());
|
||||
responseDto.setPrepayId(result.getPrepayId());
|
||||
responseDto.setTimeStamp(String.valueOf(System.currentTimeMillis() / 1000));
|
||||
responseDto.setNonceStr(result.getNonceStr());
|
||||
responseDto.setPackageValue("prepay_id=" + result.getPrepayId());
|
||||
responseDto.setSignType("RSA");
|
||||
|
||||
// 生成小程序调起支付的签名
|
||||
String paySign = generatePaySign(responseDto);
|
||||
responseDto.setPaySign(paySign);
|
||||
|
||||
log.info("微信支付JSAPI订单创建成功,预支付ID:{}", result.getPrepayId());
|
||||
return responseDto;
|
||||
|
||||
} catch (WxPayException e) {
|
||||
log.error("微信支付订单创建失败,商户订单号:{},错误信息:{}", request.getOutTradeNo(), e.getMessage(), e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("微信支付订单创建异常,商户订单号:{},错误信息:{}", request.getOutTradeNo(), e.getMessage(), e);
|
||||
throw new WxPayException("微信支付订单创建异常:" + e.getMessage(), e);
|
||||
public Object createJsapiOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
|
||||
log.info("开始创建微信支付JSAPI订单,入参为:{}", JSON.toJSONString(request));
|
||||
|
||||
// 调用微信支付SDK创建订单
|
||||
Object result = wxPayService.createOrder(request);
|
||||
|
||||
if (result == null) {
|
||||
throw new WxPayException("微信支付订单创建失败,返回结果为空");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,26 +72,26 @@ public class WeChatPayServiceImpl implements WeChatPayService {
|
|||
/**
|
||||
* 申请退款
|
||||
*
|
||||
* @param outTradeNo 商户订单号
|
||||
* @param outTradeNo 商户订单号
|
||||
* @param outRefundNo 商户退款单号
|
||||
* @param totalFee 订单总金额(分)
|
||||
* @param refundFee 退款金额(分)
|
||||
* @param refundDesc 退款描述
|
||||
* @param totalFee 订单总金额(分)
|
||||
* @param refundFee 退款金额(分)
|
||||
* @param notifyUrl 退款描述
|
||||
* @return 退款结果
|
||||
* @throws WxPayException 微信支付异常
|
||||
*/
|
||||
public String refund(String outTradeNo, String outRefundNo, int totalFee, int refundFee, String refundDesc) throws WxPayException {
|
||||
public String refund(String outTradeNo, String outRefundNo, int totalFee, int refundFee, String notifyUrl) throws WxPayException {
|
||||
try {
|
||||
log.info("开始申请微信支付退款,商户订单号:{},退款单号:{},退款金额:{}", outTradeNo, outRefundNo, refundFee);
|
||||
|
||||
|
||||
WxPayRefundRequest refundRequest = WxPayRefundRequest.newBuilder()
|
||||
.outTradeNo(outTradeNo)
|
||||
.outRefundNo(outRefundNo)
|
||||
.totalFee(totalFee)
|
||||
.refundFee(refundFee)
|
||||
.refundDesc(refundDesc)
|
||||
.build();
|
||||
|
||||
.outTradeNo(outTradeNo)
|
||||
.outRefundNo(outRefundNo)
|
||||
.totalFee(totalFee)
|
||||
.refundFee(refundFee)
|
||||
.notifyUrl(notifyUrl)
|
||||
.build();
|
||||
|
||||
WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
|
||||
return refundResult.getRefundId();
|
||||
} catch (WxPayException e) {
|
||||
|
|
@ -138,153 +100,4 @@ public class WeChatPayServiceImpl implements WeChatPayService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成小程序调起支付的签名
|
||||
*
|
||||
* 小程序调起支付的签名规则:
|
||||
* 1. 对参数按照key=value的格式,并按照参数名ASCII字典序排序
|
||||
* 2. 如果参数的值为空不参与签名
|
||||
* 3. 参数名区分大小写
|
||||
* 4. 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名
|
||||
* 5. 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
|
||||
*
|
||||
* @param responseDto 支付响应DTO
|
||||
* @return 支付签名
|
||||
*/
|
||||
private String generatePaySign(WechatPayJsapiOrderResponseDto responseDto) {
|
||||
try {
|
||||
// 构建签名字符串
|
||||
StringBuilder signStr = new StringBuilder();
|
||||
signStr.append("appId=").append(responseDto.getAppId())
|
||||
.append("&nonceStr=").append(responseDto.getNonceStr())
|
||||
.append("&package=").append(responseDto.getPackageValue())
|
||||
.append("&signType=").append(responseDto.getSignType())
|
||||
.append("&timeStamp=").append(responseDto.getTimeStamp());
|
||||
|
||||
// 获取商户密钥(需要从配置中获取)
|
||||
String apiKey = wxPayService.getConfig().getMchKey();
|
||||
|
||||
// 添加商户密钥
|
||||
signStr.append("&key=").append(apiKey);
|
||||
|
||||
// 使用MD5签名
|
||||
String signString = signStr.toString();
|
||||
log.debug("待签名字符串:{}", signString);
|
||||
|
||||
// 使用MD5签名(这里需要使用MD5工具类)
|
||||
String paySign = md5(signString).toUpperCase();
|
||||
|
||||
log.debug("生成的支付签名:{}", paySign);
|
||||
return paySign;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("生成支付签名失败:{}", e.getMessage(), e);
|
||||
throw new RuntimeException("生成支付签名失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5签名
|
||||
*
|
||||
* @param data 待签名数据
|
||||
* @return MD5签名结果
|
||||
*/
|
||||
private String md5(String data) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] bytes = md.digest(data.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
sb.append(String.format("%02x", b));
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
log.error("MD5签名失败:{}", e.getMessage(), e);
|
||||
throw new RuntimeException("MD5签名失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证支付回调签名
|
||||
*
|
||||
* @param xmlData 回调XML数据
|
||||
* @return 验证结果
|
||||
*/
|
||||
public boolean verifyNotify(String xmlData) {
|
||||
try {
|
||||
// 验证签名(暂时返回true,实际项目中需要实现正确的签名验证逻辑)
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("验证支付回调签名失败:{}", e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理支付回调
|
||||
*
|
||||
* @param xmlData 回调XML数据
|
||||
* @return 处理结果
|
||||
*/
|
||||
public String handleNotify(String xmlData) {
|
||||
try {
|
||||
log.info("开始处理微信支付回调:{}", xmlData);
|
||||
|
||||
// 验证签名
|
||||
if (!verifyNotify(xmlData)) {
|
||||
log.error("支付回调签名验证失败");
|
||||
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
|
||||
}
|
||||
|
||||
// 解析回调数据
|
||||
Map<String, String> notifyData = parseXmlToMap(xmlData);
|
||||
String outTradeNo = notifyData.get("out_trade_no");
|
||||
String transactionId = notifyData.get("transaction_id");
|
||||
String resultCode = notifyData.get("result_code");
|
||||
|
||||
log.info("支付回调处理成功,商户订单号:{},微信交易号:{},结果:{}", outTradeNo, transactionId, resultCode);
|
||||
|
||||
// 这里可以添加业务逻辑,比如更新订单状态等
|
||||
// TODO: 根据实际业务需求处理支付成功后的逻辑
|
||||
|
||||
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理支付回调异常:{}", e.getMessage(), e);
|
||||
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理异常]]></return_msg></xml>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单的XML解析方法
|
||||
*
|
||||
* @param xmlData XML数据
|
||||
* @return 解析后的Map
|
||||
*/
|
||||
private Map<String, String> parseXmlToMap(String xmlData) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
try {
|
||||
// 简单的XML解析,提取标签和值
|
||||
String[] lines = xmlData.split("\n");
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("<") && line.endsWith(">") && !line.startsWith("</")) {
|
||||
int start = line.indexOf(">") + 1;
|
||||
int end = line.lastIndexOf("<");
|
||||
if (start > 0 && end > start) {
|
||||
String key = line.substring(1, line.indexOf(">"));
|
||||
String value = line.substring(start, end);
|
||||
// 移除CDATA包装
|
||||
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
|
||||
value = value.substring(9, value.length() - 3);
|
||||
}
|
||||
result.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析XML数据失败:{}", e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.njzscloud.supervisory.wxPay.utils;
|
||||
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RequestHolder {
|
||||
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
}
|
||||
|
||||
public static String getClientIP() {
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
return ServletUtil.getClientIP(request);
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,8 @@ spring:
|
|||
- /bulletin/paging
|
||||
- /truck_location_track/**
|
||||
- /fdx
|
||||
- /payment/wechat/callback
|
||||
- /payment/wechat/notify
|
||||
- /payment/wechat/refundNotify
|
||||
app:
|
||||
default-place:
|
||||
province: 320000
|
||||
|
|
@ -71,13 +72,12 @@ wechat:
|
|||
# 证书序列号
|
||||
cert-serial-no: 1BCB1533688F349541C7B636EF67C666828BADBA
|
||||
# 文件路径
|
||||
private-key-path: classpath:cert/apiclient_key.pem
|
||||
private-cert-path: classpath:cert/apiclient_cert.pem
|
||||
private-cert-p12-path: classpath:cert/apiclient_key.p12
|
||||
private-key-path: classpath:cert/apiclient_cert.p12
|
||||
# private-key-path: D:/project/再昇云/代码/njzscloud/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12
|
||||
# 支付回调地址
|
||||
notify-url: https://your-domain.com/api/payment/wechat/callback
|
||||
notify-url: http://115.29.236.92:8082/payment/wechat/notify
|
||||
# 退款回调地址
|
||||
refund-notify-url: https://your-domain.com/api/payment/wechat/refundCallback
|
||||
refund-notify-url: http://115.29.236.92:8082/payment/wechat/refundNotify
|
||||
mqtt:
|
||||
enabled: true
|
||||
broker: tcp://139.224.54.144:1883
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEJDCCAwygAwIBAgIUG8sVM2iPNJVBx7Y272fGZoKLrbowDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjUxMDEzMDI1OTIxWhcNMzAxMDEyMDI1OTIxWjB+MRMwEQYDVQQDDAox
|
||||
NzI5NzAzMTEwMRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xKjAoBgNVBAsM
|
||||
Iea7geW3nuW4guWFtOa7geWunuS4muaciemZkOWFrOWPuDELMAkGA1UEBhMCQ04x
|
||||
ETAPBgNVBAcMCFNoZW5aaGVuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAveXhbJ0COwMCbfVwyjhiMRRvLwmQlOvxnjwVncGZK8RbNiel0z1xtlJs8+nv
|
||||
s2T/j2ln5ceRjpnzAErSqmq+Y16l859kTOMkly3B1u3CPAf415tZRrHG3KEM19Fi
|
||||
z+lcxyo/VHgGvJuVVPqV0/n3OY8nz4VTvFL+jDGtyTGJlTmX8EekJ3e7tzyQrGS9
|
||||
+twC7NxQC0Ob11/rGksT/dnVlSSZu4VlYwDFfUeTsGXIV1NbRmnvsjy30AHQW4dI
|
||||
DLWYyT30xloKL02pN7g3NJB1qm3g5L1wby97zOhJBtdZPINq2ubahN2pPNF3Jf/2
|
||||
pqoZ9W70AO0kJ+6eOir7t02n2QIDAQABo4G5MIG2MAkGA1UdEwQCMAAwCwYDVR0P
|
||||
BAQDAgP4MIGbBgNVHR8EgZMwgZAwgY2ggYqggYeGgYRodHRwOi8vZXZjYS5pdHJ1
|
||||
cy5jb20uY24vcHVibGljL2l0cnVzY3JsP0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFE
|
||||
Mzk3NTQ5ODQ2QzAxQzNFOEVCRDImc2c9SEFDQzQ3MUI2NTQyMkUxMkIyN0E5RDMz
|
||||
QTg3QUQxQ0RGNTkyNkUxNDAzNzEwDQYJKoZIhvcNAQELBQADggEBABwjPgD83RY2
|
||||
NJZswumIh70IeEsthu7H/uHQJhkHxqetMRcbarr6uSAzdaXrk4aq/h/UQ+kzVjd4
|
||||
VCcx3YRX2tkxhAnfVJEnQTFYtQ5kTWa83P/W2mrQm/XjnMWa2RD44lhld14kx/zO
|
||||
gBhQHZcG8jQiNoJspIXIaTxvzU6XsDh2muPA0Ris6l4/83z7dNguWPzAxAD+B1Nn
|
||||
60KP1eOj+Jjw9wLOqWmtI48zFU8MHDzjYmeFtu4QSJy1eMn7gNKQ91pSjR0r2fzS
|
||||
ujLMBgtY657UEXPlwtVSzohnWCr0hAnMrFsxMuNPkeOOg+QuXOZoOa1J84aBu1oU
|
||||
SFzt6sqGLgM=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC95eFsnQI7AwJt
|
||||
9XDKOGIxFG8vCZCU6/GePBWdwZkrxFs2J6XTPXG2Umzz6e+zZP+PaWflx5GOmfMA
|
||||
StKqar5jXqXzn2RM4ySXLcHW7cI8B/jXm1lGscbcoQzX0WLP6VzHKj9UeAa8m5VU
|
||||
+pXT+fc5jyfPhVO8Uv6MMa3JMYmVOZfwR6Qnd7u3PJCsZL363ALs3FALQ5vXX+sa
|
||||
SxP92dWVJJm7hWVjAMV9R5OwZchXU1tGae+yPLfQAdBbh0gMtZjJPfTGWgovTak3
|
||||
uDc0kHWqbeDkvXBvL3vM6EkG11k8g2ra5tqE3ak80Xcl//amqhn1bvQA7SQn7p46
|
||||
Kvu3TafZAgMBAAECggEAFu2vtzaJ82gcnfw5nyEJshVei1ZjT6fhZ5KnpYGfpeoy
|
||||
fSpyWjwcA8CWCSlg2M9EECPQ+KyNBaPO9GUUZKE41bSy4uSG7sWqQFq1Aed5QVhR
|
||||
Em9eayvB8Be9/jz46lOp8R5HwUIwxgsfD8Cl4I9Y62k+jE7z2lRHCdRhwF4r14mE
|
||||
cKZCi8JclOQkEkWN0R3gEZuwOV2LUYwHT1TPGMsSIoTKz66K1C45wN1HViL+XI1A
|
||||
VgwFnzFKbixB4tmU8QfcB/BiR5dLaurN2oCLcIh9/goNAq3W9t8R0c4vhpRtVthg
|
||||
SeYB4MonUsWUOmA46O+aQsnVshIFmHQUDp3571o6UQKBgQDe4GZQWlQryUDAKGco
|
||||
4B0PBoJia460Q+ll+0uFcDHsV5abmpJ4qwQ04OTRNwNRyh9Ni0uqH400zABpoKC8
|
||||
W+wfZdHfJeQHOtKc+hTh8hMOKHENvFpq79qY0iFpTPXoCP5xRdZ2y7460Lx2Sz8f
|
||||
oABfLD1zZkFCtg4KlEGATcD6HQKBgQDaHsWQK1FtFBpjYSjmDzTN73t7hGjCNOtx
|
||||
sscOhIb6sP0Dc5BlmBX+3O04D0KMToSdAezAeHvC1K9SotkYE+MYRlMRxxpTgRMT
|
||||
kyGKFnYTaH4yu9ntDHtEEkvk2GPSmpG3m6d61DNCZM5Y0hGEIrIJpaK31PI5bSoY
|
||||
jyrpdmuX7QKBgGJ9ZZlCoYmL8Po5oIS2rQCzzrBxeWl9zUlMyG3aS6V2e06d+vYq
|
||||
FLzNWTB/EA93s2eQE8rFEKBxOglzezRhprGlTB5BX0g2nVXTSaEjWXpbMsJwJsC0
|
||||
57O6wBsJcG2uc8pYo1Jx7MmO7omT7Pwrt55XLXyuhk5Vp1TTeTKaqZmdAoGAcFjB
|
||||
MczeF+zu2plE05qpfBkJ5UkCHGXdj6ah2NxyGdXnvEtd6LY5PhjVJrbVdCdNLwG6
|
||||
zDhCpsudslamszwrEGnIh7Oh37jv9nkmIVYIY17DAaa4TNzM8PbrmGfMosFypLvL
|
||||
u/xomp4Jmr44v3KPeWCTO1S3ntSXhibX14BjUtECgYAp9K5TOTD8bPX1IVz3nZvB
|
||||
ADA1U87AQJ0zrvGjHCOCY//hngQw5Q+oKb24Uo3TkEfkhuXr58AGRPqnRoOYeCUm
|
||||
cS3bjLkqOQN6fukRsT1Lb+FG0UZh7DdakUo9UtSUanWl3AdVdLWHWJmV4hZ2E5Fi
|
||||
GM/N+FRqmebPyJRFNhQY0Q==
|
||||
-----END PRIVATE KEY-----
|
||||
10
pom.xml
10
pom.xml
|
|
@ -181,6 +181,16 @@
|
|||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>cert/**</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<includes>
|
||||
<include>cert/**</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
|
|
|||
Loading…
Reference in New Issue