Skip to content

支付关系表

1. 概述

支付关系表是梵医云系统中用于管理支付订单、退款订单、支付渠道、支付应用、分账记录、钱包等相关数据的核心模块。该模块提供了完整的支付管理体系,包括支付、退款、转账、分账、钱包充值等功能。

2. 表结构

2.1 支付订单表 (pay_order)

支付订单表是支付模块的核心表,存储支付订单的基本信息、价格信息、渠道信息等。

2.1.1 表结构

字段名类型长度允许空默认值说明
idbigint20-订单编号(主键)
merchant_idbigint20-商户ID
app_idbigint20-应用编号
channel_idbigint20-渠道编号
channel_codevarchar32-渠道编码
order_sourcevarchar64NULL订单来源
merchant_order_idvarchar64-商户订单编号
subjectvarchar128NULL商品标题
bodyvarchar512NULL商品描述信息
notify_urlvarchar512NULL异步通知地址
priceint11-支付金额(单位:分)
channel_fee_ratedouble10,4NULL渠道手续费(单位:百分比)
channel_fee_priceint110渠道手续金额(单位:分)
profit_sharingtinyint40分账状态
statustinyint4-支付状态(0待支付 1支付成功 2支付关闭)
user_ipvarchar50NULL用户IP
expire_timedatetime-NULL订单失效时间
success_timedatetime-NULL订单支付成功时间
extension_idbigint20NULL支付成功的订单拓展单编号
novarchar64NULL支付成功的外部订单号
refund_priceint110退款总金额(单位:分)
channel_user_idvarchar128NULL渠道用户编号
channel_order_novarchar64NULL渠道订单号
pay_channel_infojson-NULL支付渠道相关信息
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.1.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_merchant_order_id_app_id唯一merchant_order_id, app_id商户订单号唯一索引
idx_status普通status支付状态索引
idx_app_id普通app_id应用索引

2.1.3 Java 实体类

java
@TableName(value = "pay_order", autoResultMap = true)
@KeySequence("pay_order_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayOrderDO extends BaseDO {

    @TableId
    private Long id;
    private Long merchantId;
    private Long appId;
    private Long channelId;
    private String channelCode;
    private String orderSource;
    private String merchantOrderId;
    private String subject;
    private String body;
    private String notifyUrl;
    private Integer price;
    private Double channelFeeRate;
    private Integer channelFeePrice;
    private OrderProfitSharingEnum profitSharing;
    private Integer status;
    private String userIp;
    private LocalDateTime expireTime;
    private LocalDateTime successTime;
    private Long extensionId;
    private String no;
    private Integer refundPrice;
    private String channelUserId;
    private String channelOrderNo;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> payChannelInfo;
}

2.2 支付订单拓展表 (pay_order_extension)

支付订单拓展表用于存储每次调用支付渠道的记录。

2.2.1 表结构

字段名类型长度允许空默认值说明
idbigint20-订单拓展编号(主键)
novarchar64-外部订单号
order_idbigint20-订单编号
channel_idbigint20-渠道编号
channel_codevarchar32-渠道编码
user_ipvarchar50NULL用户IP
statustinyint4-支付状态
channel_extrasjson-NULL支付渠道的额外参数
channel_error_codevarchar128NULL调用渠道的错误码
channel_error_msgvarchar512NULL调用渠道报错时,错误信息
channel_notify_datatext-NULL支付渠道的同步/异步通知的内容
extras_infojson-NULL额外信息
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.2.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_no唯一no外部订单号唯一索引
idx_order_id普通order_id订单索引

2.2.3 Java 实体类

java
@TableName(value = "pay_order_extension", autoResultMap = true)
@KeySequence("pay_order_extension_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayOrderExtensionDO extends BaseDO {

    @TableId
    private Long id;
    private String no;
    private Long orderId;
    private Long channelId;
    private String channelCode;
    private String userIp;
    private Integer status;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, String> channelExtras;
    private String channelErrorCode;
    private String channelErrorMsg;
    private String channelNotifyData;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Object extrasInfo;
}

2.3 支付退款单表 (pay_refund)

支付退款单表用于处理支付订单的退款流程。

2.3.1 表结构

