LOCBOX

API Referral & Attribution

Hệ thống headless: không quản lý tài khoản, không đăng nhập end-user. App chính giữ user và gọi các endpoint dưới đây bằng header X-Api-Key. Mọi response là JSON UTF-8 kèm request_id.

Xác thực

Gửi khóa bí mật ở header X-Api-Key. Rate limit mặc định 600 request/phút mỗi khóa; vượt hạn mức trả 429 kèm Retry-After.

X-Api-Key: <khóa do LocBox cấp>
Content-Type: application/json

Endpoints

POST/api/public/ref/users

Gọi khi user đăng ký. Idempotent theo uuid — gọi lại trả cùng kết quả.

Ví dụ curl

curl -s -X POST "https://link.locbox.vn/api/public/ref/users" \
  -H "X-Api-Key: $LOCBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "uuid": "1f0b...uuid của app chính",
  "referred_by_code": "K7RMD4X",
  "clipboard_token": "LOCBOX#K7RMD4X",
  "install_referrer": "ref_code=K7RMD4X&utm_source=locbox",
  "platform": "android"
}'

Response

{
  "created": true,
  "uuid": "1f0b...",
  "ref_code": "T9WQZ2M",
  "invite_url": "https://link.locbox.vn/open/invite/T9WQZ2M",
  "referred_by": "8ac2...",
  "request_id": "..."
}
POST/api/public/ref/users/batch

Backfill tối đa 500 user cũ. Trả về mảng kết quả + lỗi từng dòng.

Ví dụ curl

curl -s -X POST "https://link.locbox.vn/api/public/ref/users/batch" \
  -H "X-Api-Key: $LOCBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "users": [
    { "uuid": "...", "referred_by_code": "K7RMD4X" },
    { "uuid": "...", "ref_code": "LEGACY7" }
  ]
}'

Response

{ "results": [ ... ], "errors": [ ... ], "request_id": "..." }
POST/api/public/ref/match

Deferred attribution sau khi cài app: ưu tiên install_referrer / clipboard, sau đó match fingerprint trong 24h.

Ví dụ curl

curl -s -X POST "https://link.locbox.vn/api/public/ref/match" \
  -H "X-Api-Key: $LOCBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "uuid": "...",
  "clipboard_token": "LOCBOX#K7RMD4X",
  "install_referrer": "ref_code=K7RMD4X",
  "screen": "390x844@3",
  "timezone": "Asia/Ho_Chi_Minh",
  "language": "vi-VN",
  "user_agent": "..."
}'

Response

{ "matched": true, "ref_code": "K7RMD4X", "confidence": 0.92, "method": "fingerprint" }
POST/api/public/ref/events

Ghi nhận mua hàng / nạp tiền. Idempotent theo external_ref.

Ví dụ curl

curl -s -X POST "https://link.locbox.vn/api/public/ref/events" \
  -H "X-Api-Key: $LOCBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "uuid": "...",
  "event_type": "purchase",
  "amount": 250000,
  "currency": "VND",
  "external_ref": "order_2026_00123"
}'

Response

{ "recorded": true, "duplicate": false, "event_id": "...", "beneficiary_uuid": "..." }
GET/api/public/ref/summary?uuid=<uuid>

Tổng quan cho 1 user: số lượt mời, số user đã mua, tổng chi tiêu downline, thưởng theo trạng thái.

Ví dụ curl

curl -s "https://link.locbox.vn/api/public/ref/summary?uuid=<uuid>" \
  -H "X-Api-Key: $LOCBOX_API_KEY"

Response

{
  "invited_count": 12,
  "converted_count": 5,
  "downline_spend": 4200000,
  "reward_total": 0,
  "rewards_by_status": { "pending": 0, "approved": 0, "paid": 0, "void": 0 }
}
GET/api/public/ref/downline?uuid=<uuid>&page=1&limit=20

Danh sách người được mời (uuid ẩn danh, thời điểm join, tổng chi tiêu).

Ví dụ curl

