Skip to content

支付表 ​

1. 概述 ​

支付表是梵医云系统中支付模块的扩展表,用于管理微信子商户、银行信息、OCR识别、媒体文件、分账接收方激活、示例订单等辅助功能。这些表与核心支付关系表配合使用,提供完整的支付生态支持。

2. 表结构 ​

2.1 微信子商户表 (pay_wx_sub_merchant) ​

微信子商户表用于管理微信支付的子商户信息。

2.1.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-编号(主键)
business_codevarchar64是NULL业务编码
company_namevarchar128是NULL公司名称
pay_app_idbigint20是NULL支付应用ID
pay_channel_idbigint20是NULL支付渠道ID
applyment_idvarchar64是NULL申请单号
sub_mchidvarchar64是NULL子商户号
sign_urlvarchar512是NULL签约链接
applyment_statetinyint4是NULL申请状态
pay_merchant_idbigint20是NULL支付商户ID
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.1.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_business_code普通business_code业务编码索引

2.1.3 Java 实体类 ​

java
@TableName(value = "pay_wx_sub_merchant")
@Data
public class PayWxSubMerchantDO {

    private Long id;
    private String businessCode;
    private String companyName;
    private Long payAppId;
    private Long payChannelId;
    private String applymentId;
    private String subMchid;
    private String signUrl;
    private SubMerchantApplymentStateEnum applymentState;
    private Long payMerchantId;
}

2.1.4 申请状态枚举 ​

java
public enum SubMerchantApplymentStateEnum {
    APPLYING(0, "申请中"),
    APPLY_SUCCESS(1, "申请成功"),
    APPLY_FAIL(2, "申请失败"),
    CANCEL(3, "已取消");
}

2.2 微信结算规则表 (pay_wx_settlement_rule) ​

微信结算规则表用于管理微信支付的结算规则信息。

2.2.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-编号(主键)
settlement_idint11否-结算ID
subject_typevarchar64是NULL主体类型
settlement_descvarchar512是NULL结算描述
applicable_industries_overviewvarchar512是NULL适用行业概述
industry_idint11是NULL行业ID
industry_namevarchar128是NULL行业名称
special_qualification_requiredvarchar512是NULL特殊资质要求
special_qualificationvarchar512是NULL特殊资质
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.2.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_settlement_id普通settlement_id结算ID索引

2.2.3 Java 实体类 ​

java
@TableName(value = "pay_wx_settlement_rule")
@Data
public class PayWxSettlementRuleDO {

    private Long id;
    private Integer settlementId;
    private String subjectType;
    private String settlementDesc;
    private String applicableIndustriesOverview;
    private Integer industryId;
    private String industryName;
    private String specialQualificationRequired;
    private String specialQualification;
}

2.3 OCR识别表 (pay_ocr) ​

OCR识别表用于存储OCR识别结果,主要用于身份证识别等场景。

2.3.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-编号(主键)
file_sha256varchar64是NULL文件SHA256值
ocr_typeint11是NULLOCR类型(1-身份证)
ocr_restext-是NULLOCR识别结果(JSON格式)
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.3.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_file_sha256普通file_sha256文件SHA256索引

2.3.3 Java 实体类 ​

java
@TableName(value = "pay_ocr")
@Data
public class PayOcrDO {

    private Long id;
    private String fileSha256;
    private Integer ocrType;
    private String ocrRes;

    public IdcardRes toIdcardRes() {
        try {
            ObjectMapper om = new ObjectMapper();
            JsonNode root = om.readTree(ocrRes).get("idcard_res");
            IdcardRes res = new IdcardRes();
            res.type = root.get("type").asInt();
            if (res.type == 0) {
                res.name = root.get("name").get("text").asText();
                res.id = root.get("id").get("text").asText();
                res.address = root.get("address").get("text").asText();
                res.gender = root.get("gender").get("text").asText();
                res.nationality = root.get("nationality").get("text").asText();
            } else {
                res.validDate = root.get("valid_date").get("text").asText();
            }
            return res;
        } catch (JsonProcessingException ex) {
            throw new RuntimeException(ex);
        }
    }

    @ToString
    public static class IdcardRes {
        public int type;
        public String name;
        public String id;
        public String address;
        public String gender;
        public String nationality;
        public String validDate;
    }
}

2.4 银行信息表 (pay_bank_info) ​

银行信息表用于管理银行的基本信息。