字段名类型长度允许空默认值说明
idbigint20-退款单编号(主键)
novarchar64-外部退款号
app_idbigint20-应用编号
channel_idbigint20-渠道编号
channel_codevarchar32-商户编码
order_idbigint20-订单编号
order_novarchar64-支付订单编号
merchant_order_idvarchar64NULL商户订单编号
merchant_refund_idvarchar64NULL商户退款订单号
notify_urlvarchar512NULL异步通知地址
statustinyint4-退款状态(0待退款 1退款成功 2退款失败)
pay_priceint11-支付金额(单位:分)
refund_priceint11-退款金额(单位:分)
reasonvarchar256NULL退款原因
user_ipvarchar50NULL用户IP
channel_order_novarchar64NULL渠道订单号
channel_refund_novarchar64NULL渠道退款单号
success_timedatetime-NULL退款成功时间
channel_error_codevarchar128NULL调用渠道的错误码
channel_error_msgvarchar512NULL调用渠道的错误提示
channel_notify_datatext-NULL支付渠道的同步/异步通知的内容
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.3.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_no唯一no外部退款号唯一索引
idx_order_id普通order_id订单索引

2.3.3 Java 实体类

java
@TableName("pay_refund")
@KeySequence("pay_refund_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayRefundDO extends BaseDO {

    @TableId
    private Long id;
    private String no;
    private Long appId;
    private Long channelId;
    private String channelCode;
    private Long orderId;
    private String orderNo;
    private String merchantOrderId;
    private String merchantRefundId;
    private String notifyUrl;
    private Integer status;
    private Integer payPrice;
    private Integer refundPrice;
    private String reason;
    private String userIp;
    private String channelOrderNo;
    private String channelRefundNo;
    private LocalDateTime successTime;
    private String channelErrorCode;
    private String channelErrorMsg;
    private String channelNotifyData;
}

2.4 支付应用表 (pay_app)

支付应用表用于管理支付应用信息。

2.4.1 表结构

字段名类型长度允许空默认值说明
idbigint20-应用编号(主键)
namevarchar64-应用名
statustinyint4-状态(0正常 1停用)
remarkvarchar512NULL备注
order_notify_urlvarchar512NULL支付结果的回调地址
refund_notify_urlvarchar512NULL退款结果的回调地址
transfer_notify_urlvarchar512NULL转账结果的回调地址
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.4.2 索引

索引名类型字段说明
PRIMARY主键id主键索引

2.4.3 Java 实体类

java
@TableName("pay_app")
@KeySequence("pay_app_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayAppDO extends BaseDO {

    @TableId
    private Long id;
    private String name;
    private Integer status;
    private String remark;
    private String orderNotifyUrl;
    private String refundNotifyUrl;
    private String transferNotifyUrl;
}

2.5 支付渠道表 (pay_channel)

支付渠道表用于管理支付渠道信息,如微信支付、支付宝支付等。

2.5.1 表结构

字段名类型长度允许空默认值说明
idbigint20-渠道编号(主键)
codevarchar32-渠道编码
statustinyint4-状态(0正常 1停用)
fee_ratedouble10,4-渠道费率(单位:百分比)
remarkvarchar512NULL备注
app_idbigint20-应用编号
configjson-NULL支付渠道配置
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.5.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_code_app_id唯一code, app_id渠道编码和应用唯一索引

2.5.3 Java 实体类

java
@TableName(value = "pay_channel", autoResultMap = true)
@KeySequence("pay_channel_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayChannelDO extends BaseDO {

    @TableId
    private Long id;
    private String code;
    private Integer status;
    private Double feeRate;
    private String remark;
    private Long appId;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private PayClientConfig config;
}

2.6 支付商户表 (pay_merchant)

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

2.6.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
merchant_namevarchar128-商户名称
pay_app_idbigint20NULL应用编号
pay_channel_infojson-NULL支付渠道相关信息
is_profit_sharingbit1NULL是否分账
mall_profit_sharing_percentagedecimal10,4NULL商城分账百分比
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.6.2 索引

索引名类型字段说明
PRIMARY主键id主键索引

2.6.3 Java 实体类

java
@TableName(value = "pay_merchant", autoResultMap = true)
@Data
public class PayMerchantDO extends BaseDO {

