> ## Documentation Index
> Fetch the complete documentation index at: https://learn.cleeksy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook portal (cổng webhook)

> Nhận dữ liệu từ hệ thống ngoài qua webhook.

Webhook portal (cổng webhook) là một loại **Data source** cho phép hệ thống ngoài **đẩy dữ liệu/sự kiện vào app** theo kiểu *event-driven*.

Webhook phù hợp khi cần nhận dữ liệu theo thời gian thực (ví dụ: đơn hàng, sự kiện thanh toán, ticket từ hệ thống khác).

Liên quan:

* [Cổng dữ liệu (Data source)](/build-apps/integrations/data-sources-overview)
* [API portal (cổng API)](/build-apps/integrations/api-portal)
* [Bảo mật (Security)](/build-apps/integrations/security-tokens)

***

## Payload basics (cơ bản về payload)

Webhook thường gửi payload dạng JSON. Payload thực dụng nên có:

* **eventType** (loại sự kiện)
* **eventId** (mã sự kiện duy nhất) để chống tạo trùng
* **timestamp** (thời điểm)
* **data** (dữ liệu nghiệp vụ) để map vào Entity đích

Thực hành tốt:

* Giữ payload gọn, chỉ chứa dữ liệu cần thiết
* Nếu dữ liệu lớn, gửi “key” và để app gọi API pull bổ sung

***

## Mapping vào Entity (tạo/cập nhật record)

Khi cấu hình webhook:

* Chọn **Entity đích**
* Chọn **field được phép ghi**
* Xác định quy tắc: tạo mới hay cập nhật theo khoá (ví dụ: External ID)

Gợi ý:

* Có field “External ID” để liên kết với hệ thống ngoài
* Có field “Webhook Event ID” để log idempotency

***

## Error handling patterns (mẫu xử lý lỗi)

### Pattern 1 — Acknowledge nhanh, xử lý sau

Nhận webhook → ghi nhận tối thiểu → xử lý workflow/automation phía sau.

### Pattern 2 — Validate trước khi ghi

Kiểm tra field bắt buộc/định dạng. Nếu sai, đưa vào trạng thái “Invalid” để đội vận hành xử lý.

### Pattern 3 — Dead-letter view

Tạo view “Webhook errors” để theo dõi record lỗi và có checklist khắc phục (mapping/field/permission).

Liên quan: [Rà soát & vận hành (App review)](/build-apps/app-review)

***

## Idempotency (tránh tạo trùng)

Webhook thường bị retry. Cần idempotency bằng cách:

* Nhận **eventId** từ payload
* Lưu eventId vào Entity
* Nếu eventId đã tồn tại → bỏ qua hoặc cập nhật theo quy tắc

Thực hành tốt:

* Idempotency theo “eventId + eventType”
* Với cập nhật, ưu tiên cập nhật theo “External ID” của đối tượng nghiệp vụ (orderId, ticketId…)

***

## Guardrails (an toàn khi công khai)

* Không để webhook URL/token lộ ra ngoài
* Giới hạn field được phép ghi
* Có logging tối thiểu để truy vết (thời điểm, eventId, kết quả)

Liên quan: [Bảo mật (Security)](/build-apps/integrations/security-tokens)

***

## Bước tiếp theo

* Khi cần tích hợp có cấu trúc: [API portal (cổng API)](/build-apps/integrations/api-portal)
* Khi cần nối app nội bộ: [Kết nối ứng dụng (Connected app)](/build-apps/integrations/connected-app)
