External Integrations
ระบบ WMS รองรับ 3 รูปแบบการเชื่อมต่อกับระบบภายนอก: Push API, Webhooks, และ File Storage (R2)
1. Push Integration API
REST API ที่ให้ระบบภายนอก (ERP, e-commerce, marketplace, suppliers) push ข้อมูลเข้า WMS โดยตรง
Base URL:
https://wms-api-dev-2w6s.onrender.com/api/v1/integration/v1Auth:X-API-Key: wms_...(SHA-256 hashed at rest)
Endpoints (16 ทั้งหมด)
จาก apps/api/src/modules/integration/integration.controller.ts:
Master Data (upsert pattern)
| Method | Path | Scope | คำอธิบาย |
|---|---|---|---|
| POST | /items | write | upsert item (by tenantId + sku) |
| POST | /items/bulk | write | bulk upsert (max 500) |
| POST | /partners | write | upsert partner (by code) |
| POST | /partners/bulk | write | bulk (max 500) |
| POST | /locations | write | upsert location (by warehouseCode + code) |
| POST | /locations/bulk | write | bulk (max 500) |
Inbound
| Method | Path | Scope | คำอธิบาย |
|---|---|---|---|
| POST | /asn | write | create ASN |
| POST | /asn/bulk | write | bulk ASN (max 100) |
| POST | /grn | write | receive against ASN |
Outbound
| Method | Path | Scope | คำอธิบาย |
|---|---|---|---|
| POST | /orders | write | create sales order |
| POST | /orders/bulk | write | bulk orders (max 100) |
| POST | /orders/:orderNo/cancel | write | cancel by order number |
LPN
| Method | Path | Scope | คำอธิบาย |
|---|---|---|---|
| POST | /lpn | write | create license plate |
Inquiry (read-only)
| Method | Path | Scope | คำอธิบาย |
|---|---|---|---|
| GET | /orders/:orderNo | read | order + lines + tasks + summary |
| GET | /asn/:asnNo | read | ASN + lines + receivedQty + GRNs |
| GET | /stock | read | by sku + warehouseCode (+ lotNo) |
ดูตัวอย่าง payload + response เต็ม: Push Integration API
Key features
- Identifier resolution — ใช้ business key (sku, code, warehouseCode) ไม่ใช่ UUID — service auto-resolve เป็น UUID
- Idempotency — header
Idempotency-Key(TTL 24 ชม.) — ส่งซ้ำ body เดิม → replay - Bulk 207 Multi-Status — bulk endpoint อาจตอบ 207 ถ้ามีบาง item error
- Tenant scoping — API Key ผูกกับ
tenantId→ จำกัดขอบเขตอัตโนมัติ
2. Security & Rate Limiting (per API Key)
ตั้งได้รายตัวใน Admin Portal → API Keys:
IP Whitelist
- รับทั้ง exact IP (
203.0.113.5) และ CIDR (203.0.113.0/24) - เช็คจาก
X-Forwarded-For(Render ส่ง real IP) - ว่าง = อนุญาตทุก IP
Allowed Origins (CORS)
- เช็ค
Originheader - ถ้าไม่มี Origin (server-to-server) → อนุญาต
- ถ้ามี + ไม่อยู่ใน list → 403
Rate Limit
- req/min ต่อ key (sliding 60s window, in-memory)
0หรือว่าง = unlimited- เกิน → 429 + header
Retry-After,X-RateLimit-Limit,X-RateLimit-Remaining
Request Logging
- ทุก request log async ลง
api_key_requesttable - ใช้ในหน้า "API Key Stats" (Admin Portal)
3. Webhooks (Outbound)
ระบบ WMS push event ไปยัง URL ของ external system
Model: WebhookSubscription
{
id: UUID;
tenantId: UUID;
url: string; // your endpoint
events: string[]; // ['order.shipped', 'asn.received', ...]
secret: string; // HMAC secret
active: boolean;
filters?: Json; // optional event filter
}Supported events
| Event | Trigger |
|---|---|
asn.received | GRN created against ASN |
asn.completed | ASN fully received |
order.allocated | Stock allocated to order |
order.released | Order released as pick tasks |
order.shipped | Shipment dispatched |
order.cancelled | Order cancelled |
stock.adjusted | Stock adjustment posted |
cyclecount.variance | Variance detected during count |
Payload format
{
"event": "order.shipped",
"timestamp": "2026-06-15T10:30:00.000Z",
"data": {
"orderNo": "SO-20260615-0042",
"shipmentNo": "SHIP-...",
"trackingNo": "TH123..."
}
}Delivery tracking
WebhookDelivery model — บันทึกทุกครั้งที่ส่ง:
responseStatus,responseBody,attempts,nextRetryAt- status:
pending/success/failed/dead_letter
Admin endpoints
| Method | Path | คำอธิบาย |
|---|---|---|
| GET | /webhooks | list subscriptions |
| POST | /webhooks | create |
| PATCH | /webhooks/:id | update |
| DELETE | /webhooks/:id | remove |
| POST | /webhooks/:id/test | fire test event |
4. File Storage — Cloudflare R2
ใช้สำหรับ:
- Shipping labels (PDF)
- Generated reports (Excel/PDF)
- Upload attachments (RMA photos, GRN docs)
Setup
S3-compatible — ใช้ @aws-sdk/client-s3 + @aws-sdk/s3-request-presigner ใน apps/api/src/modules/files/
Env vars:
R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=...
R2_SECRET_ACCESS_KEY=...
R2_BUCKET_NAME=wms-filesUpload pattern (presigned URL)
1. Client → POST /api/v1/files/presigned-upload
{ fileName, contentType }
2. API → returns { uploadUrl, fileKey, expiresIn: 300 }
3. Client → PUT <uploadUrl> with file body (direct to R2)
4. Client → POST /api/v1/<resource> { fileKey: "..." }
(เก็บ key ใน DB; access ภายหลังด้วย presigned GET URL)ทำไม R2
- ไม่มี egress fees (ต่าง S3 / GCS)
- S3-compatible API → reuse SDK ได้
- Cloudflare network → latency ต่ำ
5. Email (placeholder)
ตอนนี้ระบบ ยังไม่ wire email provider — code มี hook สำหรับ:
- Welcome email (user create)
- Password reset
- Approval notifications
แนะนำ provider เมื่อพร้อม: Resend หรือ AWS SES (cheap, transactional)
ตำแหน่งที่จะใส่: สร้าง MailModule + service ใน apps/api/src/modules/mail/ — inject เข้า UsersService + ApprovalsService
Integration Best Practices
- Production keys ตั้ง IP whitelist เสมอ — ลดความเสียหายถ้า key รั่ว
- Rate limit ตามจริง — เช่น ERP: 120 req/min
- Allowed Origins เฉพาะ key สำหรับ browser — server-to-server ไม่ต้อง
- Rotate ทุก 90 วัน — สร้างใหม่ → verify → revoke เก่า
- แยก key ต่อ integration — ปิด/หมุนทีละตัว
- ใช้ Idempotency-Key ทุก POST — ป้องกัน duplicate จาก network retry
- Webhook endpoint ต้อง idempotent — เราจะ retry ถ้า fail