    private Long id;
    private String merchantName;
    private Long payAppId;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> payChannelInfo;
    private Boolean isProfitSharing;
    private BigDecimal mallProfitSharingPercentage;
}

2.7 支付分账记录表 (pay_profit_sharing_record)

支付分账记录表用于记录支付订单的分账信息。

2.7.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
request_novarchar64NULL请求流水号
order_idbigint20NULL商户订单ID
order_novarchar64NULL商户订单编号
pay_order_idbigint20NULL支付订单ID
channel_codevarchar32NULL支付渠道编码
payment_amountint11NULL支付金额(单位:分)
available_amountint11NULL可用的分账金额(单位:分)
profit_sharing_percentagedecimal10,4NULL分账百分比
profit_sharing_amountint11NULL实际分账金额
receiver_accountvarchar128NULL分账接收方账号
receiver_account_namevarchar128NULL分账接收方账号名称
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.7.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_pay_order_id普通pay_order_id支付订单索引

2.7.3 Java 实体类

java
@TableName("pay_profit_sharing_record")
@Data
public class PayProfitSharingRecordDO {

    private Long id;
    private String requestNo;
    private Long orderId;
    private String orderNo;
    private Long payOrderId;
    private String channelCode;
    private Integer paymentAmount;
    private Integer availableAmount;
    private BigDecimal profitSharingPercentage;
    private Integer profitSharingAmount;
    private String receiverAccount;
    private String receiverAccountName;
}

2.8 支付分账接收方表 (pay_profit_sharing_receiver)

支付分账接收方表用于配置分账接收方信息。

2.8.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
channel_codevarchar32-支付渠道编码
receiver_accountvarchar128-分账接收方账号
receiver_account_namevarchar128-分账接收方账号名称
receiver_descriptionvarchar512NULL分账描述
profit_sharing_percentagedecimal10,4-分账百分比
filter_configjson-NULL分账时用于过滤接收方的配置
is_platform_collection_accountbit1NULL是否平台代收账号
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.8.2 索引

索引名类型字段说明
PRIMARY主键id主键索引

2.8.3 Java 实体类

java
@TableName(value = "pay_profit_sharing_receiver", autoResultMap = true)
@Data
public class PayProfitSharingReceiverDO {

    private Long id;
    private String channelCode;
    private String receiverAccount;
    private String receiverAccountName;
    private String receiverDescription;
    private BigDecimal profitSharingPercentage;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private PayProfitSharingFilterConfig filterConfig;
    private Boolean isPlatformCollectionAccount;
}

2.9 支付转账单表 (pay_transfer)

支付转账单表用于处理转账业务。

2.9.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
novarchar64-转账单号
app_idbigint20-应用编号
channel_idbigint20-转账渠道编号
channel_codevarchar32-转账渠道编码
merchant_transfer_idvarchar64NULL商户转账单编号
typetinyint4-类型
subjectvarchar128NULL转账标题
priceint11-转账金额(单位:分)
user_namevarchar64NULL收款人姓名
statustinyint4-转账状态
success_timedatetime-NULL订单转账成功时间
alipay_logon_idvarchar128NULL支付宝登录号
openidvarchar128NULL微信openId
notify_urlvarchar512NULL异步通知地址
user_ipvarchar50NULL用户IP
channel_extrasjson-NULL渠道的额外参数
channel_transfer_novarchar64NULL渠道转账单号
channel_error_codevarchar128NULL调用渠道的错误码
channel_error_msgvarchar512NULL调用渠道的错误提示
channel_notify_datatext-NULL渠道的同步/异步通知的内容
bank_accountvarchar128NULL银行账号
merchant_idbigint20NULL商户id
merchant_namevarchar128NULL商户名称
service_network_idvarchar64NULL提现网点id
service_networkvarchar128NULL提现网点
audit_statustinyint4NULL审核状态
audit_reasonvarchar512NULL审核原因
user_idbigint20NULL用户id
withdraw_idint11NULL提现id
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.9.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_no唯一no转账单号唯一索引

2.9.3 Java 实体类

java
@TableName(value = "pay_transfer", autoResultMap = true)
@KeySequence("pay_transfer_seq")
@Data
public class PayTransferDO extends BaseDO {