curl -s "https://link.locbox.vn/api/public/ref/downline?uuid=<uuid>&page=1&limit=20" \
  -H "X-Api-Key: $LOCBOX_API_KEY"

Response

{ "page": 1, "limit": 20, "total": 12, "items": [ { "uuid_masked": "1f0b2c3d****9a12", "joined_at": "...", "total_spend": 250000 } ] }
GET/api/public/ref/users/<uuid>

Tra cứu ref_code và invite_url của một user.

Ví dụ curl

curl -s "https://link.locbox.vn/api/public/ref/users/<uuid>" \
  -H "X-Api-Key: $LOCBOX_API_KEY"

Response

{ "uuid": "...", "ref_code": "T9WQZ2M", "invite_url": "https://link.locbox.vn/open/invite/T9WQZ2M" }

Link mời & deep link

Mỗi user có link dạng https://link.locbox.vn/open/invite/<ref_code> (alias ngắn /i/<code>). Trang này SSR đầy đủ Open Graph cho Zalo/Messenger/Facebook, ghi log click, copy token LOCBOX#<code> vào clipboard rồi tự mở app: Android qua App Link/intent với fallback Play Store kèm referrer=ref_code%3D<code>, iOS qua Universal Link với fallback App Store, desktop hiển thị QR.

GET https://link.locbox.vn/.well-known/assetlinks.json
GET https://link.locbox.vn/.well-known/apple-app-site-association

Webhook ngược (HMAC-SHA256)

Khi có lượt mời mới hoặc đơn hàng được ghi nhận, hệ thống POST về backend app chính với chữ ký HMAC-SHA256 trên chuỗi <timestamp>.<raw_body>. Retry backoff 1/5/15/60/180/720 phút, tối đa 6 lần.

  • referral.joined — user mới gắn được người giới thiệu
  • referral.purchase — ghi nhận đơn hàng / nạp tiền
  • reward.granted — phát sinh khoản thưởng (bật khi rule thưởng được cấu hình)
POST <REF_WEBHOOK_TARGET_URL>
X-Signature: sha256=<hex>
X-Timestamp: 1786274141
X-Webhook-Event: referral.joined

{ "event": "referral.joined", "timestamp": "1786274141", "data": { ... } }

Kiểm tra chữ ký phía bạn:

const expected = crypto
  .createHmac("sha256", REF_WEBHOOK_SECRET)
  .update(`${timestamp}.${rawBody}`)
  .digest("hex");

Checklist tích hợp

iOS

  1. Bật Associated Domains: applinks:link.locbox.vn.
  2. Gửi LocBox Apple Team ID + bundle ID để cập nhật AASA.
  3. Xử lý Universal Link /open/invite/<code> và scheme locbox://invite?code=.
  4. Lần mở app đầu tiên: đọc clipboard, bắt chuỗi LOCBOX#<code>.
  5. Nếu không có code: gọi POST /match kèm fingerprint để quy kết trì hoãn.

Android

  1. Khai báo intent-filter App Link cho link.locbox.vn (autoVerify).
  2. Gửi SHA-256 fingerprint bản release để cập nhật assetlinks.json.
  3. Đọc Install Referrer, lấy ref_code từ tham số referrer.
  4. Fallback: đọc clipboard LOCBOX#<code>.
  5. Fallback cuối: gọi POST /match.

Backend app chính

  1. Lưu API key vào secret, gửi header X-Api-Key cho mọi request.
  2. Khi user đăng ký: POST /users (idempotent theo uuid).
  3. Backfill user cũ bằng POST /users/batch (500/lần).
  4. Khi thanh toán thành công: POST /events với external_ref duy nhất.
  5. Mở endpoint nhận webhook, verify X-Signature rồi trả 2xx.

Mã lỗi

  • unauthorized (401) — thiếu hoặc sai X-Api-Key
  • invalid_json / invalid_input (400) — body sai định dạng hoặc không qua Zod
  • not_found (404) — uuid hoặc ref_code không tồn tại
  • rate_limited (429) — vượt hạn mức
  • server_error (500) — lỗi hệ thống, gửi kèm request_id khi báo lỗi