Bỏ qua để đến nội dung

SDK TypeScript

~2 phút đọc

@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.

Terminal window
npm install @dongtien/sdk
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Ý nghĩa
apiKeyBắt buộc. Khoá dt_live_… hoặc dt_test_…; chỉ gửi trong header Authorization.
baseUrlMặc định https://api.dongtien.pro.
versionNgày phiên bản gửi trong DongTien-Version. Bỏ trống thì dùng phiên bản ghim ở khoá.
maxRetriesSố lần thử lại sau lần đầu; mặc định 3, đặt 0 để tắt.
retryTinh chỉnh lùi thời gian (gốc, trần, đồng hồ, hàm ngủ); maxRetries luôn thắng.
fetchThay fetch toàn cục, ví dụ trong kiểm thử, qua proxy hay service binding của Workers.
headersHeader thêm vào mọi yêu cầu.
idempotencyKeyHàm thay bộ sinh khoá UUIDv7, chủ yếu cho kiểm thử.

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);
}

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.

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;
}
}