    @TableId
    private Long id;
    private String no;
    private Long appId;
    private Long channelId;
    private String channelCode;
    private String merchantTransferId;
    private Integer type;
    private String subject;
    private Integer price;
    private String userName;
    private Integer status;
    private LocalDateTime successTime;
    private String alipayLogonId;
    private String openid;
    private String notifyUrl;
    private String userIp;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, String> channelExtras;
    private String channelTransferNo;
    private String channelErrorCode;
    private String channelErrorMsg;
    private String channelNotifyData;
    private String bankAccount;
    private Long merchantId;
    private String merchantName;
    private String serviceNetworkId;
    private String serviceNetwork;
    private Integer auditStatus;
    private String auditReason;
    private Long userId;
    private Integer withdrawId;
}

2.10 支付通知任务表 (pay_notify_task)

支付通知任务表用于管理支付、退款等通知任务。

2.10.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
app_idbigint20-应用编号
typetinyint4-通知类型
data_idbigint20-数据编号
merchant_order_idvarchar64NULL商户订单编号
merchant_transfer_idvarchar64NULL商户转账单编号
statustinyint4-通知状态(0待通知 1通知成功 2通知失败)
next_notify_timedatetime--下一次通知时间
last_execute_timedatetime-NULL最后一次执行时间
notify_timesint110当前通知次数
max_notify_timesint11-最大可通知次数
notify_urlvarchar512-通知地址
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.10.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_next_notify_time普通next_notify_time下一次通知时间索引

2.10.3 Java 实体类

java
@TableName("pay_notify_task")
@KeySequence("pay_notify_task_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class PayNotifyTaskDO extends BaseDO {

    public static final Integer[] NOTIFY_FREQUENCY = new Integer[]{
            15, 15, 30, 180,
            1800, 1800, 1800, 3600
    };

    @TableId
    private Long id;
    private Long appId;
    private Integer type;
    private Long dataId;
    private String merchantOrderId;
    private String merchantTransferId;
    private Integer status;
    private LocalDateTime nextNotifyTime;
    private LocalDateTime lastExecuteTime;
    private Integer notifyTimes;
    private Integer maxNotifyTimes;
    private String notifyUrl;
}

2.11 支付通知日志表 (pay_notify_log)

支付通知日志表用于记录支付、退款等通知的日志。

2.11.1 表结构

字段名类型长度允许空默认值说明
idbigint20-日志编号(主键)
task_idbigint20-通知任务编号
notify_timesint11-第几次被通知
responsetext-NULLHTTP响应结果
statustinyint4-支付通知状态
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.11.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_task_id普通task_id通知任务索引

2.11.3 Java 实体类

java
@TableName("pay_notify_log")
@KeySequence("pay_notify_log_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayNotifyLogDO extends BaseDO {

    @TableId
    private Long id;
    private Long taskId;
    private Integer notifyTimes;
    private String response;
    private Integer status;
}

2.12 支付钱包表 (pay_wallet)

支付钱包表用于管理用户的钱包信息。

2.12.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
user_idbigint20-用户id
user_typetinyint4-用户类型
balanceint110余额(单位分)
freeze_priceint110冻结金额(单位分)
total_expenseint110累计支出(单位分)
total_rechargeint110累计充值(单位分)
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.12.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_user_id_user_type唯一user_id, user_type用户唯一索引

2.12.3 Java 实体类

java
@TableName(value = "pay_wallet")
@KeySequence("pay_wallet_seq")
@Data
public class PayWalletDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private Integer userType;
    private Integer balance;
    private Integer freezePrice;
    private Integer totalExpense;
    private Integer totalRecharge;
}

2.13 钱包充值表 (pay_wallet_recharge)

钱包充值表用于管理钱包充值记录。

2.13.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
wallet_idbigint20-钱包编号
total_priceint11-用户实际到账余额
pay_priceint11-实际支付金额
bonus_priceint110钱包赠送金额
package_idbigint20NULL充值套餐编号
pay_statusbit1b'0'是否已支付
pay_order_idbigint20NULL支付订单编号
pay_channel_codevarchar32NULL支付成功的支付渠道
pay_timedatetime-NULL订单支付时间
pay_refund_idbigint20NULL支付退款单编号
refund_total_priceint11NULL退款金额(包含赠送金额)
refund_pay_priceint11NULL退款支付金额
refund_bonus_priceint11NULL退款钱包赠送金额
refund_timedatetime-NULL退款时间
refund_statustinyint4NULL退款状态
remarkvarchar512NULL备注
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.13.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_wallet_id普通wallet_id钱包索引

