mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-03 19:16:21 +00:00
feat 支付对账文件解析
This commit is contained in:
@@ -2,8 +2,8 @@ package cn.bootx.platform.daxpay.admin.controller.system;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.Res;
|
||||
import cn.bootx.platform.common.core.rest.ResResult;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.service.PayChannelInfoService;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.payinfo.PayChannelInfoDto;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.service.PayChannelConfigService;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.config.PayChannelConfigDto;
|
||||
import cn.bootx.platform.daxpay.service.param.system.payinfo.PayChannelInfoParam;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -19,28 +19,28 @@ import java.util.List;
|
||||
*/
|
||||
@Tag(name = "支付通道信息")
|
||||
@RestController
|
||||
@RequestMapping("/pay/channel/info")
|
||||
@RequestMapping("/pay/channel/config")
|
||||
@RequiredArgsConstructor
|
||||
public class PayChannelInfoController {
|
||||
private final PayChannelInfoService payChannelInfoService;
|
||||
public class PayChannelConfigController {
|
||||
private final PayChannelConfigService payChannelConfigService;
|
||||
|
||||
@Operation(summary = "查询全部")
|
||||
@GetMapping("/findAll")
|
||||
public ResResult<List<PayChannelInfoDto>> findAll(){
|
||||
List<PayChannelInfoDto> all = payChannelInfoService.findAll();
|
||||
public ResResult<List<PayChannelConfigDto>> findAll(){
|
||||
List<PayChannelConfigDto> all = payChannelConfigService.findAll();
|
||||
return Res.ok(all);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据ID获取")
|
||||
@GetMapping("/findById")
|
||||
public ResResult<PayChannelInfoDto> findById(Long id){
|
||||
return Res.ok(payChannelInfoService.findById(id));
|
||||
public ResResult<PayChannelConfigDto> findById(Long id){
|
||||
return Res.ok(payChannelConfigService.findById(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新")
|
||||
@PostMapping("/update")
|
||||
public ResResult<Void> update(@RequestBody PayChannelInfoParam param){
|
||||
payChannelInfoService.update(param);
|
||||
payChannelConfigService.update(param);
|
||||
return Res.ok();
|
||||
}
|
||||
}
|
@@ -19,12 +19,13 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 包括支付成功/退款/转账等一系列类型的回调处理
|
||||
* @author xxm
|
||||
* @since 2021/2/27
|
||||
*/
|
||||
@IgnoreAuth
|
||||
@Slf4j
|
||||
@Tag(name = "支付回调")
|
||||
@Tag(name = "支付通道信息回调")
|
||||
@RestController
|
||||
@RequestMapping("/pay/callback")
|
||||
@AllArgsConstructor
|
||||
@@ -35,21 +36,20 @@ public class PayCallbackController {
|
||||
private final WeChatPayCallbackService weChatPayCallbackService;
|
||||
|
||||
@SneakyThrows
|
||||
@Operation(summary = "支付宝回调")
|
||||
@Operation(summary = "支付宝信息回调")
|
||||
@PostMapping("/alipay")
|
||||
public String aliPay(HttpServletRequest request) {
|
||||
public String aliPayNotify(HttpServletRequest request) {
|
||||
|
||||
Map<String, String> stringStringMap = AliPayApi.toMap(request);
|
||||
return aliPayCallbackService.payCallback(stringStringMap);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Operation(summary = "微信支付回调")
|
||||
@Operation(summary = "微信支付信息回调")
|
||||
@PostMapping("/wechat")
|
||||
public String wechat(HttpServletRequest request) {
|
||||
public String wechatPayNotify(HttpServletRequest request) {
|
||||
String xmlMsg = HttpKit.readData(request);
|
||||
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
|
||||
return weChatPayCallbackService.payCallback(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -73,7 +73,8 @@ public class TestController {
|
||||
@Operation(summary = "下载支付宝对账单")
|
||||
@GetMapping("/aliDownReconcile")
|
||||
public ResResult<String> aliDownReconcile(String date){
|
||||
return Res.ok(alipayReconcileService.downAndSave(date));
|
||||
alipayReconcileService.downAndSave(date);
|
||||
return Res.ok();
|
||||
}
|
||||
@Operation(summary = "下载微信对账单")
|
||||
@GetMapping("/wxDownReconcile")
|
||||
|
@@ -36,6 +36,9 @@ public interface WeChatPayCode {
|
||||
/** 返回错误代码(例如付款码返回的支付中状态就在这里面) */
|
||||
String ERR_CODE = "err_code";
|
||||
|
||||
/** 返回错误代码(如对账错误) */
|
||||
String ERROR_CODE = "error_code";
|
||||
|
||||
/** 返回错误信息 */
|
||||
String ERR_CODE_DES = "err_code_des";
|
||||
|
||||
@@ -97,7 +100,7 @@ public interface WeChatPayCode {
|
||||
/** 订单总退款次数 */
|
||||
String TOTAL_REFUND_COUNT = "total_refund_count";
|
||||
|
||||
/** */
|
||||
String account_type_basic = "Basic";
|
||||
/** 资金账单 - 基本账户 */
|
||||
String ACCOUNT_TYPE_BASIC = "Basic";
|
||||
|
||||
}
|
||||
|
@@ -1,12 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付宝对账单
|
||||
* @author xxm
|
||||
* @since 2024/1/17
|
||||
*/
|
||||
@Data
|
||||
public class AliPayReconcileBill {
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.domain;
|
||||
|
||||
import cn.hutool.core.annotation.Alias;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付宝业务明细对账单
|
||||
* @author xxm
|
||||
* @since 2024/1/18
|
||||
*/
|
||||
@Data
|
||||
public class AliReconcileBillDetail {
|
||||
@Alias("支付宝交易号")
|
||||
private String tradeNo;
|
||||
@Alias("商户订单号")
|
||||
private String outTradeNo;
|
||||
@Alias("业务类型")
|
||||
private String tradeType;
|
||||
@Alias("商品名称")
|
||||
private String subject;
|
||||
@Alias("完成时间")
|
||||
private String endTime;
|
||||
@Alias("门店编号")
|
||||
private String storeId;
|
||||
@Alias("门店名称")
|
||||
private String storeName;
|
||||
@Alias("操作员")
|
||||
private String operator;
|
||||
@Alias("终端号")
|
||||
private String terminalId;
|
||||
@Alias("对方账户")
|
||||
private String otherAccount;
|
||||
@Alias("订单金额(元)")
|
||||
private String orderAmount;
|
||||
@Alias("商家实收(元)")
|
||||
private String realAmount;
|
||||
@Alias("支付宝红包(元)")
|
||||
private String alipayAmount;
|
||||
@Alias("集分宝(元)")
|
||||
private String jfbAmount;
|
||||
@Alias("支付宝优惠(元)")
|
||||
private String alipayDiscountAmount;
|
||||
@Alias("商家优惠(元)")
|
||||
private String discountAmount;
|
||||
@Alias("券核销金额(元)")
|
||||
private String couponDiscountAmount;
|
||||
@Alias("券名称")
|
||||
private String couponName;
|
||||
@Alias("商家红包消费金额(元)")
|
||||
private String couponAmount;
|
||||
@Alias("卡消费金额(元)")
|
||||
private String cardAmount;
|
||||
@Alias("退款批次号/请求号")
|
||||
private String batchNo;
|
||||
@Alias("服务费(元)")
|
||||
private String serviceAmount;
|
||||
@Alias("分润(元)")
|
||||
private String splitAmount;
|
||||
@Alias("备注")
|
||||
private String remark;
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.domain;
|
||||
|
||||
import cn.hutool.core.annotation.Alias;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付宝业务汇总对账单
|
||||
* @author xxm
|
||||
* @since 2024/1/17
|
||||
*/
|
||||
@Data
|
||||
public class AliReconcileBillTotal {
|
||||
@Alias("门店编号")
|
||||
private String storeId;
|
||||
@Alias("门店名称")
|
||||
private String storeName;
|
||||
@Alias("交易订单总笔数")
|
||||
private String totalNum;
|
||||
@Alias("退款订单总笔数")
|
||||
private String totalRefundNum;
|
||||
@Alias("订单金额(元)")
|
||||
private String totalOrderAmount;
|
||||
@Alias("商家实收(元)")
|
||||
private String totalAmount;
|
||||
@Alias("支付宝优惠(元)")
|
||||
private String totalDiscountAmount;
|
||||
@Alias("商家优惠(元)")
|
||||
private String totalCouponAmount;
|
||||
// 卡消费金额(元) 服务费(元) 分润(元) 实收净额(元)
|
||||
@Alias("卡消费金额(元)")
|
||||
private String totalConsumeAmount;
|
||||
@Alias("服务费(元)")
|
||||
private String totalServiceAmount;
|
||||
@Alias("分润(元)")
|
||||
private String totalShareAmount;
|
||||
@Alias("实收净额(元)")
|
||||
private String totalNetAmount;
|
||||
}
|
@@ -8,7 +8,7 @@ import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayWay;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliPayConfigManager;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.service.PayChannelInfoService;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.service.PayChannelConfigService;
|
||||
import cn.bootx.platform.daxpay.service.param.channel.alipay.AliPayConfigParam;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
@@ -38,7 +38,7 @@ public class AliPayConfigService {
|
||||
/** 默认支付宝配置的主键ID */
|
||||
private final static Long ID = 0L;
|
||||
private final AliPayConfigManager alipayConfigManager;
|
||||
private final PayChannelInfoService payChannelInfoService;
|
||||
private final PayChannelConfigService payChannelConfigService;
|
||||
|
||||
/**
|
||||
* 修改
|
||||
@@ -48,7 +48,7 @@ public class AliPayConfigService {
|
||||
AliPayConfig alipayConfig = alipayConfigManager.findById(ID).orElseThrow(() -> new DataNotExistException("支付宝配置不存在"));
|
||||
// 启用或停用
|
||||
if (!Objects.equals(param.getEnable(), alipayConfig.getEnable())){
|
||||
payChannelInfoService.setEnable(PayChannelEnum.ALI.getCode(), param.getEnable());
|
||||
payChannelConfigService.setEnable(PayChannelEnum.ALI.getCode(), param.getEnable());
|
||||
}
|
||||
|
||||
BeanUtil.copyProperties(param, alipayConfig, CopyOptions.create().ignoreNullValue());
|
||||
|
@@ -1,6 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.domain.AliReconcileBillDetail;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.domain.AliReconcileBillTotal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.csv.CsvReader;
|
||||
import cn.hutool.core.text.csv.CsvUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel;
|
||||
@@ -8,6 +16,7 @@ import com.ijpay.alipay.AliPayApi;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -17,6 +26,8 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 支付宝对账服务
|
||||
@@ -27,36 +38,80 @@ import java.util.List;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AlipayReconcileService {
|
||||
private final AliPayConfigService configService;
|
||||
|
||||
/**
|
||||
* 下载对账单, 并进行解析进行保存
|
||||
* @param date 对账日期 yyyy-MM-dd 格式
|
||||
*/
|
||||
@SneakyThrows
|
||||
public String downAndSave(String date){
|
||||
public void downAndSave(String date){
|
||||
AliPayConfig config = configService.getConfig();
|
||||
configService.initConfig(config);
|
||||
|
||||
try {
|
||||
AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
|
||||
model.setBillDate(date);
|
||||
model.setBillType("trade");
|
||||
val response = AliPayApi.billDownloadUrlQueryToResponse(model);
|
||||
// 判断返回结果
|
||||
if (!Objects.equals(AliPayCode.SUCCESS, response.getCode())) {
|
||||
log.error("获取支付宝对账单失败: {}", response.getSubMsg());
|
||||
throw new PayFailureException(response.getSubMsg());
|
||||
}
|
||||
|
||||
// 获取对账单下载地址并下载
|
||||
String url = AliPayApi.billDownloadUrlQuery(model);
|
||||
String url = response.getBillDownloadUrl();
|
||||
byte[] bytes = HttpUtil.downloadBytes(url);
|
||||
// 使用 Apache commons-compress 包装流,
|
||||
ZipArchiveInputStream zipArchiveInputStream = new ZipArchiveInputStream(new ByteArrayInputStream(bytes),"GBK");
|
||||
|
||||
ZipArchiveEntry entry;
|
||||
List<AliReconcileBillDetail> billDetails;
|
||||
List<AliReconcileBillTotal> billTotals;
|
||||
while ((entry= zipArchiveInputStream.getNextZipEntry()) != null){
|
||||
String name = entry.getName();
|
||||
System.out.println(name);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(zipArchiveInputStream,"GBK"));
|
||||
List<String> strings = IoUtil.readLines(bufferedReader, new ArrayList<>());
|
||||
strings.forEach(System.out::println);
|
||||
|
||||
String name = entry.getName();
|
||||
if (StrUtil.endWith(name,"_业务明细(汇总).csv")){
|
||||
billTotals = this.parseTotal(strings);
|
||||
} else {
|
||||
billDetails = this.parseDetail(strings);
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
// 保存
|
||||
System.out.println();
|
||||
} catch (AlipayApiException e) {
|
||||
log.error("下载对账单失败",e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析明细
|
||||
*/
|
||||
public List<AliReconcileBillDetail> parseDetail(List<String> list){
|
||||
// 去除前 4 行和后 2 行 然后合并是个一个字符串
|
||||
String billDetail = list.subList(4, list.size() - 2)
|
||||
.stream()
|
||||
.collect(Collectors.joining(System.lineSeparator()));
|
||||
billDetail = billDetail.replaceAll("\t", "");
|
||||
CsvReader reader = CsvUtil.getReader();
|
||||
List<AliReconcileBillDetail> billDetails = reader.read(billDetail, AliReconcileBillDetail.class);
|
||||
return billDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析汇总
|
||||
*/
|
||||
public List<AliReconcileBillTotal> parseTotal(List<String> list){
|
||||
// 去除前 4 行和后 2 行 然后合并是个一个字符串
|
||||
String billTotal = list.subList(4, list.size() - 2)
|
||||
.stream()
|
||||
.collect(Collectors.joining(System.lineSeparator()));
|
||||
billTotal = billTotal.replaceAll("\t", "");
|
||||
CsvReader reader = CsvUtil.getReader();
|
||||
List<AliReconcileBillTotal> billTotals = reader.read(billTotal, AliReconcileBillTotal.class);
|
||||
return billTotals;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import lombok.Data;
|
||||
* @since 2024/1/17
|
||||
*/
|
||||
@Data
|
||||
public class WechatPayReconcileBillDetail {
|
||||
public class WxReconcileBillDetail {
|
||||
@Alias("交易时间")
|
||||
private String transactionTime;
|
||||
|
||||
@@ -95,6 +95,4 @@ public class WechatPayReconcileBillDetail {
|
||||
@Alias("费率备注")
|
||||
private String packet8;
|
||||
|
||||
|
||||
|
||||
}
|
@@ -9,7 +9,7 @@ import lombok.Data;
|
||||
* @since 2024/1/17
|
||||
*/
|
||||
@Data
|
||||
public class WechatPayReconcileBillTotal {
|
||||
public class WxReconcileBillTotal {
|
||||
|
||||
@Alias("总交易单数")
|
||||
private String totalNum;
|
@@ -0,0 +1,35 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.wechat.domain;
|
||||
|
||||
import cn.hutool.core.annotation.Alias;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 微信资金账单明细
|
||||
* @author xxm
|
||||
* @since 2024/1/18
|
||||
*/
|
||||
@Data
|
||||
public class WxReconcileFundFlowDetail {
|
||||
@Alias("记账时间")
|
||||
private String time;
|
||||
@Alias("微信支付业务单号")
|
||||
private String outTradeNo;
|
||||
@Alias("资金流水单号")
|
||||
private String id;
|
||||
@Alias("业务名称")
|
||||
private String packet1;
|
||||
@Alias("业务类型")
|
||||
private String packet2;
|
||||
@Alias("收支类型")
|
||||
private String packet3;
|
||||
@Alias("收支金额(元)")
|
||||
private String amount;
|
||||
@Alias("账户结余(元)")
|
||||
private String balance;
|
||||
@Alias("资金变更提交申请人")
|
||||
private String packet4;
|
||||
@Alias("备注")
|
||||
private String packet5;
|
||||
@Alias("业务凭证号")
|
||||
private String packet6;
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.wechat.domain;
|
||||
|
||||
import cn.hutool.core.annotation.Alias;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 微信资金账单汇总
|
||||
* @author xxm
|
||||
* @since 2024/1/18
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class WxReconcileFundFlowTotal {
|
||||
|
||||
// 资金流水总笔数,收入笔数,收入金额,支出笔数,支出金额
|
||||
@Alias("资金流水总笔数")
|
||||
private String totalNum;
|
||||
@Alias("收入笔数")
|
||||
private String incomeNum;
|
||||
@Alias("收入金额")
|
||||
private String incomeAmount;
|
||||
@Alias("支出笔数")
|
||||
private String expenditureNum;
|
||||
@Alias("支出金额")
|
||||
private String expenditureAmount;
|
||||
}
|
@@ -7,7 +7,7 @@ import cn.bootx.platform.daxpay.service.code.WeChatPayWay;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.dao.WeChatPayConfigManager;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.service.PayChannelInfoService;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.service.PayChannelConfigService;
|
||||
import cn.bootx.platform.daxpay.service.param.channel.wechat.WeChatPayConfigParam;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
@@ -33,7 +33,7 @@ public class WeChatPayConfigService {
|
||||
/** 默认微信支付配置的主键ID */
|
||||
private final static Long ID = 0L;
|
||||
private final WeChatPayConfigManager weChatPayConfigManager;
|
||||
private final PayChannelInfoService payChannelInfoService;
|
||||
private final PayChannelConfigService payChannelConfigService;
|
||||
|
||||
/**
|
||||
* 修改
|
||||
@@ -43,7 +43,7 @@ public class WeChatPayConfigService {
|
||||
WeChatPayConfig weChatPayConfig = weChatPayConfigManager.findById(ID).orElseThrow(() -> new PayFailureException("微信支付配置不存在"));
|
||||
// 启用或停用
|
||||
if (!Objects.equals(param.getEnable(), weChatPayConfig.getEnable())){
|
||||
payChannelInfoService.setEnable(PayChannelEnum.WECHAT.getCode(), param.getEnable());
|
||||
payChannelConfigService.setEnable(PayChannelEnum.WECHAT.getCode(), param.getEnable());
|
||||
}
|
||||
BeanUtil.copyProperties(param, weChatPayConfig, CopyOptions.create().ignoreNullValue());
|
||||
weChatPayConfigManager.updateById(weChatPayConfig);
|
||||
|
@@ -41,7 +41,6 @@ public class WeChatPayOrderService {
|
||||
* 支付调起成功 更新payment中异步支付类型信息, 如果支付完成, 创建微信支付单
|
||||
*/
|
||||
public void updatePaySuccess(PayOrder payOrder, PayChannelParam payChannelParam) {
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();;
|
||||
payOrder.setAsyncPay(true).setAsyncChannel(PayChannelEnum.WECHAT.getCode());
|
||||
|
||||
payOrderChannelService.updateChannel(payChannelParam,payOrder);
|
||||
|
@@ -1,7 +1,10 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.domain.WechatPayReconcileBillDetail;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.domain.WechatPayReconcileBillTotal;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.service.code.WeChatPayCode;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.domain.WxReconcileBillDetail;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.domain.WxReconcileBillTotal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.domain.WxReconcileFundFlowDetail;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.text.csv.CsvReader;
|
||||
@@ -19,6 +22,9 @@ import org.springframework.stereotype.Service;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.ACCOUNT_TYPE_BASIC;
|
||||
|
||||
/**
|
||||
* 微信支付对账
|
||||
@@ -33,7 +39,7 @@ public class WechatPayReconcileService {
|
||||
|
||||
/**
|
||||
* 下载对账单并保存
|
||||
* @param date 下载日期
|
||||
* @param date 对账日期 yyyyMMdd 格式
|
||||
*/
|
||||
public void downAndSave(String date, WeChatPayConfig config) {
|
||||
config = weChatPayConfigService.getConfig();
|
||||
@@ -43,6 +49,7 @@ public class WechatPayReconcileService {
|
||||
|
||||
/**
|
||||
* 下载交易账单
|
||||
* @param date 对账日期 yyyyMMdd 格式
|
||||
*/
|
||||
public void downBill(String date, WeChatPayConfig config){
|
||||
// 下载交易账单
|
||||
@@ -54,18 +61,32 @@ public class WechatPayReconcileService {
|
||||
.bill_type("ALL")
|
||||
.build()
|
||||
.createSign(config.getApiKeyV2(), SignType.HMACSHA256);
|
||||
String res = WxPayApi.downloadBill(config.isSandbox(), params);
|
||||
String result = WxPayApi.downloadBill(config.isSandbox(), params);
|
||||
|
||||
// 验证返回数据是否成功
|
||||
this.verifyBillMsg(result);
|
||||
|
||||
// 过滤特殊字符
|
||||
result = result.replaceAll("`", "").replaceAll("\uFEFF", "");
|
||||
CsvReader reader = CsvUtil.getReader();
|
||||
|
||||
// 获取交易记录
|
||||
String billDetail = StrUtil.subBefore(result, "总交易单数", false);
|
||||
List<WxReconcileBillDetail> billDetails = reader.read(billDetail, WxReconcileBillDetail.class);
|
||||
|
||||
// 获取汇总数据
|
||||
System.out.println(res);
|
||||
CsvReader reader = CsvUtil.getReader();
|
||||
List<WechatPayReconcileBillDetail> read = reader.read(res, WechatPayReconcileBillDetail.class);
|
||||
String billTotal = result.substring(result.indexOf("总交易单数"));
|
||||
List<WxReconcileBillTotal> billTotals = reader.read(billTotal, WxReconcileBillTotal.class);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载资金账单, 需要双向证书
|
||||
* 下载资金账单, 需要双向证书,
|
||||
* 如果出现 No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
|
||||
* 更换一下最新的JDK即可, 例如 corretto Jdk
|
||||
*
|
||||
* @param date 对账日期 yyyyMMdd 格式
|
||||
*/
|
||||
public void downFundFlow(String date, WeChatPayConfig config){
|
||||
if (StrUtil.isBlank(config.getP12())){
|
||||
@@ -76,32 +97,83 @@ public class WechatPayReconcileService {
|
||||
.appid(config.getWxAppId())
|
||||
.nonce_str(WxPayKit.generateStr())
|
||||
.bill_date(date)
|
||||
.account_type("Basic")
|
||||
.account_type(ACCOUNT_TYPE_BASIC)
|
||||
.build()
|
||||
.createSign(config.getApiKeyV2(), SignType.HMACSHA256);
|
||||
byte[] fileBytes = Base64.decode(config.getP12());
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(fileBytes);
|
||||
// 证书密码为 微信商户号
|
||||
String s = WxPayApi.downloadFundFlow(fundFlow, inputStream, config.getWxMchId());
|
||||
// String url = WxPayApi.getReqUrl(PayApiEnum.DOWNLOAD_BILL, null, config.isSandbox());
|
||||
// String post = HttpUtil.post(url, WxPayKit.toXml(fundFlow));
|
||||
System.out.println(s);
|
||||
}
|
||||
String result = WxPayApi.downloadFundFlow(fundFlow, inputStream, config.getWxMchId());
|
||||
|
||||
// 验证返回数据是否成功
|
||||
this.verifyFundFlowMsg(result);
|
||||
|
||||
public static void main(String[] args){
|
||||
String s = "\uFEFF交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注\n" +
|
||||
"`2024-01-16 22:43:59,`wx9dfe38480f030e85,`1627859777,`0,`,`4200002086202401160745964084,`1747268229775183872,`o2RW45oGxo1Z8Fhcf6Oy9rMM7aT8,`NATIVE,`SUCCESS,`OTHERS,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`测试支付4,`,`0.00000,`0.90%,`0.02,`0.00,`\n" +
|
||||
"`2024-01-16 22:45:16,`wx9dfe38480f030e85,`1627859777,`0,`,`4200002086202401160745964084,`1747268229775183872,`o2RW45oGxo1Z8Fhcf6Oy9rMM7aT8,`NATIVE,`REFUND,`OTHERS,`CNY,`0.00,`0.00,`50303108562024011601487282563,`R1747268742516264960,`0.01,`0.00,`ORIGINAL,`SUCCESS,`测试支付4,`,`0.00000,`0.90%,`0.00,`0.01,`\n" +
|
||||
"`2024-01-16 23:10:18,`wx9dfe38480f030e85,`1627859777,`0,`,`4200002086202401160745964084,`1747268229775183872,`o2RW45oGxo1Z8Fhcf6Oy9rMM7aT8,`NATIVE,`REFUND,`OTHERS,`CNY,`0.00,`0.00,`50303108562024011683774350275,`R1747275041228390400,`0.01,`0.00,`ORIGINAL,`SUCCESS,`测试支付4,`,`0.00000,`0.90%,`0.00,`0.01,`\n" +
|
||||
"总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款总金额\n" +
|
||||
"`3,`0.02,`0.02,`0.00,`0.00000,`0.02,`0.02";
|
||||
s = s.replaceAll("`", "").replaceAll("\uFEFF", "");
|
||||
String s1 = StrUtil.subBefore(s, "总交易单数", false);
|
||||
String s2 = s.substring(s.indexOf("总交易单数"));
|
||||
// 过滤特殊字符
|
||||
result = result.replaceAll("`", "").replaceAll("\uFEFF", "");
|
||||
CsvReader reader = CsvUtil.getReader();
|
||||
List<WechatPayReconcileBillDetail> read = reader.read(s1, WechatPayReconcileBillDetail.class);
|
||||
List<WechatPayReconcileBillTotal> read1 = reader.read(s2, WechatPayReconcileBillTotal.class);
|
||||
|
||||
// 获取交易记录
|
||||
String billDetail = StrUtil.subBefore(result, "资金流水总笔数", false);
|
||||
List<WxReconcileFundFlowDetail> billDetails = reader.read(billDetail, WxReconcileFundFlowDetail.class);
|
||||
|
||||
// 获取汇总数据
|
||||
String billTotal = result.substring(result.indexOf("资金流水总笔数"));
|
||||
List<WxReconcileFundFlowDetail> billTotals = reader.read(billTotal, WxReconcileFundFlowDetail.class);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证交易对账单错误信息
|
||||
*/
|
||||
private void verifyBillMsg(String res) {
|
||||
// 判断是否能是对账单还是特殊数据
|
||||
if (StrUtil.startWith(res, "\uFEFF")){
|
||||
return;
|
||||
}
|
||||
|
||||
// 出现xml返回说明一定是错误了
|
||||
Map<String, String> result = WxPayKit.xmlToMap(res);
|
||||
|
||||
// 返回码
|
||||
String errCode = result.get(WeChatPayCode.ERROR_CODE);
|
||||
// 原因
|
||||
String resultMsg = result.get(WeChatPayCode.RETURN_MSG);
|
||||
|
||||
// 处理20002 分别是 账单不存在 账单未生成
|
||||
if (Objects.equals(errCode, "20002")){
|
||||
if (Objects.equals("No Bill Exist",resultMsg)){
|
||||
log.warn("交易账单不存在, 请检查当前商户号在指定日期内是否有成功的交易");
|
||||
throw new PayFailureException("交易账单不存在");
|
||||
}
|
||||
if (Objects.equals("Bill Creating",resultMsg)){
|
||||
log.warn("交易账单未生成, 请在上午10点以后再试");
|
||||
throw new PayFailureException("交易账单未生成, 请在上午10点以后再试");
|
||||
}
|
||||
|
||||
} else {
|
||||
log.error("微信交易对账失败, 原因: {}, 错误码: {}, 错误信息: {}", resultMsg, errCode, res);
|
||||
throw new PayFailureException("微信支付交易对账失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证资金对账单
|
||||
*/
|
||||
private void verifyFundFlowMsg(String res) {
|
||||
// 判断是否能是对账单还是特殊数据
|
||||
if (StrUtil.startWith(res, "\uFEFF")){
|
||||
return;
|
||||
}
|
||||
// 出现xml返回说明一定是错误了
|
||||
Map<String, String> result = WxPayKit.xmlToMap(res);
|
||||
String returnCode = result.get(WeChatPayCode.RETURN_CODE);
|
||||
String errorMsg = result.get(WeChatPayCode.ERR_CODE_DES);
|
||||
if (StrUtil.isBlank(errorMsg)) {
|
||||
errorMsg = result.get(WeChatPayCode.RETURN_MSG);
|
||||
}
|
||||
log.error("微信资金对账失败, 原因: {}, 错误码: {}, 错误信息: {}", errorMsg, returnCode, res);
|
||||
throw new PayFailureException("微信资金对账失败: " + errorMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,21 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.reconcile.entity;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付对账单记录
|
||||
* @author xxm
|
||||
* @since 2024/1/18
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "支付对账单记录")
|
||||
@TableName("pay_reconcile_record")
|
||||
public class PayReconcileRecord extends MpCreateEntity {
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.config.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.entity.PayChannelConfig;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.config.PayChannelConfigDto;
|
||||
import cn.bootx.platform.daxpay.service.param.system.payinfo.PayChannelInfoParam;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/8
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayChannelConfigConvert {
|
||||
PayChannelConfigConvert CONVERT = Mappers.getMapper(PayChannelConfigConvert.class);
|
||||
|
||||
PayChannelConfig convert(PayChannelInfoParam in);
|
||||
|
||||
PayChannelConfigDto convert(PayChannelConfig in);
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.payinfo.dao;
|
||||
package cn.bootx.platform.daxpay.service.core.system.config.dao;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.entity.PayChannelInfo;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.entity.PayChannelConfig;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -18,20 +18,20 @@ import java.util.Optional;
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class PayChannelInfoManager extends BaseManager<PayChannelInfoMapper, PayChannelInfo> {
|
||||
public class PayChannelConfigManager extends BaseManager<PayChannelConfigMapper, PayChannelConfig> {
|
||||
|
||||
/**
|
||||
* 根据code查询
|
||||
*/
|
||||
public Optional<PayChannelInfo> findByCode(String code){
|
||||
return findByField(PayChannelInfo::getCode, code);
|
||||
public Optional<PayChannelConfig> findByCode(String code){
|
||||
return findByField(PayChannelConfig::getCode, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全部
|
||||
*/
|
||||
@Override
|
||||
public List<PayChannelInfo> findAll() {
|
||||
public List<PayChannelConfig> findAll() {
|
||||
return lambdaQuery().orderByAsc(MpIdEntity::getId).list();
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.config.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.entity.PayChannelConfig;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/8
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayChannelConfigMapper extends BaseMapper<PayChannelConfig> {
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.payinfo.entity;
|
||||
package cn.bootx.platform.daxpay.service.core.system.config.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.convert.PayChannelInfoConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.payinfo.PayChannelInfoDto;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.convert.PayChannelConfigConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.config.PayChannelConfigDto;
|
||||
import cn.bootx.platform.daxpay.service.param.system.payinfo.PayChannelInfoParam;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
@@ -15,17 +15,17 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付通道
|
||||
* 都是在代码中定义好的,界面上只做展示和部分信息的修改用,不可以进行增删相关的操作
|
||||
* 支付通道配置
|
||||
* 有哪些通道都是在代码中定义好的,界面上只做展示和部分信息的修改用,不可以进行增删相关的操作
|
||||
* @author xxm
|
||||
* @since 2024/1/8
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "支付通道信息")
|
||||
@TableName("pay_channel_info")
|
||||
public class PayChannelInfo extends MpBaseEntity implements EntityBaseFunction<PayChannelInfoDto> {
|
||||
@DbTable(comment = "支付通道配置")
|
||||
@TableName("pay_channel_config")
|
||||
public class PayChannelConfig extends MpBaseEntity implements EntityBaseFunction<PayChannelConfigDto> {
|
||||
|
||||
/** 需要与系统中配置的枚举一致 */
|
||||
@DbColumn(comment = "代码")
|
||||
@@ -37,8 +37,8 @@ public class PayChannelInfo extends MpBaseEntity implements EntityBaseFunction<P
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String name;
|
||||
|
||||
/** logo图片 */
|
||||
@DbColumn(comment = "ICON")
|
||||
/** ICON图片 */
|
||||
@DbColumn(comment = "ICON图片")
|
||||
private Long iconId;
|
||||
|
||||
/** 卡牌背景色 */
|
||||
@@ -47,22 +47,22 @@ public class PayChannelInfo extends MpBaseEntity implements EntityBaseFunction<P
|
||||
|
||||
/** 是否启用 */
|
||||
@DbColumn(comment = "是否启用")
|
||||
private Boolean enabled;
|
||||
private Boolean enable;
|
||||
|
||||
/** 备注 */
|
||||
@DbColumn(comment = "备注")
|
||||
private String remark;
|
||||
|
||||
public static PayChannelInfo init(PayChannelInfoParam in){
|
||||
return PayChannelInfoConvert.CONVERT.convert(in);
|
||||
public static PayChannelConfig init(PayChannelInfoParam in){
|
||||
return PayChannelConfigConvert.CONVERT.convert(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
@Override
|
||||
public PayChannelInfoDto toDto() {
|
||||
return PayChannelInfoConvert.CONVERT.convert(this);
|
||||
public PayChannelConfigDto toDto() {
|
||||
return PayChannelConfigConvert.CONVERT.convert(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.payinfo.service;
|
||||
package cn.bootx.platform.daxpay.service.core.system.config.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.dao.PayChannelInfoManager;
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.entity.PayChannelInfo;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.payinfo.PayChannelInfoDto;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.dao.PayChannelConfigManager;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.entity.PayChannelConfig;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.config.PayChannelConfigDto;
|
||||
import cn.bootx.platform.daxpay.service.param.system.payinfo.PayChannelInfoParam;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
@@ -22,32 +22,32 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PayChannelInfoService {
|
||||
private final PayChannelInfoManager manager;
|
||||
public class PayChannelConfigService {
|
||||
private final PayChannelConfigManager manager;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
public List<PayChannelInfoDto> findAll(){
|
||||
public List<PayChannelConfigDto> findAll(){
|
||||
return manager.findAll().stream()
|
||||
.map(PayChannelInfo::toDto)
|
||||
.map(PayChannelConfig::toDto)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 单条
|
||||
*/
|
||||
public PayChannelInfoDto findById(Long id){
|
||||
return manager.findById(id).map(PayChannelInfo::toDto).orElseThrow(DataNotExistException::new);
|
||||
public PayChannelConfigDto findById(Long id){
|
||||
return manager.findById(id).map(PayChannelConfig::toDto).orElseThrow(DataNotExistException::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否启用
|
||||
*/
|
||||
public void setEnable(String code,boolean enable){
|
||||
PayChannelInfo info = manager.findByCode(code)
|
||||
PayChannelConfig info = manager.findByCode(code)
|
||||
.orElseThrow(DataNotExistException::new);
|
||||
info.setEnabled(enable);
|
||||
info.setEnable(enable);
|
||||
manager.updateById(info);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class PayChannelInfoService {
|
||||
* 更新
|
||||
*/
|
||||
public void update(PayChannelInfoParam param){
|
||||
PayChannelInfo info = manager.findById(param.getId()).orElseThrow(DataNotExistException::new);
|
||||
PayChannelConfig info = manager.findById(param.getId()).orElseThrow(DataNotExistException::new);
|
||||
BeanUtil.copyProperties(param,info, CopyOptions.create().ignoreNullValue());
|
||||
manager.updateById(info);
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.payinfo.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.entity.PayChannelInfo;
|
||||
import cn.bootx.platform.daxpay.service.dto.system.payinfo.PayChannelInfoDto;
|
||||
import cn.bootx.platform.daxpay.service.param.system.payinfo.PayChannelInfoParam;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/8
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayChannelInfoConvert {
|
||||
PayChannelInfoConvert CONVERT = Mappers.getMapper(PayChannelInfoConvert.class);
|
||||
|
||||
PayChannelInfo convert(PayChannelInfoParam in);
|
||||
|
||||
PayChannelInfoDto convert(PayChannelInfo in);
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.system.payinfo.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.system.payinfo.entity.PayChannelInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/8
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayChannelInfoMapper extends BaseMapper<PayChannelInfo> {
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.system.payinfo;
|
||||
package cn.bootx.platform.daxpay.service.dto.system.config;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "支付通道信息")
|
||||
public class PayChannelInfoDto extends BaseDto {
|
||||
public class PayChannelConfigDto extends BaseDto {
|
||||
|
||||
/** 需要与系统中配置的枚举一致 */
|
||||
@Schema(description = "代码")
|
||||
@@ -28,7 +28,7 @@ public class PayChannelInfoDto extends BaseDto {
|
||||
|
||||
/** 是否启用 */
|
||||
@DbColumn(comment = "是否启用")
|
||||
private Boolean enabled;
|
||||
private Boolean enable;
|
||||
|
||||
/** logo图片 */
|
||||
@Schema(description = "logo图片")
|
Reference in New Issue
Block a user