Seller SOS API Reference
Base URL: https://boxme-sos.pages.dev/api
Tất cả API trả về JSON. Authentication sử dụng Supabase Auth (Bearer token) hoặc demo token.
🏥 Health Check
GET /api/health
// Response 200
{ "status": "ok", "module": "sos-seller", "timestamp": "2026-02-22T00:00:00.000Z" }
🔐 Auth
POST /api/auth/supabase-login
Đăng nhập bằng Supabase Auth.
// Request
{ "email": "admin@boxme.vn", "password": "your_password" }
// Response 200
{
"success": true,
"user": {
"id": 1, "username": "admin", "role": "bod",
"warehouse_id": null, "full_name": "Admin",
"warehouse_name": null, "email": "admin@boxme.vn"
},
"session": {
"access_token": "eyJ...",
"refresh_token": "abc...",
"expires_at": 1708000000
}
}
GET /api/auth/me
Verify session và lấy thông tin user hiện tại.
Authorization: Bearer <access_token>
// Response 200
{
"id": 1, "username": "admin", "role": "bod",
"warehouse_id": null, "full_name": "Admin",
"warehouse_name": null, "email": "admin@boxme.vn",
"employee_code": "BM001", "employee_id": 1
}
POST /api/auth/update-password
Authorization: Bearer <access_token>
// Request
{ "new_password": "new_secure_password" }
// Response 200
{ "success": true, "message": "Mật khẩu đã được cập nhật" }
POST /api/auth/login (Legacy/Demo)
// Request
{ "username": "admin", "password": "admin" }
// Response 200
{ "success": true, "user": { ... }, "token": "demo_token_1_bod" }
🏪 Sellers
GET /api/sellers
Danh sách sellers với filtering và pagination.
| Query Param | Type | Default | Description |
|---|---|---|---|
status | string | active | active / suspended / terminated |
warehouse_id | number | — | Filter by warehouse |
am_id | number | — | Filter by Account Manager |
search | string | — | Search seller_code or company_name |
page | number | 1 | Page number |
limit | number | 20 | Items per page |
// Response 200
{
"data": [
{
"id": 1, "seller_code": "SEL001", "company_name": "Acme Corp",
"contract_type": "B2C", "status": "active",
"am_name": "Nguyen Van A", "warehouse_name": "HN-CG"
}
],
"total": 42, "page": 1, "limit": 20
}
GET /api/sellers/:id
Chi tiết seller (lookup by id hoặc seller_code).
POST /api/sellers
// Request (required: seller_code, company_name)
{
"seller_code": "SEL001",
"company_name": "Acme Corp",
"contract_start_date": "2026-01-01",
"contract_type": "B2C",
"primary_warehouse_id": 1,
"assigned_am_id": 1,
"oms_system_type": "native",
"payment_terms_days": 30,
"metadata": {}
}
// Response 200
{ "success": true, "id": 1 }
PATCH /api/sellers/:id
Cập nhật seller. Chỉ gửi fields cần thay đổi.
// Request
{ "status": "suspended", "payment_terms_days": 15 }
// Response 200
{ "success": true }
GET /api/sellers/:id/exceptions
Danh sách score exceptions của seller.
POST /api/sellers/:id/exceptions
// Request (required: exception_type, adjustment_rule, effective_from)
{
"exception_type": "new_seller_grace",
"score_component_affected": "o_score",
"adjustment_rule": { "set_score": 100 },
"reason": "Seller mới, chưa đủ data O-Score",
"approved_by": "admin",
"effective_from": "2026-01-01",
"effective_to": "2026-03-31"
}
// Response 200
{ "success": true, "id": 5 }
DELETE /api/sellers/:sellerId/exceptions/:exId
Soft-delete exception (is_active = 0).
GET /api/sellers/am/list
Danh sách Account Managers.
POST /api/sellers/am/create
{ "name": "Nguyen Van A", "email": "a@boxme.vn", "employee_id": 10 }
📅 Campaigns
GET /api/campaigns
| Query Param | Type | Description |
|---|---|---|
status | string | upcoming / active / completed / cancelled |
type | string | major_campaign / mini_campaign |
page / limit | number | Pagination |
GET /api/campaigns/:id
Chi tiết campaign (by id or campaign_code).
POST /api/campaigns
// Required: campaign_code, campaign_name, campaign_type, start_date, end_date
{
"campaign_code": "CAMP-2026-02",
"campaign_name": "Valentine Sale",
"campaign_type": "major_campaign",
"start_date": "2026-02-10",
"end_date": "2026-02-16",
"warehouses": ["1", "2"],
"description": "Valentine flash sale",
"created_by": "admin"
}
PATCH /api/campaigns/:id
Update campaign fields.
DELETE /api/campaigns/:id
Cancel campaign (sets status = 'cancelled').
GET /api/campaigns/:id/forecasts
Danh sách seller forecast submissions cho campaign.
GET /api/campaigns/:id/actuals
Danh sách kết quả thực tế (actual results) cho campaign.
📊 SOS Scores
GET /api/sos/sellers/:seller_code/score
Điểm SOS hiện tại của seller (kỳ gần nhất).
// Response 200
{
"seller_code": "SEL001",
"period": "2026-02",
"total_sos": 85.7,
"tier": {
"name": "Gold", "color": "#FFD700",
"benefits": "Priority support, lower surcharge"
},
"components": {
"p_score": { "raw": 85, "weighted": 21.25 },
"o_score": { "raw": 90, "weighted": 18.0 },
"t_score": { "raw": 80, "weighted": 16.0 },
"f_score": { "raw": 100, "weighted": 20.0 },
"i_score": { "raw": 70, "weighted": 10.5 }
},
"trend": { "previous_sos": 82.0, "delta": 3.7, "direction": "improving" },
"top_opportunity": "i_score",
"is_grace_period": false,
"status": "final"
}
GET /api/sos/sellers/:seller_code/score/history
Lịch sử điểm SOS (tối đa 24 kỳ).
| Query Param | Description |
|---|---|
from | Period bắt đầu (YYYY-MM) |
to | Period kết thúc (YYYY-MM) |
GET /api/sos/sellers/:seller_code/enforcement
Kiểm tra enforcement cho WMS — seller có bị block/surcharge không?
// Response 200
{
"seller_code": "SEL001",
"is_blocked": false,
"active_surcharges": [
{ "type": "aging_storage_multiplier", "amount": 150000, "period": "2026-02", "reason": "Inventory aging > 30%" }
]
}
GET /api/sos/tiers
Danh sách tier config (public).
GET /api/sos/monthly
Danh sách monthly scores (admin view).
| Query Param | Type | Default | Description |
|---|---|---|---|
period | string | current month | Format: YYYY-MM |
status | string | — | draft / under_review / final |
am_id | number | — | Filter by AM |
page / limit | number | Pagination |
PATCH /api/sos/monthly/:id/finalize
Finalize điểm SOS → triggers webhook events.
// Request
{ "reviewed_by": "admin", "notes": "Reviewed and approved" }
// Response 200
{ "success": true }
// → Webhook: seller.score_finalized
// → Webhook: seller.tier_changed (nếu tier thay đổi so với kỳ trước)
POST /api/sos/monthly/calculate
Trigger scoring engine cho tất cả active sellers.
// Request
{ "period": "2026-02" }
// Response 200
{
"period": "2026-02",
"sellers_scored": 42,
"results": [
{ "seller_id": "1", "total_sos": 85.7, "tier": "Gold", "grace": false }
]
}
📋 Appeals
Xem chi tiết tại Appeals & Surcharges.
GET /api/appeals
| Query Param | Description |
|---|---|
status | pending / under_review / approved / partially_approved / rejected / expired |
period | Format: YYYY-MM |
POST /api/appeals
{
"seller_code": "SEL001",
"period": "2026-02",
"component_appealed": "o_score",
"appeal_reason_type": "system_sync_error",
"description": "OMS sync bị lỗi ngày 2026-02-05",
"evidence_urls": ["https://drive.google.com/file/..."],
"submitted_by_am_id": 1
}
GET /api/appeals/:id
PATCH /api/appeals/:id/review-ops
Ops Head review.
{ "decision": "approve", "notes": "Confirmed OMS issue", "reviewed_by": "ops_head" }
PATCH /api/appeals/:id/review-am
AM Head review (final decision). Có thể kèm score adjustment.
{
"decision": "approve",
"notes": "Approved with adjustment",
"reviewed_by": "am_head",
"score_adjustment": { "o_score_raw_after": 90, "total_sos_after": 87.5 }
}
🔔 Webhooks
Xem chi tiết tại Webhook Integration.
GET /api/webhooks — List subscriptions
POST /api/webhooks — Create subscription
PATCH /api/webhooks/:id — Update subscription
DELETE /api/webhooks/:id — Delete (soft)
GET /api/webhooks/logs — Delivery logs
📈 Dashboard
GET /api/dashboard/stats
| Query Param | Description |
|---|---|
period | Format: YYYY-MM (default: current) |
warehouse_id | Filter by warehouse |
// Response 200
{
"period": "2026-02",
"total_sellers": 42,
"avg_sos": 81.5,
"scored_sellers": 38,
"tier_distribution": [
{ "tier_name": "Gold", "count": 15 },
{ "tier_name": "Silver", "count": 12 }
],
"pending_appeals": 3,
"active_surcharges": 5,
"top_improved": [ { "seller_code": "SEL001", "sos_delta": 8.5, ... } ],
"top_declined": [ { "seller_code": "SEL042", "sos_delta": -5.2, ... } ]
}
💰 Surcharges
GET /api/surcharges
| Query Param | Description |
|---|---|
seller_code | Filter by seller |
status | pending / applied / waived |
period | Format: YYYY-MM |
POST /api/surcharges
{
"seller_code": "SEL001",
"period": "2026-02",
"surcharge_type": "planning_overload",
"amount": 500000,
"trigger_details": { "reason": "No forecast submitted" }
}
// → Webhook: seller.surcharge_created
// → Webhook: seller.order_blocked (nếu type = payment_block)
PATCH /api/surcharges/:id
{ "status": "waived" }
🔄 Data Sync
Xem chi tiết tại Data Sync Integration.
| Endpoint | Source | Description |
|---|---|---|
POST /api/sync/orders | OMS | Order timing data |
POST /api/sync/forecasts | OMS | Forecast submissions |
POST /api/sync/campaign-actuals | WMS/OMS | Actual campaign results |
POST /api/sync/tickets | Helpdesk | Ticket SLA metrics |
POST /api/sync/payments | Accounting | Payment data |
POST /api/sync/inventory | WMS | Inventory snapshots |
POST /api/sync/revenue | Accounting | AM revenue data |
👤 AM Portfolio
GET /api/am/portfolio
| Query Param | Description |
|---|---|
period | Format: YYYY-MM (default: current) |
GET /api/am/portfolio/:amId
AM detail + danh sách sellers trong portfolio.
GET /api/am/portfolio/:amId/history
Lịch sử KPI của AM (tối đa 12 kỳ).
⚙️ Configuration
Xem chi tiết tại Configuration Reference.
Tất cả config endpoints follow pattern CRUD chung:
GET /api/config/<type>— List activeGET /api/config/<type>/:id— Get by idPOST /api/config/<type>— CreatePUT /api/config/<type>/:id— UpdateDELETE /api/config/<type>/:id— Soft delete
Available types:
score-weights, tiers, p-score, o-score, t-score, f-score, i-score, surcharge, am-bonus-penalty, am-kpi-weight, grace-period, helpdesk
Error Responses
Tất cả errors trả về format:
{ "error": "Human-readable error message" }
| Status Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad Request (missing/invalid params) |
| 401 | Unauthorized (invalid/expired token) |
| 404 | Resource not found |
| 500 | Internal Server Error |