v3.0.0 springboot3+jdk17版本

This commit is contained in:
hupeng committed 2024-06-01 16:29:28 +08:00
1 parent 3aa2c942dc
commit b3ee447f8e
3676 files changed
+64366 -370384

No files matched your search

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>yshop-module-pay-api</module>
<module>yshop-module-pay-biz</module>
</modules>
<artifactId>yshop-module-pay</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
pay 模块
</description>
</project>
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yshop-module-pay</artifactId>
<groupId>co.yixiang.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yshop-module-pay-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
pay 模块 API,暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-mq</artifactId>
</dependency>
<!-- 支付相关 -->
<dependency>
<groupId>com.egzosn</groupId>
<artifactId>pay-java-wx</artifactId>
</dependency>
<dependency>
<groupId>com.egzosn</groupId>
<artifactId>pay-java-ali</artifactId>
</dependency>
<dependency>
<groupId>com.egzosn</groupId>
<artifactId>pay-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.egzosn</groupId>
<artifactId>pay-java-web-support</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,61 @@
package co.yixiang.yshop.module.pay.config;
import co.yixiang.yshop.module.pay.config.handlers.AliPayMessageHandler;
import co.yixiang.yshop.module.pay.config.handlers.WxPayMessageHandler;
import com.egzosn.pay.spring.boot.core.PayServiceConfigurer;
import com.egzosn.pay.spring.boot.core.configurers.MerchantDetailsServiceConfigurer;
import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer;
import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform;
import com.egzosn.pay.spring.boot.core.provider.merchant.platform.AliPaymentPlatform;
import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms;
import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxPaymentPlatform;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import jakarta.annotation.Resource;
/**
* 支付服务配置
*
* @author hupeng
* @date 2023/7/15
*/
@Configuration
public class MerchantPayServiceConfigurer implements PayServiceConfigurer {
@Resource
private JdbcTemplate jdbcTemplate;
@Resource
private AliPayMessageHandler aliPayMessageHandler;
@Resource
private WxPayMessageHandler wxPayMessageHandler;
/**
* 商户配置
*
* @param merchants 商户配置
*/
@Override
public void configure(MerchantDetailsServiceConfigurer merchants) {
merchants.jdbc()
//是否开启缓存,默认不开启,这里开启缓存
.cache(false)
.template(jdbcTemplate);
}
/**
* 商户配置
*
* @param configurer 支付消息配置
*/
@Override
public void configure(PayMessageConfigurer configurer) {
PaymentPlatform aliPaymentPlatform = PaymentPlatforms.getPaymentPlatform(AliPaymentPlatform.PLATFORM_NAME);
PaymentPlatform wxPaymentPlatform = PaymentPlatforms.getPaymentPlatform(WxPaymentPlatform.PLATFORM_NAME);
configurer.addHandler(aliPaymentPlatform, aliPayMessageHandler);
configurer.addHandler(wxPaymentPlatform, wxPayMessageHandler);
//configurer.addInterceptor(wxPaymentPlatform, spring.getBean(AliPayMessageInterceptor.class));
}
}
@@ -0,0 +1,10 @@
package co.yixiang.yshop.module.pay.config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
//@Configuration
//@EnableAutoConfiguration
public class PayAutoConfiguration
{
}
@@ -0,0 +1,53 @@
package co.yixiang.yshop.module.pay.config.handlers;
import co.yixiang.yshop.module.pay.mq.producer.PayNoticeProducer;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliPayMessage;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
import java.util.Map;
/**
* 支付宝支付回调处理器
* @author hupeng
* @date 2023/7/15
*/
@Component
public class AliPayMessageHandler implements PayMessageHandler<AliPayMessage, AliPayService> {
@Resource
private PayNoticeProducer payNoticeProducer;
/**
* 处理支付回调消息的处理器接口
*
* @param payMessage 支付消息
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param payService 支付服务
* @return xml, text格式的消息,如果在异步规则里处理的话,可以返回null
* @throws PayErrorException 支付错误异常
*/
@Override
public PayOutMessage handle(AliPayMessage payMessage, Map<String, Object> context, AliPayService payService) throws PayErrorException {
Map<String, Object> message = payMessage.getPayMessage();
//交易状态
String trade_status = (String) message.get("trade_status");
//交易完成
if ("TRADE_SUCCESS".equals(trade_status) || "TRADE_FINISHED".equals(trade_status)) {
String orderId = (String) payMessage.getPayMessage().get("out_trade_no");
//消息队列处理
payNoticeProducer.sendPayNoticeMessage(orderId,"alipay");
return payService.getPayOutMessage("success", "成功");
}
return payService.getPayOutMessage("fail", "失败");
}
}
@@ -0,0 +1,43 @@
package co.yixiang.yshop.module.pay.config.handlers;
import co.yixiang.yshop.module.pay.mq.producer.PayNoticeProducer;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.wx.bean.WxPayMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
import java.util.Map;
/**
* 微信支付回调处理器
* @author hupeng
* @date 2023/7/15
*/
@Component
@Slf4j
public class WxPayMessageHandler implements PayMessageHandler<WxPayMessage, PayService> {
@Resource
private PayNoticeProducer payNoticeProducer;
@Override
public PayOutMessage handle(WxPayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
log.info("======pay notice ========");
//交易状态
if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))){
String orderId = (String)payMessage.getPayMessage().get("out_trade_no");
//消息队列处理
payNoticeProducer.sendPayNoticeMessage(orderId,"weixin");
return payService.getPayOutMessage("SUCCESS", "OK");
}
return payService.getPayOutMessage("FAIL", "失败");
}
}
@@ -0,0 +1,42 @@
package co.yixiang.yshop.module.pay.config.interceptor;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliPayMessage;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayMessageInterceptor;
import com.egzosn.pay.common.exception.PayErrorException;
import java.util.Map;
/**
* 支付宝回调信息拦截器
* @author hupeng
* @date 2023/7/15
*/
//使用 自己开启
//@Component
public class AliPayMessageInterceptor implements PayMessageInterceptor<AliPayMessage, AliPayService> {
/**
* 拦截支付消息
*
* @param payMessage 支付回调消息
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param payService 支付服务
* @return true代表OK,false代表不OK并直接中断对应的支付处理器
* @see PayMessageHandler 支付处理器
* @throws PayErrorException PayErrorException*
*/
@Override
public boolean intercept(AliPayMessage payMessage, Map<String, Object> context, AliPayService payService) throws PayErrorException {
//这里进行拦截器处理,自行实现
String outTradeNo = payMessage.getOutTradeNo();
// todo
return true;
}
}
@@ -0,0 +1,52 @@
package co.yixiang.yshop.module.pay.config.interceptor;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliPayMessage;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayMessageInterceptor;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.wx.api.WxPayService;
import com.egzosn.pay.wx.bean.WxPayMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 支付宝回调信息拦截器
* @author hupeng
* @date 2023/7/15
*/
//使用 自己开启
//@Component
public class WxPayMessageInterceptor implements PayMessageInterceptor<WxPayMessage, WxPayService> {
// /**
// * 拦截支付消息
// *
// * @param payMessage 支付回调消息
// * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
// * @param payService 支付服务
// * @return true代表OK,false代表不OK并直接中断对应的支付处理器
// * @see PayMessageHandler 支付处理器
// * @throws PayErrorException PayErrorException*
// */
// @Override
// public boolean intercept(AliPayMessage payMessage, Map<String, Object> context, AliPayService payService) throws PayErrorException {
//
// //这里进行拦截器处理,自行实现
// String outTradeNo = payMessage.getOutTradeNo();
// // todo
//
//
//
// return true;
// }
@Override
public boolean intercept(WxPayMessage wxPayMessage, Map<String, Object> map, WxPayService wxPayService) throws PayErrorException {
// wxPayService.
return false;
}
}
@@ -0,0 +1,8 @@
package co.yixiang.yshop.module.pay.enums;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
public interface ErrorCodeConstants {
ErrorCode MERCHANT_DETAILS_NOT_EXISTS = new ErrorCode(1008009000, "支付服务商配置不存在");
}
@@ -0,0 +1,24 @@
package co.yixiang.yshop.module.pay.mq.message;
import co.yixiang.yshop.framework.mq.redis.core.stream.AbstractRedisStreamMessage;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
@Data
public class PayNoticeMessage extends AbstractRedisStreamMessage {
/**
* 订单编号
*/
@NotNull(message = "订单编号编号不能为空")
private String orderId;
//支付类型
private String payType;
@Override
public String getStreamKey() {
return "order.pay.notice";
}
}
@@ -0,0 +1,24 @@
package co.yixiang.yshop.module.pay.mq.producer;
import co.yixiang.yshop.framework.mq.redis.core.RedisMQTemplate;
import co.yixiang.yshop.module.pay.mq.message.PayNoticeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
@Slf4j
@Component
public class PayNoticeProducer {
@Resource
private RedisMQTemplate redisMQTemplate;
/**
* 发送消息
* @param orderId 订单编号
*/
public void sendPayNoticeMessage(String orderId,String payType) {
PayNoticeMessage payNoticeMessage = new PayNoticeMessage().setOrderId(orderId).setPayType(payType);
redisMQTemplate.send(payNoticeMessage);
}
}
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yshop-module-pay</artifactId>
<groupId>co.yixiang.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yshop-module-pay-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
pay 模块,我们放支付业务,提供业务的支付能力。
例如说:商户、应用、支付、退款等等
</description>
<dependencies>
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-module-pay-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<!-- <dependency>-->
<!-- <groupId>co.yixiang.boot</groupId>-->
<!-- <artifactId>yshop-spring-boot-starter-biz-operatelog</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-security</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>co.yixiang.boot</groupId>-->
<!-- <artifactId>yshop-spring-boot-starter-desensitize</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-redis</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-mq</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,97 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import java.util.*;
import java.io.IOException;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.framework.common.pojo.CommonResult;
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
import co.yixiang.yshop.framework.excel.core.util.ExcelUtils;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
import co.yixiang.yshop.module.pay.convert.merchantdetails.MerchantDetailsConvert;
import co.yixiang.yshop.module.pay.service.merchantdetails.MerchantDetailsService;
@Tag(name = "管理后台 - 支付服务商配置")
@RestController
@RequestMapping("/pay/merchant-details")
@Validated
public class MerchantDetailsController {
@Resource
private MerchantDetailsService merchantDetailsService;
@PostMapping("/create")
@Operation(summary = "创建支付服务商配置")
@PreAuthorize("@ss.hasPermission('pay:merchant-details:create')")
public CommonResult<String> createMerchantDetails(@Valid @RequestBody MerchantDetailsCreateReqVO createReqVO) {
return success(merchantDetailsService.createMerchantDetails(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新支付服务商配置")
@PreAuthorize("@ss.hasPermission('pay:merchant-details:update')")
public CommonResult<Boolean> updateMerchantDetails(@Valid @RequestBody MerchantDetailsUpdateReqVO updateReqVO) {
merchantDetailsService.updateMerchantDetails(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除支付服务商配置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('pay:merchant-details:delete')")
public CommonResult<Boolean> deleteMerchantDetails(@RequestParam("id") String id) {
merchantDetailsService.deleteMerchantDetails(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得支付服务商配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('pay:merchant-details:query')")
public CommonResult<MerchantDetailsRespVO> getMerchantDetails(@RequestParam("id") String id) {
MerchantDetailsDO merchantDetails = merchantDetailsService.getMerchantDetails(id);
return success(MerchantDetailsConvert.INSTANCE.convert(merchantDetails));
}
@GetMapping("/list")
@Operation(summary = "获得支付服务商配置列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('pay:merchant-details:query')")
public CommonResult<List<MerchantDetailsRespVO>> getMerchantDetailsList(@RequestParam("ids") Collection<String> ids) {
List<MerchantDetailsDO> list = merchantDetailsService.getMerchantDetailsList(ids);
return success(MerchantDetailsConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得支付服务商配置分页")
@PreAuthorize("@ss.hasPermission('pay:merchant-details:query')")
public CommonResult<PageResult<MerchantDetailsRespVO>> getMerchantDetailsPage(@Valid MerchantDetailsPageReqVO pageVO) {
PageResult<MerchantDetailsDO> pageResult = merchantDetailsService.getMerchantDetailsPage(pageVO);
return success(MerchantDetailsConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出支付服务商配置 Excel")
@PreAuthorize("@ss.hasPermission('pay:merchant-details:export')")
public void exportMerchantDetailsExcel(@Valid MerchantDetailsExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<MerchantDetailsDO> list = merchantDetailsService.getMerchantDetailsList(exportReqVO);
// 导出 Excel
List<MerchantDetailsExcelVO> datas = MerchantDetailsConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "支付服务商配置.xls", "数据", MerchantDetailsExcelVO.class, datas);
}
}
@@ -0,0 +1,73 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import co.yixiang.yshop.framework.desensitize.core.slider.annotation.SliderDesensitize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import jakarta.validation.constraints.*;
/**
* 支付服务商配置 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class MerchantDetailsBaseVO {
private String detailsId;
@Schema(description = "支付类型(支付渠道) 详情查看com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform对应子类,aliPay 支付宝, wxPay微信..等等", required = true, example = "2")
@NotNull(message = "支付类型(支付渠道)等不能为空")
private String payType;
//@SliderDesensitize(prefixKeep=3 ,suffixKeep=4)
@Schema(description = "应用id", example = "1718")
private String appid;
@Schema(description = "商户id,商户号,合作伙伴id等等", example = "21574")
//@SliderDesensitize(prefixKeep=2 ,suffixKeep=2)
private String mchId;
@Schema(description = "当前面私钥公钥为证书类型的时候,这里必填,可选值:PATH,STR,INPUT_STREAM,CLASS_PATH,URL", example = "1")
private String certStoreType;
@Schema(description = "私钥或私钥证书")
//@SliderDesensitize(prefixKeep=4 ,suffixKeep=4)
private String keyPrivate;
@Schema(description = "公钥或公钥证书")
private String keyPublic;
@Schema(description = "key证书,附加证书使用,如SSL证书,或者银联根级证书方面")
private String keyCert;
@Schema(description = "私钥证书或key证书的密码")
private String keyCertPwd;
@Schema(description = "异步回调", example = "https://www.yixiang.co")
private String notifyUrl;
@Schema(description = "同步回调地址,大部分用于付款成功后页面转跳", example = "https://www.yixiang.co")
private String returnUrl;
@Schema(description = "签名方式,目前已实现多种签名方式详情查看com.egzosn.pay.common.util.sign.encrypt。MD5,RSA等等", required = true, example = "1")
@NotNull(message = "签名方式不能为空")
private String signType;
@Schema(description = "收款账号,暂时只有支付宝部分使用,可根据开发者自行使用")
private String seller;
@Schema(description = "子appid", example = "13761")
private String subAppId;
@Schema(description = "子商户id", example = "10127")
private String subMchId;
@Schema(description = "编码类型,大部分为utf-8", required = true)
//@NotNull(message = "编码类型,大部分为utf-8不能为空")
private String inputCharset;
@Schema(description = "是否为测试环境: 0 否,1 测试环境", required = true)
@NotNull(message = "是否为测试环境: 0 否,1 测试环境不能为空")
private Integer isTest;
}
@@ -0,0 +1,12 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "管理后台 - 支付服务商配置创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MerchantDetailsCreateReqVO extends MerchantDetailsBaseVO {
}
@@ -0,0 +1,66 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import lombok.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 支付服务商配置 Excel VO
*
* @author yshop
*/
@Data
public class MerchantDetailsExcelVO {
@ExcelProperty("列表id")
private String detailsId;
@ExcelProperty("支付类型(支付渠道) 详情查看com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform对应子类,aliPay 支付宝, wxPay微信..等等")
private String payType;
@ExcelProperty("应用id")
private String appid;
@ExcelProperty("商户id,商户号,合作伙伴id等等")
private String mchId;
@ExcelProperty("当前面私钥公钥为证书类型的时候,这里必填,可选值:PATH,STR,INPUT_STREAM,CLASS_PATH,URL")
private String certStoreType;
@ExcelProperty("私钥或私钥证书")
private String keyPrivate;
@ExcelProperty("公钥或公钥证书")
private String keyPublic;
@ExcelProperty("key证书,附加证书使用,如SSL证书,或者银联根级证书方面")
private String keyCert;
@ExcelProperty("私钥证书或key证书的密码")
private String keyCertPwd;
@ExcelProperty("异步回调")
private String notifyUrl;
@ExcelProperty("同步回调地址,大部分用于付款成功后页面转跳")
private String returnUrl;
@ExcelProperty("签名方式,目前已实现多种签名方式详情查看com.egzosn.pay.common.util.sign.encrypt。MD5,RSA等等")
private String signType;
@ExcelProperty("收款账号,暂时只有支付宝部分使用,可根据开发者自行使用")
private String seller;
@ExcelProperty("子appid")
private String subAppId;
@ExcelProperty("子商户id")
private String subMchId;
@ExcelProperty("编码类型,大部分为utf-8")
private String inputCharset;
@ExcelProperty("是否为测试环境: 0 否,1 测试环境")
private Integer isTest;
}
@@ -0,0 +1,58 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "管理后台 - 支付服务商配置 Excel 导出 Request VO,参数和 MerchantDetailsPageReqVO 是一致的")
@Data
public class MerchantDetailsExportReqVO {
@Schema(description = "支付类型(支付渠道) 详情查看com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform对应子类,aliPay 支付宝, wxPay微信..等等", example = "2")
private String payType;
@Schema(description = "应用id", example = "1718")
private String appid;
@Schema(description = "商户id,商户号,合作伙伴id等等", example = "21574")
private String mchId;
@Schema(description = "当前面私钥公钥为证书类型的时候,这里必填,可选值:PATH,STR,INPUT_STREAM,CLASS_PATH,URL", example = "1")
private String certStoreType;
@Schema(description = "私钥或私钥证书")
private String keyPrivate;
@Schema(description = "公钥或公钥证书")
private String keyPublic;
@Schema(description = "key证书,附加证书使用,如SSL证书,或者银联根级证书方面")
private String keyCert;
@Schema(description = "私钥证书或key证书的密码")
private String keyCertPwd;
@Schema(description = "异步回调", example = "https://www.yixiang.co")
private String notifyUrl;
@Schema(description = "同步回调地址,大部分用于付款成功后页面转跳", example = "https://www.yixiang.co")
private String returnUrl;
@Schema(description = "签名方式,目前已实现多种签名方式详情查看com.egzosn.pay.common.util.sign.encrypt。MD5,RSA等等", example = "1")
private String signType;
@Schema(description = "收款账号,暂时只有支付宝部分使用,可根据开发者自行使用")
private String seller;
@Schema(description = "子appid", example = "13761")
private String subAppId;
@Schema(description = "子商户id", example = "10127")
private String subMchId;
@Schema(description = "编码类型,大部分为utf-8")
private String inputCharset;
@Schema(description = "是否为测试环境: 0 否,1 测试环境")
private Boolean isTest;
}
@@ -0,0 +1,61 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import co.yixiang.yshop.framework.common.pojo.PageParam;
@Schema(description = "管理后台 - 支付服务商配置分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MerchantDetailsPageReqVO extends PageParam {
@Schema(description = "支付类型(支付渠道) 详情查看com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform对应子类,aliPay 支付宝, wxPay微信..等等", example = "2")
private String payType;
@Schema(description = "应用id", example = "1718")
private String appid;
@Schema(description = "商户id,商户号,合作伙伴id等等", example = "21574")
private String mchId;
@Schema(description = "当前面私钥公钥为证书类型的时候,这里必填,可选值:PATH,STR,INPUT_STREAM,CLASS_PATH,URL", example = "1")
private String certStoreType;
@Schema(description = "私钥或私钥证书")
private String keyPrivate;
@Schema(description = "公钥或公钥证书")
private String keyPublic;
@Schema(description = "key证书,附加证书使用,如SSL证书,或者银联根级证书方面")
private String keyCert;
@Schema(description = "私钥证书或key证书的密码")
private String keyCertPwd;
@Schema(description = "异步回调", example = "https://www.yixiang.co")
private String notifyUrl;
@Schema(description = "同步回调地址,大部分用于付款成功后页面转跳", example = "https://www.yixiang.co")
private String returnUrl;
@Schema(description = "签名方式,目前已实现多种签名方式详情查看com.egzosn.pay.common.util.sign.encrypt。MD5,RSA等等", example = "1")
private String signType;
@Schema(description = "收款账号,暂时只有支付宝部分使用,可根据开发者自行使用")
private String seller;
@Schema(description = "子appid", example = "13761")
private String subAppId;
@Schema(description = "子商户id", example = "10127")
private String subMchId;
@Schema(description = "编码类型,大部分为utf-8")
private String inputCharset;
@Schema(description = "是否为测试环境: 0 否,1 测试环境")
private Boolean isTest;
}
@@ -0,0 +1,15 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 支付服务商配置 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MerchantDetailsRespVO extends MerchantDetailsBaseVO {
@Schema(description = "列表id", required = true, example = "17552")
private String detailsId;
}
@@ -0,0 +1,18 @@
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import jakarta.validation.constraints.*;
@Schema(description = "管理后台 - 支付服务商配置更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MerchantDetailsUpdateReqVO extends MerchantDetailsBaseVO {
@Schema(description = "列表id", required = true, example = "17552")
@NotNull(message = "列表id不能为空")
private String detailsId;
}
@@ -0,0 +1,34 @@
package co.yixiang.yshop.module.pay.convert.merchantdetails;
import java.util.*;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
/**
* 支付服务商配置 Convert
*
* @author yshop
*/
@Mapper
public interface MerchantDetailsConvert {
MerchantDetailsConvert INSTANCE = Mappers.getMapper(MerchantDetailsConvert.class);
MerchantDetailsDO convert(MerchantDetailsCreateReqVO bean);
MerchantDetailsDO convert(MerchantDetailsUpdateReqVO bean);
MerchantDetailsRespVO convert(MerchantDetailsDO bean);
List<MerchantDetailsRespVO> convertList(List<MerchantDetailsDO> list);
PageResult<MerchantDetailsRespVO> convertPage(PageResult<MerchantDetailsDO> page);
List<MerchantDetailsExcelVO> convertList02(List<MerchantDetailsDO> list);
}
@@ -0,0 +1,92 @@
package co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import co.yixiang.yshop.framework.mybatis.core.dataobject.BaseDO;
/**
* 支付服务商配置 DO
*
* @author yshop
*/
@TableName("merchant_details")
@KeySequence("merchant_details_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MerchantDetailsDO extends BaseDO {
/**
* 列表id
*/
@TableId(type = IdType.INPUT)
private String detailsId;
/**
* 支付类型(支付渠道) 详情查看com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform对应子类,aliPay 支付宝, wxPay微信..等等
*/
private String payType;
/**
* 应用id
*/
private String appid;
/**
* 商户id,商户号,合作伙伴id等等
*/
private String mchId;
/**
* 当前面私钥公钥为证书类型的时候,这里必填,可选值:PATH,STR,INPUT_STREAM,CLASS_PATH,URL
*/
private String certStoreType;
/**
* 私钥或私钥证书
*/
private String keyPrivate;
/**
* 公钥或公钥证书
*/
private String keyPublic;
/**
* key证书,附加证书使用,如SSL证书,或者银联根级证书方面
*/
private String keyCert;
/**
* 私钥证书或key证书的密码
*/
private String keyCertPwd;
/**
* 异步回调
*/
private String notifyUrl;
/**
* 同步回调地址,大部分用于付款成功后页面转跳
*/
private String returnUrl;
/**
* 签名方式,目前已实现多种签名方式详情查看com.egzosn.pay.common.util.sign.encrypt。MD5,RSA等等
*/
private String signType;
/**
* 收款账号,暂时只有支付宝部分使用,可根据开发者自行使用
*/
private String seller;
/**
* 子appid
*/
private String subAppId;
/**
* 子商户id
*/
private String subMchId;
/**
* 编码类型,大部分为utf-8
*/
private String inputCharset;
/**
* 是否为测试环境: 0 否,1 测试环境
*/
private Integer isTest;
}
@@ -0,0 +1,62 @@
package co.yixiang.yshop.module.pay.dal.mysql.merchantdetails;
import java.util.*;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.framework.mybatis.core.query.LambdaQueryWrapperX;
import co.yixiang.yshop.framework.mybatis.core.mapper.BaseMapperX;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
import org.apache.ibatis.annotations.Mapper;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
/**
* 支付服务商配置 Mapper
*
* @author yshop
*/
@Mapper
public interface MerchantDetailsMapper extends BaseMapperX<MerchantDetailsDO> {
default PageResult<MerchantDetailsDO> selectPage(MerchantDetailsPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MerchantDetailsDO>()
.eqIfPresent(MerchantDetailsDO::getPayType, reqVO.getPayType())
.eqIfPresent(MerchantDetailsDO::getAppid, reqVO.getAppid())
.eqIfPresent(MerchantDetailsDO::getMchId, reqVO.getMchId())
.eqIfPresent(MerchantDetailsDO::getCertStoreType, reqVO.getCertStoreType())
.eqIfPresent(MerchantDetailsDO::getKeyPrivate, reqVO.getKeyPrivate())
.eqIfPresent(MerchantDetailsDO::getKeyPublic, reqVO.getKeyPublic())
.eqIfPresent(MerchantDetailsDO::getKeyCert, reqVO.getKeyCert())
.eqIfPresent(MerchantDetailsDO::getKeyCertPwd, reqVO.getKeyCertPwd())
.eqIfPresent(MerchantDetailsDO::getNotifyUrl, reqVO.getNotifyUrl())
.eqIfPresent(MerchantDetailsDO::getReturnUrl, reqVO.getReturnUrl())
.eqIfPresent(MerchantDetailsDO::getSignType, reqVO.getSignType())
.eqIfPresent(MerchantDetailsDO::getSeller, reqVO.getSeller())
.eqIfPresent(MerchantDetailsDO::getSubAppId, reqVO.getSubAppId())
.eqIfPresent(MerchantDetailsDO::getSubMchId, reqVO.getSubMchId())
.eqIfPresent(MerchantDetailsDO::getInputCharset, reqVO.getInputCharset())
.eqIfPresent(MerchantDetailsDO::getIsTest, reqVO.getIsTest())
.orderByDesc(MerchantDetailsDO::getDetailsId));
}
default List<MerchantDetailsDO> selectList(MerchantDetailsExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<MerchantDetailsDO>()
.eqIfPresent(MerchantDetailsDO::getPayType, reqVO.getPayType())
.eqIfPresent(MerchantDetailsDO::getAppid, reqVO.getAppid())
.eqIfPresent(MerchantDetailsDO::getMchId, reqVO.getMchId())
.eqIfPresent(MerchantDetailsDO::getCertStoreType, reqVO.getCertStoreType())
.eqIfPresent(MerchantDetailsDO::getKeyPrivate, reqVO.getKeyPrivate())
.eqIfPresent(MerchantDetailsDO::getKeyPublic, reqVO.getKeyPublic())
.eqIfPresent(MerchantDetailsDO::getKeyCert, reqVO.getKeyCert())
.eqIfPresent(MerchantDetailsDO::getKeyCertPwd, reqVO.getKeyCertPwd())
.eqIfPresent(MerchantDetailsDO::getNotifyUrl, reqVO.getNotifyUrl())
.eqIfPresent(MerchantDetailsDO::getReturnUrl, reqVO.getReturnUrl())
.eqIfPresent(MerchantDetailsDO::getSignType, reqVO.getSignType())
.eqIfPresent(MerchantDetailsDO::getSeller, reqVO.getSeller())
.eqIfPresent(MerchantDetailsDO::getSubAppId, reqVO.getSubAppId())
.eqIfPresent(MerchantDetailsDO::getSubMchId, reqVO.getSubMchId())
.eqIfPresent(MerchantDetailsDO::getInputCharset, reqVO.getInputCharset())
.eqIfPresent(MerchantDetailsDO::getIsTest, reqVO.getIsTest())
.orderByDesc(MerchantDetailsDO::getDetailsId));
}
}
@@ -0,0 +1,70 @@
package co.yixiang.yshop.module.pay.http;
import com.egzosn.pay.common.bean.NoticeRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
public class HttpRequestNoticeNewParams implements NoticeRequest {
private final HttpServletRequest httpServletRequest;
public HttpRequestNoticeNewParams(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
/**
* 根据请求头名称获取请求头信息
*
* @param name 名称
* @return 请求头值
*/
@Override
public String getHeader(String name) {
return httpServletRequest.getHeader(name);
}
/**
* 根据请求头名称获取请求头信息
*
* @param name 名称
* @return 请求头值
*/
@Override
public Enumeration<String> getHeaders(String name) {
return httpServletRequest.getHeaders(name);
}
/**
* 获取所有的请求头名称
*
* @return 请求头名称
*/
@Override
public Enumeration<String> getHeaderNames() {
return httpServletRequest.getHeaderNames();
}
/**
* 输入流
*
* @return 输入流
* @throws IOException IOException
*/
@Override
public InputStream getInputStream() throws IOException {
return httpServletRequest.getInputStream();
}
/**
* 获取所有的请求参数
*
* @return 请求参数
*/
@Override
public Map<String, String[]> getParameterMap() {
return httpServletRequest.getParameterMap();
}
}
@@ -0,0 +1,70 @@
package co.yixiang.yshop.module.pay.service.merchantdetails;
import java.util.*;
import jakarta.validation.*;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
import co.yixiang.yshop.framework.common.pojo.PageResult;
/**
* 支付服务商配置 Service 接口
*
* @author yshop
*/
public interface MerchantDetailsService {
/**
* 创建支付服务商配置
*
* @param createReqVO 创建信息
* @return 编号
*/
String createMerchantDetails(@Valid MerchantDetailsCreateReqVO createReqVO);
/**
* 更新支付服务商配置
*
* @param updateReqVO 更新信息
*/
void updateMerchantDetails(@Valid MerchantDetailsUpdateReqVO updateReqVO);
/**
* 删除支付服务商配置
*
* @param id 编号
*/
void deleteMerchantDetails(String id);
/**
* 获得支付服务商配置
*
* @param id 编号
* @return 支付服务商配置
*/
MerchantDetailsDO getMerchantDetails(String id);
/**
* 获得支付服务商配置列表
*
* @param ids 编号
* @return 支付服务商配置列表
*/
List<MerchantDetailsDO> getMerchantDetailsList(Collection<String> ids);
/**
* 获得支付服务商配置分页
*
* @param pageReqVO 分页查询
* @return 支付服务商配置分页
*/
PageResult<MerchantDetailsDO> getMerchantDetailsPage(MerchantDetailsPageReqVO pageReqVO);
/**
* 获得支付服务商配置列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 支付服务商配置列表
*/
List<MerchantDetailsDO> getMerchantDetailsList(MerchantDetailsExportReqVO exportReqVO);
}
@@ -0,0 +1,82 @@
package co.yixiang.yshop.module.pay.service.merchantdetails;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.pay.convert.merchantdetails.MerchantDetailsConvert;
import co.yixiang.yshop.module.pay.dal.mysql.merchantdetails.MerchantDetailsMapper;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.pay.enums.ErrorCodeConstants.*;
/**
* 支付服务商配置 Service 实现类
*
* @author yshop
*/
@Service
@Validated
public class MerchantDetailsServiceImpl implements MerchantDetailsService {
@Resource
private MerchantDetailsMapper merchantDetailsMapper;
@Override
public String createMerchantDetails(MerchantDetailsCreateReqVO createReqVO) {
// 插入
MerchantDetailsDO merchantDetails = MerchantDetailsConvert.INSTANCE.convert(createReqVO);
merchantDetailsMapper.insert(merchantDetails);
// 返回
return merchantDetails.getDetailsId();
}
@Override
public void updateMerchantDetails(MerchantDetailsUpdateReqVO updateReqVO) {
// 校验存在
validateMerchantDetailsExists(updateReqVO.getDetailsId());
// 更新
MerchantDetailsDO updateObj = MerchantDetailsConvert.INSTANCE.convert(updateReqVO);
merchantDetailsMapper.updateById(updateObj);
}
@Override
public void deleteMerchantDetails(String id) {
// 校验存在
validateMerchantDetailsExists(id);
// 删除
merchantDetailsMapper.deleteById(id);
}
private void validateMerchantDetailsExists(String id) {
if (merchantDetailsMapper.selectById(id) == null) {
throw exception(MERCHANT_DETAILS_NOT_EXISTS);
}
}
@Override
public MerchantDetailsDO getMerchantDetails(String id) {
return merchantDetailsMapper.selectById(id);
}
@Override
public List<MerchantDetailsDO> getMerchantDetailsList(Collection<String> ids) {
return merchantDetailsMapper.selectBatchIds(ids);
}
@Override
public PageResult<MerchantDetailsDO> getMerchantDetailsPage(MerchantDetailsPageReqVO pageReqVO) {
return merchantDetailsMapper.selectPage(pageReqVO);
}
@Override
public List<MerchantDetailsDO> getMerchantDetailsList(MerchantDetailsExportReqVO exportReqVO) {
return merchantDetailsMapper.selectList(exportReqVO);
}
}
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="co.yixiang.yshop.module.pay.dal.mysql.merchantdetails.MerchantDetailsMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见:https://www.yixiang.co/MyBatis/x-plugins/
-->
</mapper>