DEVELOPER · GUIDE

Hướng dẫn tích hợp

Hướng dẫn từng bước cho đối tác tích hợp Open API của plott LIFE.

PHASE 01 · Bắt đầu

Từ cấp khóa API đến thiết lập môi trường phát triển

STEP 01

Thêm ứng dụng và cấp khóa API

Để gọi Open API, bạn cần tạo ứng dụng và lấy API client key và secret.

Tạo ứng dụng

  1. Màn hình app Điền mẫu đăng ký.
  2. Nhập tên dịch vụ, tên tiếng Anh (mã kênh) và URL, rồi gửi.
  3. Sau xét duyệt, kênh riêng tư sẽ được tạo; kết quả gửi qua email. Nếu được duyệt, bạn có thể tạo API key trực tiếp trên trang app theo hướng dẫn.

Cấp API client

  1. Trang chi tiết app của API client trong phần [Thêm client] nhấn vào.
  2. Nhập Client ID (tự do, tối đa 100 ký tự) và chọn scope.
  3. Hiển thị ngay sau khi tạo Lưu Client Secret ngay vào nơi an toàn Giá trị này sẽ không được hiển thị lại.

Scope

  • buildingUnit:readBUILDING_UNIT_READXem phòng
  • buildingUnit:writeBUILDING_UNIT_WRITETạo/Sửa mapping phòng
  • booking:readBOOKING_READXem đặt chỗ
  • booking:writeBOOKING_WRITETạo/Sửa đặt chỗ
  • contract:readCONTRACT_READXem hợp đồng
  • contract:writeCONTRACT_WRITETạo/Sửa hợp đồng (Phương thức B)
  • user:writeUSER_WRITETạo user (Phương thức A · liên kết đăng nhập)
  • userLoginTicket:writeUSER_LOGIN_TICKET_WRITECấp ticket đăng nhập (Phương thức A · liên kết đăng nhập)
  • chat:readCHAT_READXem chat
  • chat:writeCHAT_WRITETạo/Gửi chat

Kết quả

Nếu đã có Client ID và Client Secret,Authorization: Basic … hãy dùng cặp khóa này trong header của mọi yêu cầu API.

STEP 02

Đăng phòng test và cấu hình mapping kênh

Để đăng hợp đồng/đặt chỗ qua API, tạo phòng test và cấu hình mapping.

Quy trình

  1. Màn hình chủ nhà Đăng phòng mới.
  2. Màn hình ánh xạ kênh Chọn phòng đã đăng, rồi thiết lập ánh xạ theo loại phòng và theo số phòng. Ánh xạ theo loại phòng là tùy chọn, nhưng bạn phải thiết lập ánh xạ theo số phòng để có thể đăng hợp đồng qua Open API. Đặt ID tin đăng bên ngoài bằng giá trị ID của phòng trên kênh đó.
  3. Để kiểm tra phòng trên trang khách, /rooms/{roomId}hãy truy cập vào đó.

Ghi chú

Ví dụ ID phòng bên ngoài https://www.airbnb.co.kr/rooms/1252576808547167623 1252576808547167623

STEP 03

Duyệt tài liệu bằng MCP

Đăng MCP server của plott LIFE Open API vào AI coding agent (Claude Code, Cursor...) để agent có thể đọc spec ngay và hỗ trợ tích hợp nhanh hơn.

Đăng vào Claude Code

claude mcp add --transport http plott-life-partner \
  https://life.plott.co.kr/api/open/mcp \
  --header "Authorization: Basic {base64(clientId:clientSecret)}"

{base64(clientId:clientSecret)} là chuỗi gồm Client ID và Secret lấy ở Step 01 clientId:clientSecret được nối bằng dấu hai chấm rồi mã hóa base64.

Ví dụ: agent AI khám phá Open API của plott LIFE sau khi đăng ký server MCPVí dụ: agent tạo mã tích hợp dựa trên spec API lấy từ MCP

PHASE 02 · Tích hợp

Chọn phương thức tích hợp, triển khai và vận hành

IMPLEMENT & OPERATE

Chọn phương thức tích hợp

Tùy mức dịch vụ đối tác xử lý trực tiếp, có hai phương thức tích hợp Phương thức A · Liên kết đăng nhập là phương thức hand-off: chỉ tích hợp danh sách phòng và đăng nhập, chuyển hợp đồng/ thanh toán sang plott LIFE, Phương thức B · Liên kết hợp đồng là phương thức tích hợp cả API hợp đồng để hoàn tất bán hàng trong app đối tác. Chọn tab bên dưới để xem các bước triển khai và vận hành tương ứng.

Chọn một trong hai phương thức tùy mức độ xử lý trực tiếp trên dịch vụ đối tác. Các bước triển khai/vận hành bên dưới sẽ hiển thị theo lựa chọn. Các bước chung trước đó (đăng ký app·tạo key, phòng test·ánh xạ kênh, MCP) và bước kênh công khai sau đó giống nhau cho cả hai.

