SDK TypeScript
Dùng @dongtien/sdk để gọi API Dòng Tiền Pro với kiểu dữ liệu đầy đủ: createClient, tuỳ chọn, paginate, idempotency, thử lại và xử lý ApiError. dung @dongtien/sdk de goi api dong tien pro voi kieu du lieu day du: createclient, tuy chon, paginate, idempotency, thu lai va xu ly apierror.@dongtien/sdk là client TypeScript xây trên openapi-fetch: đường dẫn, tham số, thân yêu cầu và phản hồi đều có kiểu được sinh từ đặc tả OpenAPI công khai. Nó chạy trên mọi môi trường có fetch: Node 20 trở lên, trình duyệt, Cloudflare Workers, Deno và Bun.
npm install @dongtien/sdkTạo client và gọi API
Phần tiêu đề “Tạo client và gọi API”import { createClient } from "@dongtien/sdk";
const dt = createClient({ apiKey: process.env.DT_API_KEY! }); // dt_test_… hoặc dt_live_…
// Lỗi không thành công sẽ ném ApiError, nên `data` luôn là phần thân thành công.const { data } = await dt.GET("/v1/transactions", { params: { query: { status: "confirmed", limit: 20 } },});console.log(data?.data.map((tx) => tx.id));Phương thức theo HTTP (GET, POST, PATCH) nhận đường dẫn của đặc tả; trình biên dịch báo lỗi khi đường dẫn, tham số hay thân sai.
Tuỳ chọn của createClient
Phần tiêu đề “Tuỳ chọn của createClient”| Tuỳ chọn | Ý nghĩa |
|---|---|
apiKey | Bắt buộc. Khoá dt_live_… hoặc dt_test_…; chỉ gửi trong header Authorization. |
baseUrl | Mặc định https://api.dongtien.pro. |
version | Ngày phiên bản gửi trong DongTien-Version. Bỏ trống thì dùng phiên bản ghim ở khoá. |
maxRetries | Số lần thử lại sau lần đầu; mặc định 3, đặt 0 để tắt. |
retry | Tinh chỉnh lùi thời gian (gốc, trần, đồng hồ, hàm ngủ); maxRetries luôn thắng. |
fetch | Thay fetch toàn cục, ví dụ trong kiểm thử, qua proxy hay service binding của Workers. |
headers | Header thêm vào mọi yêu cầu. |
idempotencyKey | Hàm thay bộ sinh khoá UUIDv7, chủ yếu cho kiểm thử. |
Phân trang
Phần tiêu đề “Phân trang”paginate(path, init) đi qua từng phần tử của mọi trang; pages(path, init) trả từng trang dạng { data, next_cursor, has_more }. Cursor không phải thứ bạn tự xử lý.
for await (const tx of dt.paginate("/v1/transactions", { params: { query: { direction: "in" } } })) { console.log(tx.id, tx.amount);}Idempotency và thử lại
Phần tiêu đề “Idempotency và thử lại”Với route khai báo idempotent, SDK tự gắn Idempotency-Key (UUIDv7) một lần cho mỗi lời gọi và gửi lại đúng khoá đó ở mọi lần thử lại. Muốn tự chọn khoá, truyền header của chính bạn; khoá của bạn được ưu tiên. Route bắt buộc khoá còn nhận thêm tham số header idempotency-key theo kiểu của đặc tả.
await dt.POST("/v1/bank-accounts", { params: { header: { "idempotency-key": crypto.randomUUID() } }, body: { company_id: "org_…", bank_code: "ACB", account_number: "…", type: "business" },});SDK thử lại tối đa 3 lần: 429 luôn thử lại theo Retry-After (lớn hơn 60 giây thì ném lỗi thay vì ngủ chờ), còn 5xx và lỗi mạng chỉ với GET, HEAD, OPTIONS, PUT, DELETE hoặc yêu cầu có khoá idempotency. Chi tiết ở trang SDK và Idempotency.
import { ApiError, ConnectionError } from "@dongtien/sdk";
try { await dt.GET("/v1/transactions", { params: { query: { limit: 500 } } });} catch (error) { if (error instanceof ApiError) { console.error(error.code, error.requestId, error.errors); // rẽ nhánh theo error.code } else if (error instanceof ConnectionError) { console.error("không nhận được phản hồi"); } else { throw error; }}ApiError có status, code, title, detail, type, requestId, errors, retryable và retryAfter. Đọc requestId khi cần liên hệ hỗ trợ. ConnectionError nghĩa là yêu cầu không có phản hồi nào sau khi hết số lần thử lại. Ý nghĩa từng trường ở trang Lỗi.
Xác minh Webhook
Phần tiêu đề “Xác minh Webhook”Gói @dongtien/sdk xuất sẵn không gian tên webhooks và lớp WebhookVerificationError để xác minh chữ ký Standard Webhooks (HMAC-SHA256, dung sai mặc định 300 giây):
import { webhooks, WebhookVerificationError } from "@dongtien/sdk";
export async function handleWebhook(request: Request) { const rawBody = await request.text(); // raw bytes hoặc text thô try { const event = webhooks.verify(rawBody, request.headers, process.env.DTP_WEBHOOK_SECRET!); console.log("Sự kiện hợp lệ:", event); return new Response("ok", { status: 200 }); } catch (err) { if (err instanceof WebhookVerificationError) { return new Response("invalid signature", { status: 400 }); } throw err; }}