2.4.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-编号(主键)
bank_aliasvarchar64否-银行别名
bank_alias_codevarchar32否-银行别名编码
account_bankvarchar128否-开户银行
account_bank_codeint11否-开户银行编码
need_bank_branchbit1否b'0'是否需要填写支行
is_corporatebit1否b'0'是否支持对公业务
is_personalbit1否b'0'是否支持个人业务
sortint11否0排序
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.4.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_bank_alias_code普通bank_alias_code银行别名编码索引

2.4.3 Java 实体类 ​

java
@TableName(value = "pay_bank_info")
@Data
public class PayBankInfoDO {

    private Long id;
    private String bankAlias;
    private String bankAliasCode;
    private String accountBank;
    private Integer accountBankCode;
    private Boolean needBankBranch;
    private Boolean isCorporate;
    private Boolean isPersonal;
    private Integer sort;
}

2.5 银行支行表 (pay_bank_branches) ​

银行支行表用于管理银行的支行信息。

2.5.1 表结构 ​

字段名类型长度允许空默认值说明
idint11否-编号(主键)
bank_codevarchar32否-银行编码
bank_namevarchar128否-银行名称
province_namevarchar64否-省份名称
province_codeint11否-省份编码
city_namevarchar64否-城市名称
city_codeint11否-城市编码
bank_branch_namevarchar128否-银行支行名称
bank_branch_idvarchar64否-银行支行ID

2.5.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_bank_code普通bank_code银行编码索引
idx_province_code普通province_code省份编码索引
idx_city_code普通city_code城市编码索引

2.5.3 Java 实体类 ​

java
@TableName(value = "pay_bank_branches")
@Data
public class PayBankBranchesDO {

    private Integer id;
    private String bankCode;
    private String bankName;
    private String provinceName;
    private Integer provinceCode;
    private String cityName;
    private Integer cityCode;
    private String bankBranchName;
    private String bankBranchId;
}

2.6 银行地区表 (pay_bank_area) ​

银行地区表用于管理银行支持的地区信息。

2.6.1 表结构 ​

字段名类型长度允许空默认值说明
idint11否-编号(主键)
pidint11否-父级ID
codeint11否-地区编码
namevarchar64否-地区名称

2.6.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_pid普通pid父级ID索引

2.6.3 Java 实体类 ​

java
@TableName(value = "pay_bank_area")
@Data
public class PayBankAreaDO {

    private Integer id;
    private Integer pid;
    private Integer code;
    private String name;

    @TableField(exist = false)
    private List<PayBankAreaDO> children;
}

2.7 支付媒体表 (pay_media) ​

支付媒体表用于管理支付相关的媒体文件。

2.7.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-编号(主键)
typevarchar32是NULL文件类型
file_sha256varchar64是NULL文件SHA256值
urlvarchar512是NULL文件URL
extensionvarchar16是NULL文件扩展名
sizeint11是NULL文件大小(字节)
wx_media_idvarchar128是NULL微信媒体ID
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.7.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_file_sha256普通file_sha256文件SHA256索引

2.7.3 Java 实体类 ​

java
@TableName(value = "pay_media")
@Data
public class PayMediaDO {

    private Long id;
    private String type;
    private String fileSha256;
    private String url;
    private String extension;
    private Integer size;
    private String wxMediaId;
}

2.8 分账接收方激活表 (pay_profit_sharing_receiver_activated) ​

分账接收方激活表用于管理已激活的分账接收方信息。

2.8.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-编号(主键)
receiver_group_novarchar64是NULL接收方分组号
receiver_accountvarchar128是NULL分账接收方账号
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.8.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_receiver_group_no普通receiver_group_no接收方分组号索引

2.8.3 Java 实体类 ​

java
@TableName("pay_profit_sharing_receiver_activated")
@Data
public class PayProfitSharingReceiverActivatedDO {

    private Long id;
    private String receiverGroupNo;
    private String receiverAccount;
}

2.9 示例转账订单表 (pay_demo_transfer) ​

示例转账订单表用于演示转账业务。

2.9.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-订单编号(主键)
app_idbigint20否-应用编号
typetinyint4否-转账类型
priceint11否-转账金额(单位:分)
user_namevarchar64是NULL收款人姓名
alipay_logon_idvarchar128是NULL支付宝登录号
openidvarchar128是NULL微信openId
transfer_statustinyint4是NULL转账状态
pay_transfer_idbigint20是NULL转账单编号
pay_channel_codevarchar32是NULL转账支付成功渠道
transfer_timedatetime-是NULL转账支付时间
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.9.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_pay_transfer_id普通pay_transfer_id转账单编号索引

2.9.3 Java 实体类 ​

java
@TableName(value = "pay_demo_transfer", autoResultMap = true)
@KeySequence("pay_demo_transfer_seq")
@Data
public class PayDemoTransferDO extends BaseDO {