2.13.3 Java 实体类

java
@TableName(value = "pay_wallet_recharge")
@KeySequence("pay_wallet_recharge_seq")
@Data
public class PayWalletRechargeDO extends BaseDO {

    @TableId
    private Long id;
    private Long walletId;
    private Integer totalPrice;
    private Integer payPrice;
    private Integer bonusPrice;
    private Long packageId;
    private Boolean payStatus;
    private Long payOrderId;
    private String payChannelCode;
    private LocalDateTime payTime;
    private Long payRefundId;
    private Integer refundTotalPrice;
    private Integer refundPayPrice;
    private Integer refundBonusPrice;
    private LocalDateTime refundTime;
    private Integer refundStatus;
    private String remark;
}

2.14 钱包流水表 (pay_wallet_transaction)

钱包流水表用于记录钱包的交易流水。

2.14.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
novarchar64-流水号
wallet_idbigint20-钱包编号
biz_typetinyint4-关联业务分类
biz_idvarchar64NULL关联业务编号
titlevarchar128NULL流水说明
priceint11-交易金额(单位分)
balanceint11-交易后余额(单位分)
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.14.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_no唯一no流水号唯一索引
idx_wallet_id普通wallet_id钱包索引

2.14.3 Java 实体类

java
@TableName(value = "pay_wallet_transaction")
@KeySequence("pay_wallet_transaction_seq")
@Data
public class PayWalletTransactionDO extends BaseDO {

    @TableId
    private Long id;
    private String no;
    private Long walletId;
    private Integer bizType;
    private String bizId;
    private String title;
    private Integer price;
    private Integer balance;
}

2.15 钱包充值套餐表 (pay_wallet_recharge_package)

钱包充值套餐表用于管理充值套餐信息。

2.15.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
namevarchar64-套餐名
pay_priceint11-支付金额
bonus_priceint110赠送金额
statustinyint4-状态(0正常 1停用)
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.15.2 索引

索引名类型字段说明
PRIMARY主键id主键索引

2.15.3 Java 实体类

java
@TableName(value = "pay_wallet_recharge_package")
@KeySequence("pay_wallet_recharge_package_seq")
@Data
public class PayWalletRechargePackageDO extends BaseDO {

    @TableId
    private Long id;
    private String name;
    private Integer payPrice;
    private Integer bonusPrice;
    private Integer status;
}

3. 表关系图

pay_app (支付应用表)
    ├── pay_channel (支付渠道表) - 通过 app_id 关联
    ├── pay_order (支付订单表) - 通过 app_id 关联
    ├── pay_refund (支付退款单表) - 通过 app_id 关联
    ├── pay_transfer (支付转账单表) - 通过 app_id 关联
    └── pay_notify_task (支付通知任务表) - 通过 app_id 关联

pay_channel (支付渠道表)
    ├── pay_order (支付订单表) - 通过 channel_id 关联
    ├── pay_order_extension (支付订单拓展表) - 通过 channel_id 关联
    ├── pay_refund (支付退款单表) - 通过 channel_id 关联
    └── pay_transfer (支付转账单表) - 通过 channel_id 关联

pay_order (支付订单表)
    ├── pay_order_extension (支付订单拓展表) - 通过 order_id 关联
    ├── pay_refund (支付退款单表) - 通过 order_id 关联
    ├── pay_profit_sharing_record (支付分账记录表) - 通过 pay_order_id 关联
    └── pay_notify_task (支付通知任务表) - 通过 data_id 关联

pay_refund (支付退款单表)
    └── pay_notify_task (支付通知任务表) - 通过 data_id 关联

pay_wallet (支付钱包表)
    ├── pay_wallet_recharge (钱包充值表) - 通过 wallet_id 关联
    └── pay_wallet_transaction (钱包流水表) - 通过 wallet_id 关联

pay_notify_task (支付通知任务表)
    └── pay_notify_log (支付通知日志表) - 通过 task_id 关联

4. 使用示例

4.1 创建支付订单

java
@Service
public class PayOrderServiceImpl implements PayOrderService {

