大改:重构项目
This commit is contained in:
@@ -1,68 +0,0 @@
|
|||||||
# 证书目录说明
|
|
||||||
|
|
||||||
这个目录用于存放支付相关的证书文件,支持Docker容器化部署。
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
|
|
||||||
```
|
|
||||||
certs/
|
|
||||||
├── README.md # 本说明文件
|
|
||||||
├── wechat/ # 微信支付证书目录
|
|
||||||
│ ├── apiclient_key.pem # 商户私钥证书
|
|
||||||
│ ├── apiclient_cert.pem # 商户证书
|
|
||||||
│ └── wechatpay_cert.pem # 微信支付平台证书
|
|
||||||
└── alipay/ # 支付宝证书目录
|
|
||||||
├── app_private_key.pem # 应用私钥
|
|
||||||
├── appCertPublicKey.crt # 应用公钥证书
|
|
||||||
├── alipayCertPublicKey.crt # 支付宝公钥证书
|
|
||||||
└── alipayRootCert.crt # 支付宝根证书
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用说明
|
|
||||||
|
|
||||||
### 1. 开发环境
|
|
||||||
- 将证书文件放在 `src/main/resources/certs/dev/` 目录下
|
|
||||||
- 应用会从classpath加载证书
|
|
||||||
|
|
||||||
### 2. 生产环境
|
|
||||||
- 将证书文件放在此目录下
|
|
||||||
- Docker容器会将此目录挂载到 `/app/certs`
|
|
||||||
- 应用会从挂载卷加载证书
|
|
||||||
|
|
||||||
### 3. 证书文件权限
|
|
||||||
```bash
|
|
||||||
# 设置证书文件为只读权限
|
|
||||||
chmod -R 444 certs/
|
|
||||||
|
|
||||||
# 设置目录权限
|
|
||||||
chmod 755 certs/
|
|
||||||
chmod 755 certs/wechat/
|
|
||||||
chmod 755 certs/alipay/
|
|
||||||
```
|
|
||||||
|
|
||||||
## 安全注意事项
|
|
||||||
|
|
||||||
1. **不要将证书文件提交到版本控制系统**
|
|
||||||
2. **确保证书文件权限设置正确**
|
|
||||||
3. **定期更新证书文件**
|
|
||||||
4. **备份重要的证书文件**
|
|
||||||
|
|
||||||
## 证书获取方式
|
|
||||||
|
|
||||||
### 微信支付证书
|
|
||||||
1. 登录微信商户平台
|
|
||||||
2. 进入"账户中心" -> "API安全"
|
|
||||||
3. 下载商户证书和平台证书
|
|
||||||
|
|
||||||
### 支付宝证书
|
|
||||||
1. 登录支付宝开放平台
|
|
||||||
2. 进入应用详情页
|
|
||||||
3. 在"开发设置"中下载相关证书
|
|
||||||
|
|
||||||
## 故障排除
|
|
||||||
|
|
||||||
如果遇到证书加载问题,请检查:
|
|
||||||
1. 证书文件是否存在
|
|
||||||
2. 证书文件路径是否正确
|
|
||||||
3. 证书文件权限是否正确
|
|
||||||
4. 证书文件是否已过期
|
|
||||||
@@ -204,9 +204,15 @@ public class BszxPayController extends BaseController {
|
|||||||
@Schema(description = "异步通知")
|
@Schema(description = "异步通知")
|
||||||
@PostMapping("/notify/{tenantId}")
|
@PostMapping("/notify/{tenantId}")
|
||||||
public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body,HttpServletRequest request, @PathVariable("tenantId") Integer tenantId) {
|
public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body,HttpServletRequest request, @PathVariable("tenantId") Integer tenantId) {
|
||||||
// 获取支付配置信息用于解密
|
// 获取支付配置信息用于解密 - 优先使用 Payment:1* 格式
|
||||||
String key = "Payment:1:".concat(tenantId.toString());
|
String key = "Payment:11"; // 微信支付类型为1,使用 Payment:11 格式
|
||||||
Payment payment = redisUtil.get(key, Payment.class);
|
Payment payment = redisUtil.get(key, Payment.class);
|
||||||
|
|
||||||
|
// 如果 Payment:1* 格式不存在,尝试原有格式
|
||||||
|
if (payment == null) {
|
||||||
|
String fallbackKey = "Payment:1:".concat(tenantId.toString());
|
||||||
|
payment = redisUtil.get(fallbackKey, Payment.class);
|
||||||
|
}
|
||||||
String uploadPath = conf.getUploadPath();
|
String uploadPath = conf.getUploadPath();
|
||||||
|
|
||||||
// 开发环境
|
// 开发环境
|
||||||
@@ -223,9 +229,10 @@ public class BszxPayController extends BaseController {
|
|||||||
mid = payment.getMchId();
|
mid = payment.getMchId();
|
||||||
apiV3Key = payment.getApiKey();
|
apiV3Key = payment.getApiKey();
|
||||||
serialNumber = payment.getMerchantSerialNumber();
|
serialNumber = payment.getMerchantSerialNumber();
|
||||||
privateKey = payment.getApiclientKey();
|
// 生产环境使用容器证书路径 /www/wwwroot/file.ws
|
||||||
apiclientCert = conf.getUploadPath().concat("/file").concat(payment.getApiclientCert());
|
privateKey = "/www/wwwroot/file.ws" + payment.getApiclientKey();
|
||||||
pubKey = uploadPath.concat("file").concat(payment.getPubKey());
|
apiclientCert = "/www/wwwroot/file.ws" + payment.getApiclientCert();
|
||||||
|
pubKey = "/www/wwwroot/file.ws" + payment.getPubKey();
|
||||||
pubId = payment.getPubKeyId();
|
pubId = payment.getPubKeyId();
|
||||||
}
|
}
|
||||||
RequestParam requestParam = new RequestParam.Builder()
|
RequestParam requestParam = new RequestParam.Builder()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class CertificateProperties {
|
|||||||
/**
|
/**
|
||||||
* Docker挂载卷证书根路径
|
* Docker挂载卷证书根路径
|
||||||
*/
|
*/
|
||||||
private String certRootPath = "/app/certs";
|
private String certRootPath = "/www/wwwroot/file.ws";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开发环境证书路径前缀
|
* 开发环境证书路径前缀
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.gxwebsoft.common.core.annotation.OperationLog;
|
|||||||
import com.gxwebsoft.common.core.utils.RedisUtil;
|
import com.gxwebsoft.common.core.utils.RedisUtil;
|
||||||
import com.gxwebsoft.common.core.utils.RequestUtil;
|
import com.gxwebsoft.common.core.utils.RequestUtil;
|
||||||
import com.gxwebsoft.common.core.web.*;
|
import com.gxwebsoft.common.core.web.*;
|
||||||
|
import com.gxwebsoft.common.core.service.PaymentCacheService;
|
||||||
import com.gxwebsoft.common.system.entity.Payment;
|
import com.gxwebsoft.common.system.entity.Payment;
|
||||||
import com.gxwebsoft.common.system.entity.User;
|
import com.gxwebsoft.common.system.entity.User;
|
||||||
import com.gxwebsoft.common.system.entity.UserBalanceLog;
|
import com.gxwebsoft.common.system.entity.UserBalanceLog;
|
||||||
@@ -51,6 +52,8 @@ public class PaymentController extends BaseController {
|
|||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
@Resource
|
@Resource
|
||||||
private RequestUtil requestUtil;
|
private RequestUtil requestUtil;
|
||||||
|
@Resource
|
||||||
|
private PaymentCacheService paymentCacheService;
|
||||||
|
|
||||||
@Operation(summary = "余额支付接口")
|
@Operation(summary = "余额支付接口")
|
||||||
@PostMapping("/balancePay")
|
@PostMapping("/balancePay")
|
||||||
@@ -96,10 +99,9 @@ public class PaymentController extends BaseController {
|
|||||||
amount.setTotal(money);
|
amount.setTotal(money);
|
||||||
amount.setCurrency("CNY");
|
amount.setCurrency("CNY");
|
||||||
transaction.setAmount(amount);
|
transaction.setAmount(amount);
|
||||||
// 获取支付配置信息用于解密
|
// 获取支付配置信息用于解密 - 使用缓存服务
|
||||||
String key = "Payment:0:".concat(order.getTenantId().toString());
|
Payment payment = paymentCacheService.getWechatPayConfig(order.getTenantId());
|
||||||
System.out.println("key = " + key);
|
System.out.println("获取到支付配置: " + payment.getMchId());
|
||||||
final Payment payment = redisUtil.get(key, Payment.class);
|
|
||||||
requestUtil.pushBalancePayNotify(transaction, payment);
|
requestUtil.pushBalancePayNotify(transaction, payment);
|
||||||
|
|
||||||
return success("支付成功",order.getOrderNo());
|
return success("支付成功",order.getOrderNo());
|
||||||
@@ -161,8 +163,8 @@ public class PaymentController extends BaseController {
|
|||||||
return fail(payment.getName() + "已存在");
|
return fail(payment.getName() + "已存在");
|
||||||
}
|
}
|
||||||
if (paymentService.save(payment)) {
|
if (paymentService.save(payment)) {
|
||||||
String key = "Payment:" + payment.getCode() + ":" + getTenantId();
|
// 使用缓存服务统一管理缓存
|
||||||
redisUtil.set(key,payment);
|
paymentCacheService.cachePaymentConfig(payment, getTenantId());
|
||||||
return success("添加成功");
|
return success("添加成功");
|
||||||
}
|
}
|
||||||
return fail("添加失败");
|
return fail("添加失败");
|
||||||
@@ -174,8 +176,8 @@ public class PaymentController extends BaseController {
|
|||||||
@PutMapping()
|
@PutMapping()
|
||||||
public ApiResult<?> update(@RequestBody Payment payment) {
|
public ApiResult<?> update(@RequestBody Payment payment) {
|
||||||
if (paymentService.updateById(payment)) {
|
if (paymentService.updateById(payment)) {
|
||||||
String key = "Payment:" + payment.getCode() + ":" + getTenantId();
|
// 使用缓存服务统一管理缓存
|
||||||
redisUtil.set(key,payment);
|
paymentCacheService.cachePaymentConfig(payment, getTenantId());
|
||||||
return success("修改成功");
|
return success("修改成功");
|
||||||
}
|
}
|
||||||
return fail("修改失败");
|
return fail("修改失败");
|
||||||
@@ -188,8 +190,9 @@ public class PaymentController extends BaseController {
|
|||||||
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
||||||
final Payment payment = paymentService.getById(id);
|
final Payment payment = paymentService.getById(id);
|
||||||
System.out.println("payment = " + payment);
|
System.out.println("payment = " + payment);
|
||||||
String key = "Payment:" + payment.getCode() + ":" + getTenantId();
|
|
||||||
redisUtil.delete(key);
|
// 使用缓存服务统一管理缓存删除
|
||||||
|
paymentCacheService.removePaymentConfig(payment.getCode(), getTenantId());
|
||||||
if (paymentService.removeById(id)) {
|
if (paymentService.removeById(id)) {
|
||||||
return success("删除成功");
|
return success("删除成功");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
import com.gxwebsoft.common.core.exception.BusinessException;
|
import com.gxwebsoft.common.core.exception.BusinessException;
|
||||||
import com.gxwebsoft.common.core.utils.RedisUtil;
|
import com.gxwebsoft.common.core.utils.RedisUtil;
|
||||||
import com.gxwebsoft.common.core.utils.CertificateLoader;
|
import com.gxwebsoft.common.core.utils.CertificateLoader;
|
||||||
|
import com.gxwebsoft.common.core.service.PaymentCacheService;
|
||||||
import com.gxwebsoft.common.system.entity.Payment;
|
import com.gxwebsoft.common.system.entity.Payment;
|
||||||
import com.gxwebsoft.common.system.param.PaymentParam;
|
import com.gxwebsoft.common.system.param.PaymentParam;
|
||||||
import com.gxwebsoft.common.system.service.PaymentService;
|
import com.gxwebsoft.common.system.service.PaymentService;
|
||||||
@@ -65,6 +66,8 @@
|
|||||||
private CertificateProperties certConfig;
|
private CertificateProperties certConfig;
|
||||||
@Resource
|
@Resource
|
||||||
private CertificateLoader certificateLoader;
|
private CertificateLoader certificateLoader;
|
||||||
|
@Resource
|
||||||
|
private PaymentCacheService paymentCacheService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<ShopOrder> pageRel(ShopOrderParam param) {
|
public PageResult<ShopOrder> pageRel(ShopOrderParam param) {
|
||||||
@@ -192,23 +195,13 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取微信支付配置
|
* 读取微信支付配置
|
||||||
|
* 生产环境优先从缓存读取 Payment:1* 格式的商户信息
|
||||||
*
|
*
|
||||||
* @param order
|
* @param order
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Payment getPayment(ShopOrder order) {
|
public Payment getPayment(ShopOrder order) {
|
||||||
String key2 = "Payment:".concat(order.getPayType().toString()).concat(":").concat(order.getTenantId().toString());
|
return paymentCacheService.getPaymentConfig(order.getPayType(), order.getTenantId());
|
||||||
final Payment payment = redisUtil.get(key2, Payment.class);
|
|
||||||
if (ObjectUtil.isNotEmpty(payment)) {
|
|
||||||
return payment;
|
|
||||||
}
|
|
||||||
final PaymentParam paymentParam = new PaymentParam();
|
|
||||||
paymentParam.setType(order.getPayType());
|
|
||||||
final List<Payment> payments = paymentService.listRel(paymentParam);
|
|
||||||
if (payments.isEmpty()) {
|
|
||||||
throw new BusinessException("请完成支付配置");
|
|
||||||
}
|
|
||||||
return payments.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -229,15 +222,15 @@
|
|||||||
apiclientCert = certificateLoader.loadCertificatePath(
|
apiclientCert = certificateLoader.loadCertificatePath(
|
||||||
certConfig.getWechatPayCertPath(certConfig.getWechatPay().getDev().getWechatpayCertFile()));
|
certConfig.getWechatPayCertPath(certConfig.getWechatPay().getDev().getWechatpayCertFile()));
|
||||||
} else {
|
} else {
|
||||||
// 生产环境配置 - 从上传目录加载
|
// 生产环境配置 - 从容器证书目录加载
|
||||||
final String uploadPath = config.getUploadPath();
|
final String certRootPath = certConfig.getCertRootPath(); // /www/wwwroot/file.ws
|
||||||
privateKey = certificateLoader.loadCertificatePath(
|
privateKey = certificateLoader.loadCertificatePath(
|
||||||
uploadPath.concat("file").concat(payment.getApiclientKey()));
|
certRootPath + payment.getApiclientKey());
|
||||||
apiclientCert = certificateLoader.loadCertificatePath(
|
apiclientCert = certificateLoader.loadCertificatePath(
|
||||||
uploadPath.concat("file").concat(payment.getApiclientCert()));
|
certRootPath + payment.getApiclientCert());
|
||||||
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) {
|
if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) {
|
||||||
pubKey = certificateLoader.loadCertificatePath(
|
pubKey = certificateLoader.loadCertificatePath(
|
||||||
uploadPath.concat("file").concat(payment.getPubKey()));
|
certRootPath + payment.getPubKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# 服务器配置
|
# 服务器配置
|
||||||
server:
|
server:
|
||||||
port: 9202
|
port: 9200
|
||||||
|
|
||||||
# 数据源配置
|
# 数据源配置
|
||||||
spring:
|
spring:
|
||||||
|
|||||||
@@ -57,4 +57,12 @@ config:
|
|||||||
# 生产环境证书配置
|
# 生产环境证书配置
|
||||||
certificate:
|
certificate:
|
||||||
load-mode: VOLUME # 生产环境从Docker挂载卷加载
|
load-mode: VOLUME # 生产环境从Docker挂载卷加载
|
||||||
cert-root-path: /app/certs
|
cert-root-path: /www/wwwroot/file.ws
|
||||||
|
|
||||||
|
# 支付配置缓存
|
||||||
|
payment:
|
||||||
|
cache:
|
||||||
|
# 支付配置缓存键前缀,生产环境使用 Payment:1* 格式
|
||||||
|
key-prefix: "Payment:1"
|
||||||
|
# 缓存过期时间(小时)
|
||||||
|
expire-hours: 24
|
||||||
|
|||||||
Reference in New Issue
Block a user