{
  "schema_version": 1,
  "diagram_type": "erd",
  "meta": {
    "title": "Đơn, tiền và hoàn tiền — ERD logic đề xuất",
    "locale": "vi",
    "quality_profile": "showcase",
    "output": "docs/ssa-miniapp/archify/payment-data.html"
  },
  "layout": {
    "mode": "grid",
    "entityW": 280,
    "gapX": 90,
    "gapY": 82
  },
  "entities": [
    {
      "id": "orders",
      "label": "orders",
      "row": 0,
      "col": 0,
      "tag": "Đơn hàng",
      "attributes": [
        {
          "name": "id",
          "key": "pk"
        },
        {
          "name": "owner_guardian_id"
        },
        {
          "name": "total_vnd"
        },
        {
          "name": "fulfillment_status"
        },
        {
          "name": "payment_status"
        }
      ]
    },
    {
      "id": "order_items",
      "label": "order_items",
      "row": 1,
      "col": 0,
      "tag": "Đơn hàng",
      "attributes": [
        {
          "name": "id",
          "key": "pk"
        },
        {
          "name": "order_id",
          "key": "fk",
          "references": "orders.id"
        },
        {
          "name": "variant_id"
        },
        {
          "name": "sku / price snapshot"
        },
        {
          "name": "quantity"
        }
      ]
    },
    {
      "id": "payment_attempts",
      "label": "payment_attempts",
      "row": 0,
      "col": 1,
      "tag": "Lần thử và sự kiện",
      "attributes": [
        {
          "name": "id",
          "key": "pk"
        },
        {
          "name": "order_id",
          "key": "fk",
          "references": "orders.id"
        },
        {
          "name": "idempotency_key",
          "key": "uk"
        },
        {
          "name": "expected_vnd / currency"
        },
        {
          "name": "status / expires_at"
        }
      ]
    },
    {
      "id": "payment_events",
      "label": "payment_events",
      "row": 1,
      "col": 1,
      "tag": "Lần thử và sự kiện",
      "attributes": [
        {
          "name": "id",
          "key": "pk"
        },
        {
          "name": "attempt_id",
          "key": "fk",
          "references": "payment_attempts.id"
        },
        {
          "name": "provider_event_key",
          "key": "uk"
        },
        {
          "name": "validation / received_at"
        },
        {
          "name": "processing_status"
        }
      ]
    },
    {
      "id": "payment_transactions",
      "label": "payment_transactions",
      "row": 0,
      "col": 2,
      "tag": "Thu và hoàn",
      "attributes": [
        {
          "name": "id",
          "key": "pk"
        },
        {
          "name": "attempt_id",
          "key": "fk",
          "references": "payment_attempts.id"
        },
        {
          "name": "provider / merchant"
        },
        {
          "name": "provider_transaction_id"
        },
        {
          "name": "amount_vnd / paid_at"
        }
      ]
    },
    {
      "id": "refunds",
      "label": "refunds",
      "row": 1,
      "col": 2,
      "tag": "Thu và hoàn",
      "attributes": [
        {
          "name": "id",
          "key": "pk"
        },
        {
          "name": "transaction_id",
          "key": "fk",
          "references": "payment_transactions.id"
        },
        {
          "name": "amount_vnd / status"
        },
        {
          "name": "requester / approver"
        },
        {
          "name": "idempotency_key",
          "key": "uk"
        }
      ]
    }
  ],
  "relationships": [
    {
      "id": "item_order",
      "from": "order_items",
      "to": "orders",
      "fromCardinality": "many",
      "toCardinality": "one"
    },
    {
      "id": "attempt_order",
      "from": "payment_attempts",
      "to": "orders",
      "fromCardinality": "many",
      "toCardinality": "one"
    },
    {
      "id": "event_attempt",
      "from": "payment_events",
      "to": "payment_attempts",
      "fromCardinality": "many",
      "toCardinality": "one",
      "toOptional": true
    },
    {
      "id": "transaction_attempt",
      "from": "payment_transactions",
      "to": "payment_attempts",
      "fromCardinality": "many",
      "toCardinality": "one"
    },
    {
      "id": "refund_transaction",
      "from": "refunds",
      "to": "payment_transactions",
      "fromCardinality": "many",
      "toCardinality": "one"
    }
  ],
  "cards": [
    {
      "dot": "amber",
      "title": "Ràng buộc tiền",
      "items": [
        "Unique giao dịch trên bộ (provider, merchant, provider_transaction_id); không unique riêng provider_transaction_id. Idempotency được scope theo chủ thể/operation khi triển khai.",
        "Một đơn có thể có nhiều lần thử; thu trùng là ngoại lệ cần xử lý. Tổng hoàn thành công không vượt tiền đã thu còn có thể hoàn; người lập không tự duyệt."
      ]
    },
    {
      "dot": "cyan",
      "title": "Sự kiện không phải bằng chứng đã thu",
      "items": [
        "Event sai chữ ký, sai tiền hoặc không tìm thấy attempt được giữ/quarantine theo policy, không cập nhật paid. Liên kết attempt có thể trống trước khi xác minh.",
        "Snapshot dòng hàng giữ lịch sử dù catalog đổi giá. Variant và inventory được tách khỏi lát cắt tiền; xem sơ đồ merchandise."
      ]
    },
    {
      "dot": "slate",
      "title": "Thiết kế logic, chưa triển khai",
      "items": [
        "Nguồn: FEATURES.md §7.4–7.5, bản thiết kế đang làm việc ngày 12/11/2026. Đây là thực thể và trường khóa chọn lọc để trình bày; không phải migration hay schema vật lý đã tồn tại. Kiểu SQL, retention và toàn bộ cột sẽ được chốt khi triển khai."
      ]
    }
  ]
}
