pos_store 1 ── N pos_store_line_pay (immutable credential versions)
│
└── current_store_id UNIQUE: one current version/store
pos_order 1 ── N pos_order_line_payment (append-only attempts)
│
├── credential_id -> exact credential version
├── active_dd_id UNIQUE: one blocking attempt/order
└── 1 ── 0..1 pos_order_line_refund
payment_gateway_log ── optional payment_id/refund_id/credential_id references
不声明物理外键,保持与现有业务表部署习惯一致;Service 在事务内保证逻辑引用存在。
pos_store_line_pay不可变门店凭证版本。Secret 按用户决定以明文保存。普通列表仅返回 hasCredential,平台详情接口可返回当前版本 Secret。
| Column | Type | Null | Notes |
|---|---|---|---|
id |
BIGINT | no | auto increment |
store_id |
BIGINT | no | pos_store.id |
credential_version |
INT | no | store 内从 1 递增 |
channel_id |
VARCHAR(50) ASCII | no | LINE Channel ID;业务层按字符串处理 |
channel_secret |
VARCHAR(255) | no | 明文 |
environment |
VARCHAR(16) | no | SANDBOX/PRODUCTION |
credential_status |
VARCHAR(32) | no | VERIFIED/VERIFY_FAILED;仅 VERIFIED 可成为 current |
is_enabled |
TINYINT | no | current 版本的新支付开关 |
current_store_id |
BIGINT | yes | current 时等于 store_id,历史版本 NULL |
verify_return_code |
VARCHAR(8) | yes | 最后探测结果码 |
verify_return_message |
VARCHAR(255) | yes | 摘要 |
verified_time |
DATETIME | yes | 验证通过时间 |
create_time/update_time |
DATETIME | no | 审计时间 |
create_by/update_by |
VARCHAR(64) | yes | 管理员 |
Constraints and indexes:
UNIQUE(store_id, credential_version)UNIQUE(current_store_id);MySQL 允许多个 NULL。INDEX(store_id, create_time)current_store_id 置 NULL,新行置 storeId。pos_order_line_payment每次真正发起的 LINE Request 对应一行,历史永不覆盖。行内更新仅用于同一尝试的状态推进和补充网关标识。
| Column | Type | Null | Notes |
|---|---|---|---|
id |
BIGINT | no | paymentId |
dd_id |
VARCHAR(64) | no | pos_order.dd_id |
line_order_id |
VARCHAR(100) ASCII BINARY | no | Request 前生成,永久唯一 |
transaction_id |
VARCHAR(32) ASCII BINARY | yes | Request 成功后获得,禁止 Long |
credential_id |
BIGINT | no | 发起时选中的不可变凭证版本 |
store_id |
BIGINT | no | 门店快照 |
amount |
INT | no | TWD 整数金额 |
currency |
CHAR(3) ASCII | no | 首版 TWD |
payment_url_web |
VARCHAR(1000) | yes | Sandbox/浏览器跳转 URL |
payment_url_app |
VARCHAR(1000) | yes | 生产 LINE App URL,可空 |
payment_provider |
VARCHAR(16) | yes | 原始值可空;展示归一为 TSP |
status |
VARCHAR(40) | no | 下方状态机 |
active_dd_id |
VARCHAR(64) | yes | 阻断新尝试时等于 ddId,明确终止后 NULL |
version |
BIGINT | no | CAS,从 0 递增 |
next_reconcile_at |
DATETIME | yes | 下次扫描 |
reconcile_deadline |
DATETIME | yes | 当前恢复阶段截止 |
reconcile_count |
INT | no | 默认 0 |
lease_owner |
VARCHAR(64) | yes | 行租约节点/批次 ID |
lease_until |
DATETIME | yes | 租约过期时间 |
status_changed_at |
DATETIME | no | 状态变化时间 |
auth_completed_time |
DATETIME | yes | Check 0110 时间 |
pay_time |
DATETIME | yes | Capture 时间 |
create_time/update_time |
DATETIME | no | 审计时间 |
Constraints and indexes:
UNIQUE(line_order_id)UNIQUE(transaction_id);允许多个 NULL。UNIQUE(active_dd_id);允许历史多 NULL。INDEX(dd_id, create_time, id)INDEX(status, next_reconcile_at, id)INDEX(credential_id, create_time)id + expected status + version,领取租约还需 lease_until IS NULL OR lease_until < NOW()。Payment states:
REQUESTING
├─ WAITING_AUTH
├─ REQUEST_UNKNOWN
└─ FAILED (only explicit no-side-effect failure; releases active key)
WAITING_AUTH / REQUEST_UNKNOWN
├─ READY_CONFIRM
├─ PAID
├─ CANCELLED_OR_EXPIRED (releases active key)
├─ FAILED (releases active key)
└─ MANUAL_REVIEW
READY_CONFIRM
├─ CONFIRMING
└─ AUTH_DONE_ORDER_CANCELLED
CONFIRMING
├─ PAID
└─ CONFIRM_UNKNOWN
CONFIRM_UNKNOWN
├─ PAID
└─ MANUAL_REVIEW
PAID、UNKNOWN、MANUAL_REVIEW 不释放 active_dd_id。旧尝试迟到证实 PAID 时照实记录,并阻断/退款,不覆盖当前尝试。
pos_order_line_refund首版只支持每笔已付款交易一次全额退款。
| Column | Type | Null | Notes |
|---|---|---|---|
id |
BIGINT | no | refund id |
payment_id |
BIGINT | no | payment,唯一 |
dd_id |
VARCHAR(64) | no | 查询快照 |
credential_id |
BIGINT | no | 默认 payment 的凭证版本 |
transaction_id |
VARCHAR(32) ASCII BINARY | no | 原支付交易号 |
refund_transaction_id |
VARCHAR(32) ASCII BINARY | yes | LINE refund transaction |
amount |
INT | no | 本地全额审计;调用时不传 refundAmount |
status |
VARCHAR(32) | no | CREATED/PROCESSING/UNKNOWN/RETRY_WAIT/REFUNDED/FAILED/MANUAL_REVIEW |
source |
VARCHAR(32) | no | USER_CANCEL/STORE_CANCEL/ADMIN/TASK |
version |
BIGINT | no | CAS |
next_reconcile_at/reconcile_deadline |
DATETIME | yes | 恢复调度 |
reconcile_count |
INT | no | 默认 0 |
lease_owner/lease_until |
VARCHAR(64)/DATETIME | yes | 行租约 |
refund_time |
DATETIME | yes | 确证全退时间 |
create_time/update_time |
DATETIME | no | 审计时间 |
Constraints and indexes:
UNIQUE(payment_id)UNIQUE(refund_transaction_id);允许多个 NULL。INDEX(status, next_reconcile_at, id)INDEX(dd_id, create_time, id)Refund transitions:
CREATED / RETRY_WAIT --CAS claim--> PROCESSING
PROCESSING ├─ REFUNDED
├─ UNKNOWN
├─ RETRY_WAIT (only documented explicit retryable result)
└─ FAILED (explicit terminal failure)
UNKNOWN ├─ REFUNDED (Retrieve refundList proves it)
└─ MANUAL_REVIEW (deadline)
payment_gateway_log仅记录 LINE Pay;不迁移 OMG。日志采用追加写,不用于决定当前支付状态。
| Column | Type | Null | Notes |
|---|---|---|---|
id |
BIGINT | no | auto increment |
correlation_id |
VARCHAR(64) ASCII | no | 同次 request/response 关联 |
payment_id/refund_id/credential_id |
BIGINT | yes | 结构化关联 |
store_id |
BIGINT | yes | 凭证验证也可关联门店 |
dd_id |
VARCHAR(64) | yes | 业务订单 |
gateway_order_id |
VARCHAR(100) ASCII BINARY | yes | line_order_id |
transaction_id |
VARCHAR(32) ASCII BINARY | yes | 网关交易号 |
action |
VARCHAR(32) | no | CREDENTIAL_VERIFY/REQUEST/CHECK/CONFIRM/RETRIEVE/REFUND/REDIRECT |
direction |
VARCHAR(8) | no | REQUEST/RESPONSE/EVENT |
source |
VARCHAR(32) | no | APP/CALLBACK/TASK/ADMIN/CANCEL |
http_status |
INT | yes | HTTP status |
return_code |
VARCHAR(8) | yes | LINE code |
return_message |
VARCHAR(255) | yes | LINE message |
success |
TINYINT | no | transport/business action summary |
duration_ms |
BIGINT | yes | elapsed |
payload |
LONGTEXT | yes | raw JSON/body/error summary |
create_time |
DATETIME | no | append time |
Indexes:
(payment_id, create_time)(refund_id, create_time)(gateway_order_id, create_time)(transaction_id, create_time)(correlation_id)(store_id, create_time)不新增 pos_order 字段。使用现有:
pay_type="3": 新 LINE 订单选择;历史同值不自动视为 LINE,必须存在匹配 Line payment。pay_status=0/1/2: 未付/已付/已确认全额退款。pay_url: 当前活跃尝试的 web URL,可作为兼容展示;支付选择以 Line payment 为准。state=4: 已取消;仍允许记录迟到 PAID,随后创建退款 intent。ddId 查询时先读取订单 pay_status。active_dd_id=ddId;没有则返回最新终态尝试。PAID;已退款选带 REFUNDED 的付款/退款组合。PAID 不自动任选,返回 MANUAL_REVIEW。line_order_id 定位,transactionId 存在时必须匹配。paymentId/refundId 操作。