# 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) ```sql -- 仅保存新实现可确认的本地创建事实;不保存 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` ```java 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: ```java 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 ```java OmgPaymentOrderSnapshot selectOrderForUpdate(String ddId); OmgPaymentAttempt selectActiveByDdId(String ddId); OmgPaymentAttempt selectByMerchantTradeNo(String merchantTradeNo); int insertCreated(OmgPaymentAttempt attempt); ``` `selectOrderForUpdate` 必须在事务中使用 `SELECT ... FOR UPDATE`。`insertCreated` 必须显式列出插入列并排除生成列 `active_dd_id`。