data-model.md 4.0 KB

Data Model: OMG AIO 创建支付尝试

pos_order_omg_attempt

首阶段采用追加式支付尝试表。只允许创建 CREATED,不在本阶段定义付款、失败、过期或退款状态。

Column Type Null Meaning
id BIGINT No 自增主键
dd_id VARCHAR(64) No pos_order.dd_id
merchant_trade_no VARCHAR(20) ASCII binary No OMG MerchantTradeNo,全局唯一
store_id BIGINT No 创建时订单门店快照
merchant_id VARCHAR(10) ASCII binary No 创建时门店 MerchantID 快照
amount INT No 创建时整数 TWD 金额快照
attempt_status TINYINT No 0=CREATED
active_dd_id VARCHAR(64) generated Yes status=0 时等于 dd_id,否则 NULL
create_time DATETIME No 本地创建时间
update_time DATETIME No 本地更新时间

DDL to append to updatesql/sql.md

2026-08-13 OMG AIO 创建支付订单从零重建(020-omg-payment-rebuild)

-- 仅保存新实现可确认的本地创建事实;不保存 HashKey、HashIV、CheckMacValue 或完整表单。
-- 本 SQL 只登记,由开发者手动执行;实现过程禁止直接执行 DDL。
CREATE TABLE pos_order_omg_attempt (
  id BIGINT NOT NULL AUTO_INCREMENT COMMENT '本地支付尝试主键',
  dd_id VARCHAR(64) NOT NULL COMMENT '关联 pos_order.dd_id',
  merchant_trade_no VARCHAR(20) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'OMG MerchantTradeNo',
  store_id BIGINT NOT NULL COMMENT '创建时订单门店快照',
  merchant_id VARCHAR(10) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT '创建时 OMG MerchantID 快照',
  amount INT NOT NULL COMMENT '创建时整数 TWD 金额快照',
  attempt_status TINYINT NOT NULL DEFAULT 0 COMMENT '本地状态:0=CREATED',
  active_dd_id VARCHAR(64)
    GENERATED ALWAYS AS (IF(attempt_status = 0, dd_id, NULL)) VIRTUAL
    COMMENT '单订单单活跃尝试唯一键载体',
  create_time DATETIME NOT NULL COMMENT '创建时间',
  update_time DATETIME NOT NULL COMMENT '更新时间',
  PRIMARY KEY (id),
  UNIQUE KEY uk_omg_attempt_trade_no (merchant_trade_no),
  UNIQUE KEY uk_omg_attempt_active_dd (active_dd_id),
  KEY idx_omg_attempt_dd_time (dd_id, create_time, id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='OMG AIO 新支付创建尝试';

Invariants

  1. merchant_trade_no 只含大写 ASCII 英数字且长度不超过 20。
  2. amount > 0、store_id 和 merchant_id 均在插入前校验。
  3. attempt_status=0 的行通过生成列唯一索引保证每个 dd_id 最多一条。
  4. 表中永远没有门店 HashKey、HashIV、完整 CheckMacValue 或完整表单。
  5. 不执行外键约束:沿用项目现有业务表风格,订单归属在事务锁与服务校验中保证。

Java types

OmgPaymentAttempt

public class OmgPaymentAttempt {
    private Long id;
    private String ddId;
    private String merchantTradeNo;
    private Long storeId;
    private String merchantId;
    private Integer amount;
    private Integer attemptStatus;
    private String activeDdId;
    private Date createTime;
    private Date updateTime;
}

OmgPaymentOrderSnapshot

只承载锁定订单时创建支付所需字段,不暴露到 Controller:

public class OmgPaymentOrderSnapshot {
    private Long id;
    private String ddId;
    private String parentDdId;
    private Long storeId;
    private Long userId;
    private Integer amount;
    private Long state;
    private Long payStatus;
    private String payType;
}

Mapper operations

OmgPaymentOrderSnapshot selectOrderForUpdate(String ddId);
OmgPaymentAttempt selectActiveByDdId(String ddId);
OmgPaymentAttempt selectByMerchantTradeNo(String merchantTradeNo);
int insertCreated(OmgPaymentAttempt attempt);

selectOrderForUpdate 必须在事务中使用 SELECT ... FOR UPDATE。insertCreated 必须显式列出插入列并排除生成列 active_dd_id。