diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/controller/mch/AlipayChannelMerchantController.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/controller/mch/AlipayChannelMerchantController.java new file mode 100644 index 000000000..9954d4384 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/controller/mch/AlipayChannelMerchantController.java @@ -0,0 +1,44 @@ +package org.dromara.daxpay.channel.alipay.controller.mch; + +import org.dromara.daxpay.platform.core.annotation.PermCode; +import org.dromara.daxpay.platform.core.rest.Res; +import org.dromara.daxpay.platform.core.rest.result.Result; +import org.dromara.daxpay.channel.alipay.param.mch.AlipayDirectChannelMerchantCreateParam; +import org.dromara.daxpay.channel.alipay.result.config.AlipayChannelMerchantResult; +import org.dromara.daxpay.channel.alipay.service.mch.AlipayChannelMerchantService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotBlank; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +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; + +@PermCode(menuCode = "payment:merchant:channelMerchant") +@Validated +@Tag(name = "支付宝通道商户管理") +@RestController +@RequestMapping("/admin/alipay/channel-merchant") +@RequiredArgsConstructor +public class AlipayChannelMerchantController { + + private final AlipayChannelMerchantService alipayChannelMerchantService; + + @PermCode(code = "view", nameCn = "商户通道商户查看", nameEn = "Merchant Channel Merchant View") + @Operation(summary = "根据通道商户号查询支付宝通道商户配置") + @GetMapping("/find-by-channel-mch-no") + public Result findByChannelMchNo( + @NotBlank(message = "{validation.field.channelMerchantNo.notBlank}") String channelMchNo) { + return Res.ok(alipayChannelMerchantService.findByChannelMchNo(channelMchNo)); + } + + @PermCode(code = "add", nameCn = "商户通道商户新增", nameEn = "Merchant Channel Merchant Add") + @Operation(summary = "创建支付宝直连通道商户") + @PostMapping("/create-direct") + public Result createDirect(@RequestBody @Validated AlipayDirectChannelMerchantCreateParam param) { + return Res.ok(alipayChannelMerchantService.createDirect(param)); + } +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/convert/AlipayChannelMerchantConvert.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/convert/AlipayChannelMerchantConvert.java new file mode 100644 index 000000000..bdacf9e2a --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/convert/AlipayChannelMerchantConvert.java @@ -0,0 +1,14 @@ +package org.dromara.daxpay.channel.alipay.convert; + +import org.dromara.daxpay.channel.alipay.entity.config.AlipayChannelMerchant; +import org.dromara.daxpay.channel.alipay.result.config.AlipayChannelMerchantResult; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AlipayChannelMerchantConvert { + + AlipayChannelMerchantConvert CONVERT = Mappers.getMapper(AlipayChannelMerchantConvert.class); + + AlipayChannelMerchantResult toResult(AlipayChannelMerchant entity); +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/dao/config/AlipayChannelMerchantManager.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/dao/config/AlipayChannelMerchantManager.java new file mode 100644 index 000000000..607168a1b --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/dao/config/AlipayChannelMerchantManager.java @@ -0,0 +1,9 @@ +package org.dromara.daxpay.channel.alipay.dao.config; + +import org.dromara.daxpay.channel.alipay.entity.config.AlipayChannelMerchant; +import org.dromara.daxpay.platform.common.mybatisplus.impl.BaseManager; +import org.springframework.stereotype.Repository; + +@Repository +public class AlipayChannelMerchantManager extends BaseManager { +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/dao/config/AlipayChannelMerchantMapper.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/dao/config/AlipayChannelMerchantMapper.java new file mode 100644 index 000000000..8cf8d9c5e --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/dao/config/AlipayChannelMerchantMapper.java @@ -0,0 +1,9 @@ +package org.dromara.daxpay.channel.alipay.dao.config; + +import org.dromara.daxpay.channel.alipay.entity.config.AlipayChannelMerchant; +import com.github.yulichang.base.MPJBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface AlipayChannelMerchantMapper extends MPJBaseMapper { +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/entity/config/AlipayChannelMerchant.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/entity/config/AlipayChannelMerchant.java new file mode 100644 index 000000000..c6e555434 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/entity/config/AlipayChannelMerchant.java @@ -0,0 +1,32 @@ +package org.dromara.daxpay.channel.alipay.entity.config; + +import org.dromara.daxpay.platform.common.mybatisplus.function.ToResult; +import org.dromara.daxpay.channel.alipay.convert.AlipayChannelMerchantConvert; +import org.dromara.daxpay.channel.alipay.result.config.AlipayChannelMerchantResult; +import org.dromara.daxpay.payment.common.entity.merchant.MchBaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@TableName(value = "mch_alipay_channel_merchant", autoResultMap = true) +public class AlipayChannelMerchant extends MchBaseEntity implements ToResult { + + private String channelMchNo; + + private String product; + + private String isvAppId; + + private String alipayUserId; + + private String appAuthToken; + + @Override + public AlipayChannelMerchantResult toResult() { + return AlipayChannelMerchantConvert.CONVERT.toResult(this); + } +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/param/mch/AlipayDirectChannelMerchantCreateParam.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/param/mch/AlipayDirectChannelMerchantCreateParam.java new file mode 100644 index 000000000..24059eaab --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/param/mch/AlipayDirectChannelMerchantCreateParam.java @@ -0,0 +1,28 @@ +package org.dromara.daxpay.channel.alipay.param.mch; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +@Schema(title = "支付宝直连通道商户创建参数") +public class AlipayDirectChannelMerchantCreateParam { + + @Schema(description = "商户号") + @NotBlank(message = "{validation.field.mchNo.notBlank}") + private String mchNo; + + @Schema(description = "通道商户名称") + @NotBlank(message = "{validation.field.channelMerchantName.notBlank}") + private String channelMerchantName; + + @Schema(description = "所属支付产品") + @NotBlank(message = "{validation.field.product.notBlank}") + private String product; + + @Schema(description = "支付宝商家用户ID(2088开头)") + @NotBlank(message = "{validation.field.alipayUserId.notBlank}") + private String alipayUserId; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/result/config/AlipayChannelMerchantResult.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/result/config/AlipayChannelMerchantResult.java new file mode 100644 index 000000000..f00ab4251 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/result/config/AlipayChannelMerchantResult.java @@ -0,0 +1,29 @@ +package org.dromara.daxpay.channel.alipay.result.config; + +import org.dromara.daxpay.payment.common.result.MchTradeBaseResult; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "支付宝通道商户配置结果") +public class AlipayChannelMerchantResult extends MchTradeBaseResult { + + @Schema(description = "通道商户号") + private String channelMchNo; + + @Schema(description = "所属支付产品") + private String product; + + @Schema(description = "支付宝服务商应用ID(aliAppId)") + private String isvAppId; + + @Schema(description = "支付宝商家唯一识别码(2088开头的16位数字)") + private String alipayUserId; + + @Schema(description = "应用授权令牌") + private String appAuthToken; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/mch/AlipayChannelMerchantService.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/mch/AlipayChannelMerchantService.java new file mode 100644 index 000000000..95c17fb60 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/mch/AlipayChannelMerchantService.java @@ -0,0 +1,57 @@ +package org.dromara.daxpay.channel.alipay.service.mch; + +import org.dromara.daxpay.channel.alipay.dao.config.AlipayChannelMerchantManager; +import org.dromara.daxpay.channel.alipay.entity.config.AlipayChannelMerchant; +import org.dromara.daxpay.channel.alipay.param.mch.AlipayDirectChannelMerchantCreateParam; +import org.dromara.daxpay.channel.alipay.result.config.AlipayChannelMerchantResult; +import org.dromara.daxpay.payment.channel.dao.mch.ChannelMerchantManager; +import org.dromara.daxpay.payment.channel.entity.mch.ChannelMerchant; +import org.dromara.daxpay.platform.core.enums.channel.ChannelMerchantSourceEnum; +import org.dromara.daxpay.platform.core.exception.DataNotExistException; +import cn.hutool.core.util.IdUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AlipayChannelMerchantService { + + private final ChannelMerchantManager channelMerchantManager; + private final AlipayChannelMerchantManager alipayChannelMerchantManager; + + @Transactional(rollbackFor = Exception.class) + public Long createDirect(AlipayDirectChannelMerchantCreateParam param) { + String channelMchNo = param.getAlipayUserId(); + + ChannelMerchant channelMerchant = new ChannelMerchant(); + long channelMerchantId = IdUtil.getSnowflakeNextId(); + channelMerchant.setId(channelMerchantId); + channelMerchant.setMchNo(param.getMchNo()); + channelMerchant.setChannelMchNo(channelMchNo); + channelMerchant.setChannelMerchantName(param.getChannelMerchantName()); + channelMerchant.setProduct(param.getProduct()); + channelMerchant.setSource(ChannelMerchantSourceEnum.MANUAL.getCode()); + channelMerchant.setEnable(true); + channelMerchantManager.save(channelMerchant); + + AlipayChannelMerchant alipayChannelMerchant = new AlipayChannelMerchant(); + alipayChannelMerchant.setId(IdUtil.getSnowflakeNextId()); + alipayChannelMerchant.setMchNo(param.getMchNo()); + alipayChannelMerchant.setChannelMchNo(channelMchNo); + alipayChannelMerchant.setProduct(param.getProduct()); + alipayChannelMerchant.setAlipayUserId(param.getAlipayUserId()); + alipayChannelMerchantManager.save(alipayChannelMerchant); + return channelMerchantId; + } + + public AlipayChannelMerchantResult findByChannelMchNo(String channelMchNo) { + return alipayChannelMerchantManager.lambdaQuery() + .eq(AlipayChannelMerchant::getChannelMchNo, channelMchNo) + .oneOpt() + .map(AlipayChannelMerchant::toResult) + .orElseThrow(() -> new DataNotExistException("error.payment.channel.channelMerchantNotExist")); + } +}