Phương thức A · Liên kết đăng nhập (Hand-off)

Trên dịch vụ đối tác chỉ hiển thị danh sách phòng; phần hợp đồng và thanh toán chuyển sang trang plott LIFE. Nếu tạo sẵn tài khoản và cấp login ticket (SSO) rồi chuyển, người dùng sẽ tự động đăng nhập trên plott LIFE để tiếp tục ký hợp đồng. Các scope cần: user:write, userLoginTicket:write là.

IMPLEMENT · Liên kết đăng nhập

Bước triển khai

1. Tích hợp danh sách phòng

Dịch vụ đối tác truy vấn phòng (listing) của plott LIFE và hiển thị cho người dùng.

GET /open/v1/building-unit-type để lấy danh sách phòng, GET /open/v1/building-unit-type/{id} để lấy chi tiết từng phòng. Danh sách page·size sử dụng phân trang Kích thước mặc định là 20. Đối với cuộn vô hạn, dùng totalItems trường trong phản hồi để xác định còn mục cần tải thêm không.

  • pageTùy chọnSố trang bắt đầu từ 0
  • sizeTùy chọn · Mặc định 20Số mục trên mỗi trang
  • operationStatusKhuyến nghịKhi hiển thị cho người dùng, chỉ truy vấn PUBLISHED (Đang hoạt động)
const res = await fetch(
  'https://life.plott.co.kr/api/open/v1/building-unit-type?page=0&size=20&operationStatus=PUBLISHED',
  { headers: { Authorization: `Basic ${credentials}` } },
);
const { items, totalItems, totalPages } = await res.json();

Ghi chú

Chính sách tính giá phòng (tiền thuê theo tỷ lệ·khuyến mãi·phí quản lý·đặt cọc·phí dịch vụ) và cách lưu (gọi trực tiếp / mirroring) giống nhau cho cả hai. Công thức và ví dụ chi tiết xem Tài liệu API xem tại

2. Tích hợp tạo thành viên

POST /open/v1/user Tạo thành viên plott LIFE từ thành viên của dịch vụ đối tác. externalUserId Xử lý idempotent theo (mã định danh thành viên đối tác); nếu đã tồn tại, trả về ID thành viên hiện có.

  • externalUserIdBắt buộcMã định danh thành viên của dịch vụ đối tác (khóa idempotent)
  • emailBắt buộcEmail thành viên
  • firstName / lastNameBắt buộcTên / Họ
  • phoneCode / phoneNumberBắt buộcMã quốc gia / Số điện thoại (ví dụ: 82 / 1012345678)
  • countryCodeTùy chọnMã quốc gia (ví dụ: KR)
const res = await fetch('https://life.plott.co.kr/api/open/v1/user', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Basic ${credentials}`,
  },
  body: JSON.stringify({
    externalUserId: 'partner-user-001',
    email: 'user@example.com',
    firstName: '길동',
    lastName: '홍',
    phoneCode: '82',
    phoneNumber: '1012345678',
    countryCode: 'KR',
  }),
});

const { id } = await res.json(); // 플라트라이프 회원 ID

3. Phát hành ticket đăng nhập

POST /open/v1/userLoginTicket Phát hành ticket đăng nhập dùng một lần cho thành viên. Yêu cầu phải chứa userId (trong phản hồi tạo thành viên của id) hoặc externalUserId một trong hai. Giá trị nhận được trong phản hồi ticket là Hợp lệ 5 phút và Chỉ dùng 1 lần vì vậy, phát hành ngay trước khi người dùng chuyển sang plott LIFE.

  • userIdChọn 1: userId / externalUserIdID thành viên plott LIFE (id trong phản hồi tạo thành viên)
  • externalUserIdChọn 1: userId / externalUserIdMã định danh thành viên của dịch vụ đối tác
const res = await fetch(
  'https://life.plott.co.kr/api/open/v1/userLoginTicket',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Basic ${credentials}`,
    },
    body: JSON.stringify({ externalUserId: 'partner-user-001' }),
  },
);

const { ticket } = await res.json(); // 5분 TTL · 1회용

Mẹo

Với cách này không tích hợp API hợp đồng. Hợp đồng và thanh toán diễn ra trên trang plott LIFE, nên dịch vụ đối tác chỉ cần hiển thị danh sách phòng và tích hợp đăng nhập.

OPERATE · Liên kết đăng nhập

Bước vận hành

  1. Hiển thị danh sách phòng trên dịch vụ đối tác.
  2. Khi người dùng chọn phòng, đối với thành viên đó Cấp login ticket (nếu chưa có thì tạo thành viên rồi phát hành).
  3. Đính kèm ticket đã phát hành vào https://life.plott.co.kr/rooms/{id}?ticket=<ticket> chuyển hướng tới. plott LIFE sẽ trao đổi ticket và Tự động đăng nhập thực hiện.
  4. Sau đó hợp đồng và thanh toán diễn ra trên trang plott LIFE. Dịch vụ đối tác không xử lý luồng hợp đồng.