    @Resource
    private PayOrderMapper payOrderMapper;

    @Resource
    private PayOrderExtensionMapper payOrderExtensionMapper;

    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(PayOrderCreateReqVO createReqVO) {
        PayOrderDO order = PayOrderDO.builder()
            .merchantId(createReqVO.getMerchantId())
            .appId(createReqVO.getAppId())
            .channelId(createReqVO.getChannelId())
            .channelCode(createReqVO.getChannelCode())
            .merchantOrderId(createReqVO.getMerchantOrderId())
            .subject(createReqVO.getSubject())
            .body(createReqVO.getBody())
            .notifyUrl(createReqVO.getNotifyUrl())
            .price(createReqVO.getPrice())
            .status(PayOrderStatusEnum.UNPAID.getStatus())
            .build();
        
        payOrderMapper.insert(order);

        PayOrderExtensionDO extension = PayOrderExtensionDO.builder()
            .no(generateOrderNo())
            .orderId(order.getId())
            .channelId(createReqVO.getChannelId())
            .channelCode(createReqVO.getChannelCode())
            .userIp(createReqVO.getUserIp())
            .status(PayOrderStatusEnum.UNPAID.getStatus())
            .build();
        
        payOrderExtensionMapper.insert(extension);
        return order.getId();
    }
}

4.2 支付订单成功

java
@Service
public class PayOrderServiceImpl implements PayOrderService {

    @Resource
    private PayOrderMapper payOrderMapper;

    @Resource
    private PayOrderExtensionMapper payOrderExtensionMapper;

    @Transactional(rollbackFor = Exception.class)
    public void successOrder(Long orderId, String channelOrderNo, Map<String, Object> channelNotifyData) {
        PayOrderDO order = payOrderMapper.selectById(orderId);
        if (order == null) {
            throw exception(ORDER_NOT_EXISTS);
        }

        PayOrderExtensionDO extension = payOrderExtensionMapper.selectOne(
            new LambdaQueryWrapperX<PayOrderExtensionDO>()
                .eq(PayOrderExtensionDO::getOrderId, orderId)
                .orderByDesc(PayOrderExtensionDO::getId)
                .last("LIMIT 1")
        );

        payOrderMapper.updateById(PayOrderDO.builder()
            .id(orderId)
            .status(PayOrderStatusEnum.SUCCESS.getStatus())
            .successTime(LocalDateTime.now())
            .extensionId(extension.getId())
            .no(extension.getNo())
            .channelOrderNo(channelOrderNo)
            .payChannelInfo(channelNotifyData)
            .build());

        payOrderExtensionMapper.updateById(PayOrderExtensionDO.builder()
            .id(extension.getId())
            .status(PayOrderStatusEnum.SUCCESS.getStatus())
            .channelNotifyData(JSON.toJSONString(channelNotifyData))
            .build());
    }
}

4.3 创建退款订单

java
@Service
public class PayRefundServiceImpl implements PayRefundService {

    @Resource
    private PayRefundMapper payRefundMapper;

    @Transactional(rollbackFor = Exception.class)
    public Long createRefund(PayRefundCreateReqVO createReqVO) {
        PayRefundDO refund = PayRefundDO.builder()
            .no(generateRefundNo())
            .appId(createReqVO.getAppId())
            .channelId(createReqVO.getChannelId())
            .channelCode(createReqVO.getChannelCode())
            .orderId(createReqVO.getOrderId())
            .orderNo(createReqVO.getOrderNo())
            .merchantOrderId(createReqVO.getMerchantOrderId())
            .merchantRefundId(createReqVO.getMerchantRefundId())
            .notifyUrl(createReqVO.getNotifyUrl())
            .status(PayRefundStatusEnum.CREATE.getStatus())
            .payPrice(createReqVO.getPayPrice())
            .refundPrice(createReqVO.getRefundPrice())
            .reason(createReqVO.getReason())
            .userIp(createReqVO.getUserIp())
            .build();
        
        payRefundMapper.insert(refund);
        return refund.getId();
    }
}

4.4 退款成功

java
@Service
public class PayRefundServiceImpl implements PayRefundService {

    @Resource
    private PayRefundMapper payRefundMapper;

    @Resource
    private PayOrderMapper payOrderMapper;

