diff --git a/sql/pay-merchant-menu.sql b/sql/pay-merchant-menu.sql
new file mode 100644
index 000000000..cc4a4e761
--- /dev/null
+++ b/sql/pay-merchant-menu.sql
@@ -0,0 +1,60 @@
+-- 支付模块-商户中心-菜单SQL
+-- 菜单 SQL
+INSERT INTO `sys_menu` (
+    `name`, `permission`,`menu_type`,`sort`, `parent_id`, `path`, `icon`, `component`,
+                        `status`, `creator`,`create_time`, `updater`, `update_time`, `deleted`
+) VALUES ('支付管理',  '', 1, 4,0, '/pay','pay', NULL, 0, '1', '2021-11-03 10:35:04', '1', '2021-11-03 10:35:04', b'0');
+
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+    '支付商户信息管理', '', 2, 0, ${table.parentMenuId},
+    'merchant', '', 'pay/merchant/index', 0
+);
+
+-- 按钮父菜单ID
+SELECT @parentId := LAST_INSERT_ID();
+
+-- 按钮 SQL
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+    '支付商户信息查询', 'pay:merchant:query', 3, 1, @parentId,
+    '', '', '', 0
+);
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+    '支付商户信息创建', 'pay:merchant:create', 3, 2, @parentId,
+    '', '', '', 0
+);
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+    '支付商户信息更新', 'pay:merchant:update', 3, 3, @parentId,
+    '', '', '', 0
+);
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+    '支付商户信息删除', 'pay:merchant:delete', 3, 4, @parentId,
+    '', '', '', 0
+);
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+    '支付商户信息导出', 'pay:merchant:export', 3, 5, @parentId,
+    '', '', '', 0
+);
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java
new file mode 100644
index 000000000..6ec9af43a
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java
@@ -0,0 +1,108 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant;
+
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
+import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
+import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
+import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserUpdateStatusReqVO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+@Api(tags = "支付商户信息")
+@RestController
+@RequestMapping("/pay/merchant")
+@Validated
+public class PayMerchantController {
+
+    @Resource
+    private PayMerchantService merchantService;
+
+    @PostMapping("/create")
+    @ApiOperation("创建支付商户信息")
+    @PreAuthorize("@ss.hasPermission('pay:merchant:create')")
+    public CommonResult<Long> createMerchant(@Valid @RequestBody PayMerchantCreateReqVO createReqVO) {
+        return success(merchantService.createMerchant(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新支付商户信息")
+    @PreAuthorize("@ss.hasPermission('pay:merchant:update')")
+    public CommonResult<Boolean> updateMerchant(@Valid @RequestBody PayMerchantUpdateReqVO updateReqVO) {
+        merchantService.updateMerchant(updateReqVO);
+        return success(true);
+    }
+
+    @PutMapping("/update-status")
+    @ApiOperation("修改支付商户状态")
+    @PreAuthorize("@ss.hasPermission('pay:merchant:update')")
+    public CommonResult<Boolean> updateMerchantStatus(@Valid @RequestBody PayMerchantUpdateStatusReqVO reqVO) {
+        merchantService.updateMerchantStatus(reqVO.getId(), reqVO.getStatus());
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除支付商户信息")
+    @ApiImplicitParam(name = "id", value = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('pay:merchant:delete')")
+    public CommonResult<Boolean> deleteMerchant(@RequestParam("id") Long id) {
+        merchantService.deleteMerchant(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得支付商户信息")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
+    public CommonResult<PayMerchantRespVO> getMerchant(@RequestParam("id") Long id) {
+        PayMerchantDO merchant = merchantService.getMerchant(id);
+        return success(PayMerchantConvert.INSTANCE.convert(merchant));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("获得支付商户信息列表")
+    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+    @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
+    public CommonResult<List<PayMerchantRespVO>> getMerchantList(@RequestParam("ids") Collection<Long> ids) {
+        List<PayMerchantDO> list = merchantService.getMerchantList(ids);
+        return success(PayMerchantConvert.INSTANCE.convertList(list));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得支付商户信息分页")
+    @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
+    public CommonResult<PageResult<PayMerchantRespVO>> getMerchantPage(@Valid PayMerchantPageReqVO pageVO) {
+        PageResult<PayMerchantDO> pageResult = merchantService.getMerchantPage(pageVO);
+        return success(PayMerchantConvert.INSTANCE.convertPage(pageResult));
+    }
+
+    @GetMapping("/export-excel")
+    @ApiOperation("导出支付商户信息 Excel")
+    @PreAuthorize("@ss.hasPermission('pay:merchant:export')")
+    @OperateLog(type = EXPORT)
+    public void exportMerchantExcel(@Valid PayMerchantExportReqVO exportReqVO,
+              HttpServletResponse response) throws IOException {
+        List<PayMerchantDO> list = merchantService.getMerchantList(exportReqVO);
+        // 导出 Excel
+        List<PayMerchantExcelVO> datas = PayMerchantConvert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "支付商户信息.xls", "数据", PayMerchantExcelVO.class, datas);
+    }
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java
new file mode 100644
index 000000000..4d83ff232
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+* 支付商户信息 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class PayMerchantBaseVO {
+
+    @ApiModelProperty(value = "商户号")
+    private String no;
+
+    @ApiModelProperty(value = "商户全称", required = true)
+    @NotNull(message = "商户全称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "商户简称", required = true)
+    @NotNull(message = "商户简称不能为空")
+    private String shortName;
+
+    @ApiModelProperty(value = "开启状态", required = true)
+    @NotNull(message = "开启状态不能为空")
+    private Integer status;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java
new file mode 100644
index 000000000..2128de88b
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java
@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("支付商户信息创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayMerchantCreateReqVO extends PayMerchantBaseVO {
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java
new file mode 100644
index 000000000..80c206c2d
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java
@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+
+/**
+ * 支付商户信息 Excel VO
+ *
+ * @author 芋艿
+ */
+@Data
+public class PayMerchantExcelVO {
+
+    @ExcelProperty("商户编号")
+    private Long id;
+
+    @ExcelProperty("商户号")
+    private String no;
+
+    @ExcelProperty("商户全称")
+    private String name;
+
+    @ExcelProperty("商户简称")
+    private String shortName;
+
+    @ExcelProperty(value = "开启状态",converter = DictConvert.class)
+    @DictFormat("pay_merchant_status")
+    private Integer status;
+
+    @ExcelProperty("备注")
+    private String remark;
+
+    @ExcelProperty("创建时间")
+    private Date createTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java
new file mode 100644
index 000000000..c6c322282
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的")
+@Data
+public class PayMerchantExportReqVO {
+
+    @ApiModelProperty(value = "商户号")
+    private String no;
+
+    @ApiModelProperty(value = "商户全称")
+    private String name;
+
+    @ApiModelProperty(value = "商户简称")
+    private String shortName;
+
+    @ApiModelProperty(value = "开启状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java
new file mode 100644
index 000000000..8a66ac953
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("支付商户信息分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayMerchantPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "商户号")
+    private String no;
+
+    @ApiModelProperty(value = "商户全称")
+    private String name;
+
+    @ApiModelProperty(value = "商户简称")
+    private String shortName;
+
+    @ApiModelProperty(value = "开启状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java
new file mode 100644
index 000000000..ba55458eb
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java
@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("支付商户信息 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayMerchantRespVO extends PayMerchantBaseVO {
+
+    @ApiModelProperty(value = "商户编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java
new file mode 100644
index 000000000..031d34fd5
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("支付商户信息更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayMerchantUpdateReqVO extends PayMerchantBaseVO {
+
+    @ApiModelProperty(value = "商户编号", required = true)
+    @NotNull(message = "商户编号不能为空")
+    private Long id;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java
new file mode 100644
index 000000000..635876954
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@ApiModel("商户更新状态 Request VO")
+@Data
+public class PayMerchantUpdateStatusReqVO {
+
+    @ApiModelProperty(value = "商户编号", required = true, example = "1024")
+    @NotNull(message = "商户编号不能为空")
+    private Long id;
+
+    @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举")
+    @NotNull(message = "状态不能为空")
+    private Integer status;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java
new file mode 100644
index 000000000..9483ff120
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.adminserver.modules.pay.convert.merchant;
+
+import java.util.*;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
+
+/**
+ * 支付商户信息 Convert
+ *
+ * @author 芋艿
+ */
+@Mapper
+public interface PayMerchantConvert {
+
+    PayMerchantConvert INSTANCE = Mappers.getMapper(PayMerchantConvert.class);
+
+    PayMerchantDO convert(PayMerchantCreateReqVO bean);
+
+    PayMerchantDO convert(PayMerchantUpdateReqVO bean);
+
+    PayMerchantRespVO convert(PayMerchantDO bean);
+
+    List<PayMerchantRespVO> convertList(List<PayMerchantDO> list);
+
+    PageResult<PayMerchantRespVO> convertPage(PageResult<PayMerchantDO> page);
+
+    List<PayMerchantExcelVO> convertList02(List<PayMerchantDO> list);
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java
new file mode 100644
index 000000000..5abc3a231
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant;
+
+import java.util.*;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
+
+/**
+ * 支付商户信息 Mapper
+ *
+ * @author 芋艿
+ */
+@Mapper
+public interface PayMerchantMapper extends BaseMapperX<PayMerchantDO> {
+
+    default PageResult<PayMerchantDO> selectPage(PayMerchantPageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<PayMerchantDO>()
+                .likeIfPresent("no", reqVO.getNo())
+                .likeIfPresent("name", reqVO.getName())
+                .likeIfPresent("short_name", reqVO.getShortName())
+                .eqIfPresent("status", reqVO.getStatus())
+                .eqIfPresent("remark", reqVO.getRemark())
+                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc("id"));
+    }
+
+    default List<PayMerchantDO> selectList(PayMerchantExportReqVO reqVO) {
+        return selectList(new QueryWrapperX<PayMerchantDO>()
+                .likeIfPresent("no", reqVO.getNo())
+                .likeIfPresent("name", reqVO.getName())
+                .likeIfPresent("short_name", reqVO.getShortName())
+                .eqIfPresent("status", reqVO.getStatus())
+                .eqIfPresent("remark", reqVO.getRemark())
+                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc("id"));
+    }
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java
new file mode 100644
index 000000000..df39d9efc
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java
@@ -0,0 +1 @@
+package cn.iocoder.yudao.adminserver.modules.pay.enums;
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java
new file mode 100644
index 000000000..db7926c12
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java
@@ -0,0 +1,77 @@
+package cn.iocoder.yudao.adminserver.modules.pay.service.merchant;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+/**
+ * 支付商户信息 Service 接口
+ *
+ * @author 芋艿
+ */
+public interface PayMerchantService {
+
+    /**
+     * 创建支付商户信息
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createMerchant(@Valid PayMerchantCreateReqVO createReqVO);
+
+    /**
+     * 更新支付商户信息
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateMerchant(@Valid PayMerchantUpdateReqVO updateReqVO);
+
+    /**
+     * 删除支付商户信息
+     *
+     * @param id 编号
+     */
+    void deleteMerchant(Long id);
+
+    /**
+     * 获得支付商户信息
+     *
+     * @param id 编号
+     * @return 支付商户信息
+     */
+    PayMerchantDO getMerchant(Long id);
+
+    /**
+     * 获得支付商户信息列表
+     *
+     * @param ids 编号
+     * @return 支付商户信息列表
+     */
+    List<PayMerchantDO> getMerchantList(Collection<Long> ids);
+
+    /**
+     * 获得支付商户信息分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 支付商户信息分页
+     */
+    PageResult<PayMerchantDO> getMerchantPage(PayMerchantPageReqVO pageReqVO);
+
+    /**
+     * 获得支付商户信息列表, 用于 Excel 导出
+     *
+     * @param exportReqVO 查询条件
+     * @return 支付商户信息列表
+     */
+    List<PayMerchantDO> getMerchantList(PayMerchantExportReqVO exportReqVO);
+
+    /**
+     * 修改商户状态
+     * @param id 商户编号
+     * @param status 状态
+     */
+    void updateMerchantStatus(Long id, Integer status);
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java
new file mode 100644
index 000000000..12981677f
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java
@@ -0,0 +1,125 @@
+package cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
+import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
+import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import com.google.common.annotations.VisibleForTesting;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.Collection;
+import java.util.List;
+
+import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+/**
+ * 支付商户信息 Service 实现类
+ *
+ * @author 芋艿
+ */
+@Service
+@Validated
+public class PayMerchantServiceImpl implements PayMerchantService {
+
+    @Resource
+    private PayMerchantMapper merchantMapper;
+
+    @Override
+    public Long createMerchant(PayMerchantCreateReqVO createReqVO) {
+        // 插入
+        PayMerchantDO merchant = PayMerchantConvert.INSTANCE.convert(createReqVO);
+        // 根据 年月日时分秒毫秒 生成时间戳
+        String merchantNo = "M" + DateUtil.format(LocalDateTime.now(),"yyyyMMddHHmmssSSS");
+        merchant.setNo(merchantNo);
+        merchantMapper.insert(merchant);
+        // 返回
+        return merchant.getId();
+    }
+
+    @Override
+    public void updateMerchant(PayMerchantUpdateReqVO updateReqVO) {
+        // 校验存在
+        this.validateMerchantExists(updateReqVO.getId());
+        // 更新
+        PayMerchantDO updateObj = PayMerchantConvert.INSTANCE.convert(updateReqVO);
+        merchantMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteMerchant(Long id) {
+        // 校验存在
+        this.validateMerchantExists(id);
+        // 删除
+        merchantMapper.deleteById(id);
+    }
+
+    private void validateMerchantExists(Long id) {
+        if (merchantMapper.selectById(id) == null) {
+            throw exception(MERCHANT_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public PayMerchantDO getMerchant(Long id) {
+        return merchantMapper.selectById(id);
+    }
+
+    @Override
+    public List<PayMerchantDO> getMerchantList(Collection<Long> ids) {
+        return merchantMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public PageResult<PayMerchantDO> getMerchantPage(PayMerchantPageReqVO pageReqVO) {
+        return merchantMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<PayMerchantDO> getMerchantList(PayMerchantExportReqVO exportReqVO) {
+        return merchantMapper.selectList(exportReqVO);
+    }
+
+    /**
+     * 修改商户状态
+     *
+     * @param id     商户编号
+     * @param status 状态
+     */
+    @Override
+    public void updateMerchantStatus(Long id, Integer status) {
+        // 校验商户存在
+        this.checkMerchantExists(id);
+        // 更新状态
+        PayMerchantDO merchant = new PayMerchantDO();
+        merchant.setId(id);
+        merchant.setStatus(status);
+        merchantMapper.updateById(merchant);
+    }
+
+    /**
+     * 检查商户是否存在
+     * @param id 商户编号
+     */
+    @VisibleForTesting
+    public void checkMerchantExists(Long id) {
+        if (id == null) {
+            return;
+        }
+        PayMerchantDO merchant = merchantMapper.selectById(id);
+        if (merchant == null) {
+            throw exception(MERCHANT_NOT_EXISTS);
+        }
+    }
+
+
+}
diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/merchant/service/PayMerchantServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/merchant/service/PayMerchantServiceTest.java
new file mode 100644
index 000000000..a93808921
--- /dev/null
+++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/merchant/service/PayMerchantServiceTest.java
@@ -0,0 +1,192 @@
+package cn.iocoder.yudao.adminserver.modules.pay.merchant.service;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
+import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl.PayMerchantServiceImpl;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+* {@link PayMerchantServiceImpl} 的单元测试类
+*
+* @author 芋艿
+*/
+@Import(PayMerchantServiceImpl.class)
+public class PayMerchantServiceTest extends BaseDbUnitTest {
+
+    @Resource
+    private PayMerchantServiceImpl merchantService;
+
+    @Resource
+    private PayMerchantMapper merchantMapper;
+
+    @Test
+    public void testCreateMerchant_success() {
+        // 准备参数
+        PayMerchantCreateReqVO reqVO = randomPojo(PayMerchantCreateReqVO.class,o ->
+            o.setStatus(RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()));
+
+        // 调用
+        Long merchantId = merchantService.createMerchant(reqVO);
+        // 断言
+        assertNotNull(merchantId);
+        // 校验记录的属性是否正确
+        PayMerchantDO merchant = merchantMapper.selectById(merchantId);
+        assertPojoEquals(reqVO, merchant,"no");
+    }
+
+    @Test
+    public void testUpdateMerchant_success() {
+        // mock 数据
+        PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o ->
+            o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class, o -> {
+            o.setId(dbMerchant.getId()); // 设置更新的 ID
+            o.setStatus(CommonStatusEnum.DISABLE.getStatus());
+        });
+
+        // 调用
+        merchantService.updateMerchant(reqVO);
+        // 校验是否更新正确
+        PayMerchantDO merchant = merchantMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, merchant);
+    }
+
+    @Test
+    public void testUpdateMerchant_notExists() {
+        // 准备参数
+        PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> merchantService.updateMerchant(reqVO), MERCHANT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteMerchant_success() {
+        // mock 数据
+        PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class,
+                o-> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbMerchant.getId();
+
+        // 调用
+        merchantService.deleteMerchant(id);
+       // 校验数据不存在了
+       assertNull(merchantMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteMerchant_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> merchantService.deleteMerchant(id), MERCHANT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testGetMerchantPage() {
+       // mock 数据
+       PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到
+           o.setNo("M1008611");
+           o.setName("灿哥的杂货铺");
+           o.setShortName("灿灿子");
+           o.setStatus(CommonStatusEnum.ENABLE.getStatus());
+           o.setRemark("灿哥的杂货铺");
+           o.setCreateTime(buildTime(2021,11,3));
+       });
+       merchantMapper.insert(dbMerchant);
+       // 测试 no 不匹配
+       merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setNo("M200000")));
+       // 测试 name 不匹配
+       merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setName("斌哥的杂货铺")));
+       // 测试 shortName 不匹配
+       merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setShortName("斌斌子")));
+       // 测试 status 不匹配
+       merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+       // 测试 remark 不匹配
+       merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setRemark("斌哥的杂货铺")));
+       // 测试 createTime 不匹配
+       merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4))));
+       // 准备参数
+       PayMerchantPageReqVO reqVO = new PayMerchantPageReqVO();
+       reqVO.setNo("M1008611");
+       reqVO.setName("灿哥的杂货铺");
+       reqVO.setShortName("灿灿子");
+       reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+       reqVO.setRemark("灿哥的杂货铺");
+       reqVO.setBeginCreateTime(buildTime(2021,11,2));
+       reqVO.setEndCreateTime(buildTime(2021,11,4));
+
+       // 调用
+       PageResult<PayMerchantDO> pageResult = merchantService.getMerchantPage(reqVO);
+       // 断言
+       assertEquals(1, pageResult.getTotal());
+       assertEquals(1, pageResult.getList().size());
+       assertPojoEquals(dbMerchant, pageResult.getList().get(0));
+    }
+
+    @Test
+    public void testGetMerchantList() {
+       // mock 数据
+       PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到
+           o.setNo("M1008611");
+           o.setName("灿哥的杂货铺");
+           o.setShortName("灿灿子");
+           o.setStatus(CommonStatusEnum.ENABLE.getStatus());
+           o.setRemark("灿哥的杂货铺");
+           o.setCreateTime(buildTime(2021,11,3));
+       });
+        merchantMapper.insert(dbMerchant);
+        // 测试 no 不匹配
+        merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setNo("M200000")));
+        // 测试 name 不匹配
+        merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setName("斌哥的杂货铺")));
+        // 测试 shortName 不匹配
+        merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setShortName("斌斌子")));
+        // 测试 status 不匹配
+        merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        // 测试 remark 不匹配
+        merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setRemark("斌哥的杂货铺")));
+        // 测试 createTime 不匹配
+        merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4))));
+       // 准备参数
+       PayMerchantExportReqVO reqVO = new PayMerchantExportReqVO();
+       reqVO.setNo("M1008611");
+       reqVO.setName("灿哥的杂货铺");
+       reqVO.setShortName("灿灿子");
+       reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+       reqVO.setRemark("灿哥的杂货铺");
+       reqVO.setBeginCreateTime(buildTime(2021,11,2));
+       reqVO.setEndCreateTime(buildTime(2021,11,4));
+
+       // 调用
+       List<PayMerchantDO> list = merchantService.getMerchantList(reqVO);
+       // 断言
+       assertEquals(1, list.size());
+       assertPojoEquals(dbMerchant, list.get(0));
+    }
+
+}
diff --git a/yudao-admin-server/src/test/resources/sql/clean.sql b/yudao-admin-server/src/test/resources/sql/clean.sql
index 75080b343..e4edd4deb 100644
--- a/yudao-admin-server/src/test/resources/sql/clean.sql
+++ b/yudao-admin-server/src/test/resources/sql/clean.sql
@@ -24,3 +24,6 @@ DELETE FROM "sys_sms_template";
 DELETE FROM "sys_sms_log";
 DELETE FROM "sys_error_code";
 DELETE FROM "sys_social_user";
+
+-- pay 开头的 DB
+DELETE FROM pay_merchant;
diff --git a/yudao-admin-server/src/test/resources/sql/create_tables.sql b/yudao-admin-server/src/test/resources/sql/create_tables.sql
index db67cad23..6c6500386 100644
--- a/yudao-admin-server/src/test/resources/sql/create_tables.sql
+++ b/yudao-admin-server/src/test/resources/sql/create_tables.sql
@@ -449,3 +449,18 @@ CREATE TABLE IF NOT EXISTS "sys_social_user" (
    "deleted" bit NOT NULL DEFAULT FALSE,
    PRIMARY KEY ("id")
 ) COMMENT '社交用户';
+
+CREATE TABLE IF NOT EXISTS "pay_merchant" (
+    "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "no" varchar(32) NOT NULL,
+    "name" varchar(64) NOT NULL,
+    "short_name" varchar(64) NOT NULL,
+    "status" tinyint NOT NULL,
+    "remark" varchar(255) DEFAULT NULL,
+    "creator" varchar(64) DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ,
+    "updater" varchar(64) DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit(1) NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+)  COMMENT '支付商户信息';
diff --git a/yudao-admin-ui/src/api/pay/merchant.js b/yudao-admin-ui/src/api/pay/merchant.js
new file mode 100644
index 000000000..5dc6e96ee
--- /dev/null
+++ b/yudao-admin-ui/src/api/pay/merchant.js
@@ -0,0 +1,67 @@
+import request from '@/utils/request'
+
+// 创建支付商户信息
+export function createMerchant(data) {
+  return request({
+    url: '/pay/merchant/create',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新支付商户信息
+export function updateMerchant(data) {
+  return request({
+    url: '/pay/merchant/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 支付商户状态修改
+export function changeMerchantStatus(id, status) {
+  const data = {
+    id,
+    status
+  }
+  return request({
+    url: '/pay/merchant/update-status',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除支付商户信息
+export function deleteMerchant(id) {
+  return request({
+    url: '/pay/merchant/delete?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 获得支付商户信息
+export function getMerchant(id) {
+  return request({
+    url: '/pay/merchant/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得支付商户信息分页
+export function getMerchantPage(query) {
+  return request({
+    url: '/pay/merchant/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出支付商户信息 Excel
+export function exportMerchantExcel(query) {
+  return request({
+    url: '/pay/merchant/export-excel',
+    method: 'get',
+    params: query,
+    responseType: 'blob'
+  })
+}
diff --git a/yudao-admin-ui/src/assets/icons/svg/merchant.svg b/yudao-admin-ui/src/assets/icons/svg/merchant.svg
new file mode 100644
index 000000000..f1ecb8127
--- /dev/null
+++ b/yudao-admin-ui/src/assets/icons/svg/merchant.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635907181185" class="icon" viewBox="0 0 1184 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3259" xmlns:xlink="http://www.w3.org/1999/xlink" width="231.25" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
+</style></defs><path d="M1005.633722 616.006249c-5.311502-0.479955-10.431022-1.27988-15.518545-2.143799-1.087898-0.127988-2.271787-0.287973-3.359685-0.479955-2.399775-0.415961-4.671562-1.055901-7.007343-1.631847-9.951067-2.143799-19.678155-4.831547-28.989282-8.351217l0 133.235509-731.355435 0 0-133.235509c-9.375121 3.551667-19.006218 6.303409-29.053276 8.511202-2.335781 0.415961-4.607568 1.055901-6.943349 1.535856-1.087898 0.191982-2.175796 0.31997-3.359685 0.511952-5.11952 0.767928-10.271037 1.535856-15.518545 2.079805-5.983439 0.479955-12.094866 0.863919-18.270287 0.863919-12.47883 0-24.701684-1.215886-36.540574-3.327688l0 357.310502c0 29.309252 24.573696 53.11502 54.874855 53.11502l841.073149 0c30.237165 0 54.810861-23.773771 54.810861-53.11502l0-357.342499c-11.83889 2.143799-24.061744 3.327688-36.540574 3.327688-6.07943 0-12.254851-0.351967-18.23829-0.863919z" p-id="3260"></path><path d="M182.83086 109.749711l804.500578 0c30.301159 0 54.874855-24.573696 54.874855-54.874855s-24.573696-54.874855-54.874855-54.874855l-804.500578 0c-30.301159 0-54.874855 24.573696-54.874855 54.874855 0.031997 30.301159 24.605693 54.874855 54.874855 54.874855z" p-id="3261"></path><path d="M1067.387932 164.592569l-964.549573 0-102.838359 256.007999c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288l-102.806362-256.007999z" p-id="3262"></path></svg>
\ No newline at end of file
diff --git a/yudao-admin-ui/src/assets/icons/svg/pay.svg b/yudao-admin-ui/src/assets/icons/svg/pay.svg
new file mode 100644
index 000000000..ddab05def
--- /dev/null
+++ b/yudao-admin-ui/src/assets/icons/svg/pay.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635906769564" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2420" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
+</style></defs><path d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m0 921.6c-225.28 0-409.6-184.32-409.6-409.6s184.32-409.6 409.6-409.6 409.6 184.32 409.6 409.6-184.32 409.6-409.6 409.6z" p-id="2421"></path><path d="M665.6 537.6h-102.4v-51.2h102.4c25.6 0 51.2-25.6 51.2-51.2s-25.6-51.2-51.2-51.2h-30.72l20.48-20.48c20.48-20.48 20.48-51.2 0-71.68s-51.2-20.48-71.68 0L512 363.52 440.32 296.96c-20.48-20.48-51.2-20.48-71.68 0s-20.48 51.2 0 71.68l20.48 20.48H358.4c-25.6 0-51.2 25.6-51.2 51.2s25.6 51.2 51.2 51.2h102.4v51.2H358.4c-25.6 0-51.2 25.6-51.2 51.2s25.6 51.2 51.2 51.2h102.4v56.32c0 25.6 20.48 46.08 46.08 46.08h10.24c25.6 0 46.08-20.48 46.08-46.08v-56.32h102.4c25.6 0 51.2-25.6 51.2-51.2s-25.6-56.32-51.2-56.32z" p-id="2422"></path></svg>
\ No newline at end of file
diff --git a/yudao-admin-ui/src/utils/dict.js b/yudao-admin-ui/src/utils/dict.js
index ca1150a59..7c17cceb8 100644
--- a/yudao-admin-ui/src/utils/dict.js
+++ b/yudao-admin-ui/src/utils/dict.js
@@ -30,6 +30,9 @@ export const DICT_TYPE = {
   INF_API_ERROR_LOG_PROCESS_STATUS: 'inf_api_error_log_process_status',
 
   TOOL_CODEGEN_TEMPLATE_TYPE: 'tool_codegen_template_type',
+
+  // 商户状态
+  PAY_MERCHANT_STATUS: 'pay_merchant_status'
 }
 
 /**
diff --git a/yudao-admin-ui/src/views/pay/merchant/index.vue b/yudao-admin-ui/src/views/pay/merchant/index.vue
new file mode 100644
index 000000000..f57b59f96
--- /dev/null
+++ b/yudao-admin-ui/src/views/pay/merchant/index.vue
@@ -0,0 +1,295 @@
+<template>
+  <div class="app-container">
+
+    <!-- 搜索工作栏 -->
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="商户号" prop="no">
+        <el-input v-model="queryParams.no" placeholder="请输入商户号" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="商户全称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入商户全称" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="商户简称" prop="shortName">
+        <el-input v-model="queryParams.shortName" placeholder="请输入商户简称" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="开启状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small">
+          <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input v-model="queryParams.remark" placeholder="请输入备注" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
+                        type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+                   v-hasPermi="['pay:merchant:create']">新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
+                   v-hasPermi="['pay:merchant:export']">导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 列表 -->
+    <el-table v-loading="loading" :data="list">
+      <el-table-column label="商户编号" align="center" prop="id" />
+      <el-table-column label="商户号" align="center" prop="no" />
+      <el-table-column label="商户全称" align="center" prop="name" />
+      <el-table-column label="商户简称" align="center" prop="shortName" />
+      <el-table-column label="开启状态" align="center" prop="status" >
+        <template slot-scope="scope">
+          <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)" />
+        </template>
+      </el-table-column>
+      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                     v-hasPermi="['pay:merchant:update']">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                     v-hasPermi="['pay:merchant:delete']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页组件 -->
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
+                @pagination="getList"/>
+
+    <!-- 对话框(添加 / 修改) -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+<!--        <el-form-item label="商户号" prop="no">-->
+<!--          <el-input v-model="form.no" placeholder="请输入商户号" />-->
+<!--        </el-form-item>-->
+        <el-form-item label="商户全称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入商户全称" />
+        </el-form-item>
+        <el-form-item label="商户简称" prop="shortName">
+          <el-input v-model="form.shortName" placeholder="请输入商户简称" />
+        </el-form-item>
+        <el-form-item label="开启状态" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
+              {{dict.label}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" placeholder="请输入备注" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  createMerchant,
+  updateMerchant,
+  changeMerchantStatus,
+  deleteMerchant,
+  getMerchant,
+  getMerchantPage,
+  exportMerchantExcel
+} from "@/api/pay/merchant";
+import {DICT_TYPE, getDictDatas} from "@/utils/dict";
+import {SysCommonStatusEnum} from "@/utils/constants";
+
+export default {
+  name: "Merchant",
+  components: {
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 支付商户信息列表
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      dateRangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        no: null,
+        name: null,
+        shortName: null,
+        status: null,
+        remark: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        no: [{ required: true, message: "商户号不能为空", trigger: "blur" }],
+        name: [{ required: true, message: "商户全称不能为空", trigger: "blur" }],
+        shortName: [{ required: true, message: "商户简称不能为空", trigger: "blur" }],
+        status: [{ required: true, message: "开启状态不能为空", trigger: "blur" }],
+      },
+      // 数据字典
+      statusDictDatas: getDictDatas(DICT_TYPE.PAY_MERCHANT_STATUS)
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询列表 */
+    getList() {
+      this.loading = true;
+      // 处理查询参数
+      let params = {...this.queryParams};
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      // 执行查询
+      getMerchantPage(params).then(response => {
+        this.list = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    /** 取消按钮 */
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    /** 表单重置 */
+    reset() {
+      this.form = {
+        id: undefined,
+        no: undefined,
+        name: undefined,
+        shortName: undefined,
+        status: undefined,
+        remark: undefined,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加支付商户信息";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id;
+      getMerchant(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改支付商户信息";
+      });
+    },
+    // 用户状态修改
+    handleStatusChange(row) {
+      let text = row.status === SysCommonStatusEnum.ENABLE ? "启用" : "停用";
+      this.$confirm('确认要"' + text + '""' + row.name + '"商户吗?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return changeMerchantStatus(row.id, row.status);
+      }).then(() => {
+        this.msgSuccess(text + "成功");
+      }).catch(function() {
+        row.status = row.status === SysCommonStatusEnum.ENABLE ? SysCommonStatusEnum.DISABLE
+          : SysCommonStatusEnum.ENABLE;
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (!valid) {
+          return;
+        }
+        // 修改的提交
+        if (this.form.id != null) {
+          updateMerchant(this.form).then(response => {
+            this.msgSuccess("修改成功");
+            this.open = false;
+            this.getList();
+          });
+          return;
+        }
+        // 添加的提交
+        createMerchant(this.form).then(response => {
+          this.msgSuccess("新增成功");
+          this.open = false;
+          this.getList();
+        });
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const id = row.id;
+      this.$confirm('是否确认删除支付商户信息编号为"' + id + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return deleteMerchant(id);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        })
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      // 处理查询参数
+      let params = {...this.queryParams};
+      params.pageNo = undefined;
+      params.pageSize = undefined;
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      // 执行导出
+      this.$confirm('是否确认导出所有支付商户信息数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportMerchantExcel(params);
+        }).then(response => {
+          this.downloadExcel(response, '支付商户信息.xls');
+        })
+    }
+  }
+};
+</script>
diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java
index d2b20111a..b8edba7e8 100644
--- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java
+++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
@@ -29,7 +31,9 @@ public class PayMerchantDO extends BaseDO {
     /**
      * 商户号
      * 例如说,M233666999
+     * 只有新增时插入,不允许修改
      */
+    @TableField(fill = FieldFill.INSERT)
     private String no;
     /**
      * 商户全称
diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java
index d2b940223..a4c88d8c0 100644
--- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java
+++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java
@@ -28,4 +28,8 @@ public interface PayErrorCodeCoreConstants {
     ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付");
     ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007003002, "支付订单不处于已支付");
 
+    /**
+     * ========== 支付商户信息 1-007-004-000 ==========
+     */
+    ErrorCode MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
 }