Thời hạn ticket

Ticket đăng nhập chỉ hợp lệ 5 phút và chỉ dùng 1 lần. Phát hành ngay trước khi redirect để chuyển kịp thời.

PHASE 03 · Kênh công khai

Sau khi kiểm duyệt, chuyển sang kênh công khai để vận hành

PUBLIC CHANNEL

Yêu cầu xét duyệt kênh công khai

Nếu đã kiểm thử tích hợp kỹ trên kênh riêng, yêu cầu chuyển sang kênh công khai để mở quyền truy cập đến phòng của mọi host. Bước này giống nhau cho cả hai phương thức.

Cách yêu cầu

  1. Trang chi tiết app trên thẻ trạng thái đăng ký [Yêu cầu chuyển kênh công khai] Nhấn vào
  2. Nhóm vận hành sẽ xem xét và thông báo kết quả qua email.
  3. Nếu bị từ chối, xem lý do, chỉnh sửa và nộp lại.

PUBLIC CHANNEL

Kích hoạt kênh công khai

Khi là kênh công khai, bạn có thể truy vấn phòng của mọi host trên plott LIFE qua Open API mà không cần thao tác thêm. Chọn phòng muốn xử lý và thiết lập channel mapping, rồi vận hành theo luồng tích hợp đã chọn.

Xem toàn bộ danh sách phòng

const res = await fetch(
  'https://life.plott.co.kr/api/open/v1/building-unit-type?page=0&size=20',
  { headers: { Authorization: `Basic ${credentials}` } },
);
const { items, totalItems, totalPages } = await res.json();

Hoạt động mặc định

Theo mặc định Đang hoạt động Chỉ hiển thị phòng ở trạng thái này. Nếu chỉ muốn xem phòng bạn đăng ký, isMine=true có thể gửi yêu cầu.

REFERENCE · Thông tin chung

Tham khảo: xác thực, lỗi và Rate Limit

COMMON

Xác thực

Mọi yêu cầu tới Open API đều dùng xác thực HTTP Basic. Trang chi tiết app được cấp từ Client ID và Client Secret nối bằng dấu hai chấm, sau đó mã hóa base64 Authorization đặt vào header rồi gửi.

const credentials = Buffer.from(
  `${process.env.CLIENT_ID}:${process.env.CLIENT_SECRET}`,
).toString('base64');

const res = await fetch('https://life.plott.co.kr/api/open/v1/contract-channel', {
  headers: {
    Authorization: `Basic ${credentials}`,
  },
});

Bảo mật Client Secret

Client Secret chỉ hiển thị một lần khi cấp. Nếu bị mất hoặc lộ ra ngoài Trang chi tiết app hãy xóa client ngay lập tức ở đó và cấp lại.

COMMON

Phản hồi lỗi

Khi xảy ra lỗi RFC 9457 Problem Detail sẽ trả về theo định dạng sau.

{
  "type": "about:blank",
  "title": "Not Found",
  "status": 404,
  "detail": "예약 매핑을 찾을 수 없습니다.",
  "instance": "/open/v1/booking"
}
  • typeURI loại lỗi
  • titleThông điệp trạng thái HTTP
  • statusMã trạng thái HTTP
  • detailThông điệp lỗi chi tiết
  • instanceĐường dẫn yêu cầu

COMMON

Rate Limit

Open API giới hạn số lần gọi để đảm bảo ổn định dịch vụ và công bằng cho đối tác.

  • Phạm vi áp dụngTất cả endpoint dưới /open/**
  • Đơn vị giới hạnTài khoản host
  • Giới hạn300 yêu cầu/phút
  • Cơ chế phục hồiPhục hồi liên tục (greedy refill). Khoảng 1s nạp lại tương đương 5 lượt.

Phản hồi khi vượt giới hạn

Yêu cầu vượt giới hạn sẽ bị từ chối ngay lập tức và 429 Too Many Requests sẽ trả về phản hồi lỗi.

Cách xử lý khuyến nghị cho client

  • 429 Khi nhận phản hồi, không thử lại ngay lập tức, chờ một khoảng rồi thử lại.
  • Trung bình khoảng khoảng 200ms là có thể gọi ổn định.
  • Với batch cần nhiều request trong thời gian ngắn, tăng khoảng cách giữa các gọi hoặc dùng exponential backoff.

Mẹo

Trong mô hình sử dụng bình thường, 429 nếu điều đó xảy ra thường xuyên, chúng tôi có thể xem xét tăng hạn mức — vui lòng liên hệ.

DOCUMENTATION

Xem toàn bộ đặc tả endpoint

Schema yêu cầu/phản hồi, tham số và mã lỗi — tất cả ở một nơi.

Xem tài liệu API