    @TableId
    private Long id;
    private Long appId;
    private Integer type;
    private Integer price;
    private String userName;
    private String alipayLogonId;
    private String openid;
    private Integer transferStatus;
    private Long payTransferId;
    private String payChannelCode;
    private LocalDateTime transferTime;
}

2.10 示例订单表 (pay_demo_order) ​

示例订单表用于演示业务系统的订单如何接入支付系统的支付与退款。

2.10.1 表结构 ​

字段名类型长度允许空默认值说明
idbigint20否-订单编号(主键)
user_idbigint20否-用户编号
spu_idbigint20否-商品编号
spu_namevarchar128否-商品名称
priceint11否-价格(单位:分)
pay_statusbit1否b'0'是否支付
pay_order_idbigint20是NULL支付订单编号
pay_timedatetime-是NULL付款时间
pay_channel_codevarchar32是NULL支付渠道
pay_refund_idbigint20是NULL支付退款单号
refund_priceint11是NULL退款金额(单位:分)
refund_timedatetime-是NULL退款完成时间
creatorvarchar64是''创建者
create_timedatetime-否CURRENT_TIMESTAMP创建时间
updatervarchar64是''更新者
update_timedatetime-否CURRENT_TIMESTAMP更新时间
deletedbit1否b'0'是否删除

2.10.2 索引 ​

索引名类型字段说明
PRIMARY主键id主键索引
idx_pay_order_id普通pay_order_id支付订单编号索引
idx_pay_refund_id普通pay_refund_id支付退款单号索引

2.10.3 Java 实体类 ​

java
@TableName("pay_demo_order")
@KeySequence("pay_demo_order_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayDemoOrderDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private Long spuId;
    private String spuName;
    private Integer price;
    private Boolean payStatus;
    private Long payOrderId;
    private LocalDateTime payTime;
    private String payChannelCode;
    private Long payRefundId;
    private Integer refundPrice;
    private LocalDateTime refundTime;
}

3. 表关系图 ​

pay_wx_sub_merchant (微信子商户表)
    ├── pay_app (支付应用表) - 通过 pay_app_id 关联
    └── pay_channel (支付渠道表) - 通过 pay_channel_id 关联

pay_wx_settlement_rule (微信结算规则表)
    └── 无直接关联

pay_ocr (OCR识别表)
    └── 无直接关联

pay_bank_info (银行信息表)
    └── 无直接关联

pay_bank_branches (银行支行表)
    ├── pay_bank_info (银行信息表) - 通过 bank_code 关联
    └── pay_bank_area (银行地区表) - 通过 province_code 和 city_code 关联

pay_bank_area (银行地区表)
    └── 自关联 - 通过 pid 关联父级

pay_media (支付媒体表)
    └── 无直接关联

pay_profit_sharing_receiver_activated (分账接收方激活表)
    └── pay_profit_sharing_receiver (分账接收方表) - 通过 receiver_account 关联

pay_demo_transfer (示例转账订单表)
    ├── pay_app (支付应用表) - 通过 app_id 关联
    └── pay_transfer (支付转账单表) - 通过 pay_transfer_id 关联

pay_demo_order (示例订单表)
    ├── pay_order (支付订单表) - 通过 pay_order_id 关联
    └── pay_refund (支付退款单表) - 通过 pay_refund_id 关联

4. 使用示例 ​

4.1 创建微信子商户 ​

java
@Service
public class PayWxSubMerchantServiceImpl implements PayWxSubMerchantService {

    @Resource
    private PayWxSubMerchantMapper payWxSubMerchantMapper;

    public Long createSubMerchant(PayWxSubMerchantCreateReqVO createReqVO) {
        PayWxSubMerchantDO subMerchant = new PayWxSubMerchantDO();
        subMerchant.setBusinessCode(generateBusinessCode());
        subMerchant.setCompanyName(createReqVO.getCompanyName());
        subMerchant.setPayAppId(createReqVO.getPayAppId());
        subMerchant.setPayChannelId(createReqVO.getPayChannelId());
        subMerchant.setApplymentState(SubMerchantApplymentStateEnum.APPLYING);
        subMerchant.setPayMerchantId(createReqVO.getPayMerchantId());
        
        payWxSubMerchantMapper.insert(subMerchant);
        return subMerchant.getId();
    }
}

4.2 OCR身份证识别 ​

java
@Service
public class PayOcrServiceImpl implements PayOcrService {

    @Resource
    private PayOcrMapper payOcrMapper;

