{
  "schema_version": 1,
  "diagram_type": "sequence",
  "meta": {
    "title": "Checkout: server xác nhận tiền — thiết kế đề xuất",
    "locale": "vi",
    "translations": {
      "page.title": "Sơ đồ {title}",
      "legend.title": "Chú giải",
      "viewer.theme.dark": "Tối",
      "viewer.theme.light": "Sáng",
      "viewer.motion.live": "Chuyển động",
      "viewer.motion.still": "Tĩnh",
      "viewer.present.present": "Trình chiếu",
      "viewer.present.exit.label": "Thoát",
      "legend.sequence.emphasis": "Luồng chính",
      "legend.sequence.return": "Phản hồi",
      "legend.sequence.security": "Kiểm soát",
      "legend.sequence.dashed": "Bất đồng bộ",
      "legend.sequence.default": "Thông điệp",
      "legend.workflow.frontend": "Giao diện",
      "legend.workflow.backend": "Xử lý nghiệp vụ",
      "legend.workflow.security": "Kiểm soát",
      "legend.workflow.messagebus": "Tác vụ",
      "legend.workflow.database": "Dữ liệu",
      "legend.workflow.cloud": "Dịch vụ",
      "legend.workflow.external": "Bên ngoài",
      "legend.dataflow.emphasis": "Dữ liệu chính",
      "legend.dataflow.security": "Quyền / dữ liệu nhạy cảm",
      "legend.dataflow.dashed": "Nhập theo đợt",
      "legend.dataflow.database": "Lưu trữ",
      "legend.dataflow.default": "Luồng dữ liệu"
    },
    "output": "docs/ssa-miniapp/archify/checkout.html",
    "quality_profile": "showcase"
  },
  "participants": [
    {
      "id": "app",
      "type": "frontend",
      "label": "Mini App",
      "sublabel": "Phụ huynh xác nhận"
    },
    {
      "id": "api",
      "type": "backend",
      "label": "Backend SSA",
      "sublabel": "Quyền + giá + trạng thái"
    },
    {
      "id": "db",
      "type": "database",
      "label": "Giao dịch",
      "sublabel": "Đơn / tiền / outbox"
    },
    {
      "id": "sdk",
      "type": "frontend",
      "label": "Checkout SDK",
      "sublabel": "Chọn phương thức"
    },
    {
      "id": "provider",
      "type": "external",
      "label": "Cổng thanh toán",
      "sublabel": "Merchant chưa chốt"
    }
  ],
  "messages": [
    {
      "id": "m1",
      "from": "app",
      "to": "api",
      "y": 160,
      "label": "Xác nhận đặt mua",
      "variant": "emphasis"
    },
    {
      "id": "m2",
      "from": "api",
      "to": "db",
      "y": 200,
      "label": "Chốt đơn + attempt",
      "variant": "emphasis",
      "note": "Kiểm quyền, giá, tồn; cùng idempotency key"
    },
    {
      "id": "m3",
      "from": "api",
      "to": "app",
      "y": 275,
      "label": "Dữ liệu checkout",
      "variant": "return"
    },
    {
      "id": "m4",
      "from": "app",
      "to": "sdk",
      "y": 315,
      "label": "Mở Checkout SDK",
      "variant": "emphasis"
    },
    {
      "id": "m5",
      "from": "sdk",
      "to": "provider",
      "y": 355,
      "label": "Thực hiện giao dịch",
      "variant": "emphasis"
    },
    {
      "id": "m6",
      "from": "sdk",
      "to": "app",
      "y": 395,
      "label": "Kết quả phía client",
      "variant": "return",
      "note": "Chỉ đổi UI; không xác nhận đã thu tiền"
    },
    {
      "id": "m7",
      "from": "provider",
      "to": "api",
      "y": 475,
      "label": "Webhook giao dịch",
      "variant": "security",
      "note": "Xác minh provider; sai dữ liệu thì từ chối"
    },
    {
      "id": "m8",
      "from": "api",
      "to": "db",
      "y": 550,
      "label": "Payment + outbox",
      "variant": "emphasis",
      "note": "Atomic; chống trùng event và transaction"
    },
    {
      "id": "m9",
      "from": "app",
      "to": "api",
      "y": 625,
      "label": "Đọc trạng thái đơn",
      "variant": "default"
    },
    {
      "id": "m10",
      "from": "api",
      "to": "provider",
      "y": 665,
      "label": "Tra nếu pending/unknown",
      "variant": "default"
    },
    {
      "id": "m11",
      "from": "provider",
      "to": "api",
      "y": 705,
      "label": "Kết quả có xác minh",
      "variant": "return"
    },
    {
      "id": "query-persist",
      "from": "api",
      "to": "db",
      "y": 745,
      "label": "Cập nhật nếu hợp lệ",
      "variant": "security"
    },
    {
      "id": "m12",
      "from": "api",
      "to": "app",
      "y": 785,
      "label": "Trạng thái server",
      "variant": "return"
    }
  ],
  "cards": [
    {
      "dot": "slate",
      "title": "Nguồn và phạm vi",
      "items": [
        "FEATURES.md §7.2, §7.4–7.6; PLAN FR-14/15. Đề xuất mới, chưa có backend/checkout thật.",
        "SDK và provider là hai vai trò; API cụ thể phụ thuộc phương thức tích hợp được chốt."
      ]
    },
    {
      "dot": "rose",
      "title": "Chỉ server xác nhận tiền",
      "items": [
        "SDK success hoặc redirect không đổi đơn thành paid. Backend xác minh chữ ký, merchant, transaction, amount/currency và order.",
        "Event trùng không thu/ghi tiền hai lần; event cũ không hạ paid thành failed."
      ]
    },
    {
      "dot": "amber",
      "title": "Ngoại lệ phải nhìn thấy",
      "items": [
        "Pending/unknown: tra provider trước khi tạo lần thu mới. Đóng app rồi mở lại vẫn đọc trạng thái server.",
        "Giá/tồn đổi cần xác nhận lại; tiền đến sau TTL giữ hàng vào ngoại lệ giao/hoàn có người duyệt."
      ]
    }
  ]
}