    @Transactional(rollbackFor = Exception.class)
    public void successRefund(Long refundId, String channelRefundNo, String channelNotifyData) {
        PayRefundDO refund = payRefundMapper.selectById(refundId);
        if (refund == null) {
            throw exception(REFUND_NOT_EXISTS);
        }

        payRefundMapper.updateById(PayRefundDO.builder()
            .id(refundId)
            .status(PayRefundStatusEnum.SUCCESS.getStatus())
            .channelRefundNo(channelRefundNo)
            .successTime(LocalDateTime.now())
            .channelNotifyData(channelNotifyData)
            .build());

        payOrderMapper.updateById(PayOrderDO.builder()
            .id(refund.getOrderId())
            .refundPrice(refund.getRefundPrice())
            .build());
    }
}

4.5 钱包充值

java
@Service
public class PayWalletServiceImpl implements PayWalletService {

    @Resource
    private PayWalletMapper payWalletMapper;

    @Resource
    private PayWalletRechargeMapper payWalletRechargeMapper;

    @Resource
    private PayWalletTransactionMapper payWalletTransactionMapper;

    @Transactional(rollbackFor = Exception.class)
    public void recharge(Long userId, Integer payPrice, Integer bonusPrice, Long packageId) {
        PayWalletDO wallet = payWalletMapper.selectOne(
            new LambdaQueryWrapperX<PayWalletDO>()
                .eq(PayWalletDO::getUserId, userId)
                .eq(PayWalletDO::getUserType, UserTypeEnum.MEMBER.getValue())
        );

        if (wallet == null) {
            wallet = PayWalletDO.builder()
                .userId(userId)
                .userType(UserTypeEnum.MEMBER.getValue())
                .balance(0)
                .freezePrice(0)
                .totalExpense(0)
                .totalRecharge(0)
                .build();
            payWalletMapper.insert(wallet);
        }

        Integer totalPrice = payPrice + bonusPrice;
        Integer balance = wallet.getBalance() + totalPrice;

        payWalletMapper.updateById(PayWalletDO.builder()
            .id(wallet.getId())
            .balance(balance)
            .totalRecharge(wallet.getTotalRecharge() + payPrice)
            .build());

        PayWalletRechargeDO recharge = PayWalletRechargeDO.builder()
            .walletId(wallet.getId())
            .totalPrice(totalPrice)
            .payPrice(payPrice)
            .bonusPrice(bonusPrice)
            .packageId(packageId)
            .payStatus(true)
            .payTime(LocalDateTime.now())
            .build();
        payWalletRechargeMapper.insert(recharge);

        PayWalletTransactionDO transaction = PayWalletTransactionDO.builder()
            .no(generateTransactionNo())
            .walletId(wallet.getId())
            .bizType(PayWalletBizTypeEnum.RECHARGE.getType())
            .bizId(recharge.getId().toString())
            .title("钱包充值")
            .price(totalPrice)
            .balance(balance)
            .build();
        payWalletTransactionMapper.insert(transaction);
    }
}

5. 业务规则

5.1 支付订单状态流转

  1. 待支付 → 支付成功(用户支付成功)
  2. 待支付 → 支付关闭(超时未支付或用户取消)

5.2 退款订单状态流转

  1. 待退款 → 退款成功(退款成功)
  2. 待退款 → 退款失败(退款失败)

5.3 通知规则

  1. 通知频率:15s、15s、30s、180s、1800s、1800s、1800s、3600s
  2. 最大通知次数:9次
  3. 通知成功后不再重复通知

5.4 分账规则

  1. 分账在支付成功后进行
  2. 分账金额 = 支付金额 - 运费等不可分账金额
  3. 分账接收方需要提前配置

5.5 钱包规则

  1. 钱包余额不能为负数
  2. 充值可以赠送金额
  3. 所有交易都需要记录流水

6. 注意事项

  1. 商户订单号在每个应用下必须唯一
  2. 外部订单号必须全局唯一
  3. 支付订单状态变更时,需要同步更新订单拓展表
  4. 退款金额不能超过支付金额
  5. 通知任务需要定时任务处理
  6. 钱包充值需要记录流水
  7. 分账接收方需要提前配置
  8. 所有金额单位都是分

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