    public PayOcrDO.IdcardRes idcardOcr(String fileSha256, String ocrRes) {
        PayOcrDO ocr = new PayOcrDO();
        ocr.setFileSha256(fileSha256);
        ocr.setOcrType(1);
        ocr.setOcrRes(ocrRes);
        
        payOcrMapper.insert(ocr);
        return ocr.toIdcardRes();
    }
}

4.3 查询银行支行 ​

java
@Service
public class PayBankServiceImpl implements PayBankService {

    @Resource
    private PayBankBranchesMapper payBankBranchesMapper;

    public List<PayBankBranchesDO> getBankBranches(String bankCode, Integer provinceCode, Integer cityCode) {
        return payBankBranchesMapper.selectList(
            new LambdaQueryWrapperX<PayBankBranchesDO>()
                .eq(PayBankBranchesDO::getBankCode, bankCode)
                .eq(PayBankBranchesDO::getProvinceCode, provinceCode)
                .eq(PayBankBranchesDO::getCityCode, cityCode)
        );
    }
}

4.4 示例订单支付 ​

java
@Service
public class PayDemoOrderServiceImpl implements PayDemoOrderService {

    @Resource
    private PayDemoOrderMapper payDemoOrderMapper;

    @Resource
    private PayOrderService payOrderService;

    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(PayDemoOrderCreateReqVO createReqVO) {
        PayDemoOrderDO order = PayDemoOrderDO.builder()
            .userId(createReqVO.getUserId())
            .spuId(createReqVO.getSpuId())
            .spuName(createReqVO.getSpuName())
            .price(createReqVO.getPrice())
            .payStatus(false)
            .build();
        
        payDemoOrderMapper.insert(order);

        Long payOrderId = payOrderService.createOrder(
            PayOrderCreateReqVO.builder()
                .merchantOrderId(order.getId().toString())
                .subject(order.getSpuName())
                .price(order.getPrice())
                .build()
        );

        order.setPayOrderId(payOrderId);
        payDemoOrderMapper.updateById(order);
        return order.getId();
    }
}

4.5 示例转账 ​

java
@Service
public class PayDemoTransferServiceImpl implements PayDemoTransferService {

    @Resource
    private PayDemoTransferMapper payDemoTransferMapper;

    @Resource
    private PayTransferService payTransferService;

    @Transactional(rollbackFor = Exception.class)
    public Long createTransfer(PayDemoTransferCreateReqVO createReqVO) {
        PayDemoTransferDO transfer = PayDemoTransferDO.builder()
            .appId(createReqVO.getAppId())
            .type(createReqVO.getType())
            .price(createReqVO.getPrice())
            .userName(createReqVO.getUserName())
            .alipayLogonId(createReqVO.getAlipayLogonId())
            .openid(createReqVO.getOpenid())
            .transferStatus(0)
            .build();
        
        payDemoTransferMapper.insert(transfer);

        Long payTransferId = payTransferService.createTransfer(
            PayTransferCreateReqVO.builder()
                .appId(transfer.getAppId())
                .type(transfer.getType())
                .price(transfer.getPrice())
                .userName(transfer.getUserName())
                .alipayLogonId(transfer.getAlipayLogonId())
                .openid(transfer.getOpenid())
                .build()
        );

        transfer.setPayTransferId(payTransferId);
        payDemoTransferMapper.updateById(transfer);
        return transfer.getId();
    }
}

5. 业务规则 ​

5.1 微信子商户申请流程 ​

  1. 提交申请信息
  2. 生成申请单号
  3. 等待微信审核
  4. 审核通过后获取子商户号

5.2 OCR识别规则 ​

  1. 支持身份证正反面识别
  2. 使用文件SHA256作为唯一标识
  3. 识别结果以JSON格式存储

5.3 银行信息规则 ​

  1. 银行信息按排序字段排序
  2. 支持对公和个人业务
  3. 部分银行需要填写支行信息

5.4 示例订单规则 ​

  1. 订单支付前需要先创建支付订单
  2. 支付成功后更新订单状态
  3. 退款需要先创建退款订单

5.5 示例转账规则 ​

  1. 转账前需要先创建转账订单
  2. 转账成功后更新转账状态
  3. 支持支付宝和微信转账

6. 注意事项 ​

  1. 微信子商户申请需要通过微信审核
  2. OCR识别结果需要妥善保存
  3. 银行支行数据量大,建议使用缓存
  4. 示例订单和转账仅用于演示,实际业务需要根据需求调整
  5. 所有金额单位都是分
  6. 文件SHA256用于唯一标识文件,避免重复上传
  7. 分账接收方激活后才能参与分账

注意:本文档持续更新中,如有问题请及时反馈。