JavaScript / SDK trình duyệt
@lartech/infraio-checkout-js là SDK duy nhất chúng tôi phát hành cho
đến nay. Nó chạy trong trình duyệt và mở checkout do hệ thống host.
SDK backend (Node, Go, Python) nằm trong roadmap; cho đến lúc đó, hãy
nói chuyện trực tiếp với gateway — xem Bắt đầu nhanh
để có helper ký HMAC.
- Phiên bản hiện tại:
0.1.1-beta.17(pre-1.0; có thể có thay đổi minor breaking) - Định dạng: ESM (
index.js), CJS (index.cjs), IIFE (index.global.js) - Types được bundle (
index.d.ts) - Không có runtime peer — không React, jQuery, hay dependency khác
Không có server-side entry. Helper xác thực chữ ký cho webhook
không được bundle — hãy tự cài đặt với crypto (trang
xác thực chữ ký có code
copy-paste trong 4 ngôn ngữ).
Cài đặt
npm
npm install @lartech/infraio-checkout-jsloadInfraIo(publicKey, options?)
Trả về Promise<InfraIoInstance>.
import { loadInfraIo } from "@lartech/infraio-checkout-js";
const sdk = await loadInfraIo("pk_live_yourkeyhere", {
// Tùy chọn. Chỉ override khi trỏ đến môi trường không phải prod.
checkoutUrl: "https://checkout-dev.infraio.xyz",
});| Param | Type | Bắt buộc | Ghi chú |
|---|---|---|---|
publicKey | string | ✓ | Phải khớp pk_(live|test)_… |
options.checkoutUrl | string | — | Override base checkout URL. Mặc định: https://checkout.infraio.xyz. URL gateway tương ứng được trang checkout xác định tại runtime — mỗi bản deploy checkout(-dev).infraio.xyz mang NEXT_PUBLIC_API_URL tại thời điểm compile, nên chọn đúng hostname ở đây sẽ tự động chọn đúng backend. Không có option gatewayUrl riêng. |
sdk.checkout({ … })
Mở checkout do hệ thống host. Trả về void (dùng callback cho trạng thái).
| Field | Type | Bắt buộc | Ghi chú |
|---|---|---|---|
sessionId | string | ✓ | session_key trả về bởi POST /b2b/v1/checkout-sessions/quick |
checkoutUrl | string | — | URL đầy đủ trả về bởi cùng endpoint. Nếu bỏ qua, SDK dựng từ checkoutUrl của loadInfraIo() (hoặc mặc định) + sessionId |
mode | "popup" | "redirect" | "embed" | — | Mặc định "popup" |
container | string | HTMLElement | chỉ embed | CSS selector hoặc DOM element nơi iframe mount |
width | number | — | Chỉ popup. Mặc định 560. Kẹp [320, 1280] |
height | number | — | Chỉ popup. Mặc định 780. Kẹp [400, 1000] |
timeoutMs | number | — | Chỉ popup. Timeout load iframe. Mặc định 30000. Gửi 0 để tắt |
locale | string | — | Tag BCP-47 forward dưới dạng ?locale= đến trang checkout (en, ja, zh-CN, zh-TW) |
hideSummary | boolean | — | Ẩn cột tóm tắt order. Mặc định false |
hideHeader | boolean | — | Ẩn header InfraIO và nút wallet-connect tích hợp sẵn. Mặc định false. Kết hợp với walletAddress để white-label đầy đủ |
walletAddress | string | — | Kết nối sẵn ví của người mua. Yêu cầu onSignRequest |
walletChainId | number | — | EVM chain ID cho ví được kết nối sẵn |
onReady | () => void | — | Phát khi iframe interactive. Chỉ popup/embed |
onSignRequest | (req: { method: string; params: unknown[] }) => Promise<string> | khi walletAddress set | SDK proxy wallet RPC đến handler của bạn; trả về hex đã ký |
onSuccess | ({ sessionId }) => void | — | Phát khi thanh toán thành công. Không phải nguồn xác thực — webhook mới là |
onCancel | () => void | — | Phát khi người mua đóng popup/embed mà không thanh toán |
onError | (err: InfraIoError) => void | — | Phát khi iframe load fail (chế độ popup + embed). Argument không hợp lệ được throw đồng bộ, không được giao qua đây. Chế độ redirect không có runtime error surface — failure được quan sát ở trang đã redirect đến. |
onSuccess không phải nguồn xác thực. Nó có thể được phát ngay
cả khi webhook sau đó xác định thanh toán đã fail (reorg testnet,
timing phía người mua). Chỉ dùng nó cho UX (hiển thị “Thanks!”,
redirect). Luôn xác nhận qua webhook trước khi fulfillment.
sdk.close()
Đóng programmatically popup hoặc embed đang mở. No-op cho chế độ redirect.
sdk.checkout({ sessionId, mode: "popup", /* … */ });
// sau đó, ví dụ khi người dùng điều hướng đi
sdk.close();sdk.openRefundRequest({ … })
Mở form refund-request do hệ thống host cho một token dùng một lần
mà backend của bạn đã phát hành qua POST /b2b/v1/merchants/{merchant_id}/refund-requests.
Người mua điền địa chỉ đích refund + lý do + metadata (tùy chọn) trên
trang của chúng tôi; trang của bạn chỉ xử lý vòng đời mở/đóng. Trả về
một hàm close() — gọi nó để programmatically đóng popup hoặc
detach embed iframe. Trong chế độ redirect, hàm trả về là no-op.
Form sống tại https://checkout.infraio.xyz/refund-request/:token.
Method này chỉ bọc URL đó trong popup / redirect / embed để người
mua không bao giờ rời domain của bạn (trong popup / embed) hoặc
quay lại nó tự động (trong redirect). Endpoint mà backend của bạn
gọi để phát hành token là POST /b2b/v1/merchants/{merchant_id}/refund-requests — ký
HMAC với khóa secret của bạn, cùng auth như phần còn lại của surface
B2B. Xem Khái niệm → Hoàn tiền.
import { loadInfraIo } from "@lartech/infraio-checkout-js";
const sdk = await loadInfraIo("pk_live_yourkeyhere");
// Phát hành token phía server, rồi giao nó cho SDK trong trình duyệt.
const { token } = await fetch("/api/mint-refund-token", { method: "POST" }).then(r => r.json());
const close = sdk.openRefundRequest({
token,
mode: "popup",
onSuccess: ({ linkToken, refundId }) => {
// Người mua đã submit form.
// linkToken → trang trạng thái /r/:linkToken (chia sẻ cho người mua).
// refundId → dùng với B2B API để approve / reject.
window.location.href = `/r/${linkToken}`;
},
onCancel: () => { /* người mua đã đóng mà không submit */ },
});
// Đóng popup programmatically sau đó nếu cần:
// close();| Field | Type | Bắt buộc | Ghi chú |
|---|---|---|---|
token | string | ✓ | Token rfqt_… trả về bởi POST /b2b/v1/merchants/{merchant_id}/refund-requests |
mode | "popup" | "redirect" | "embed" | — | Mặc định "popup". Cùng surface semantics như sdk.checkout() — xem Ghi chú chế độ |
container | string | HTMLElement | chỉ embed | CSS selector hoặc DOM element nơi iframe mount |
locale | string | — | Tag BCP-47 forward dưới dạng ?locale= (en, ja, zh-CN, zh-TW) |
hideHeader | boolean | — | Ẩn header InfraIO bên trong iframe. Trong popup/embed, SDK tự vẽ modal chrome riêng, nên header của trang thường là noise. Mặc định false |
hideSummary | boolean | — | Ẩn cột Order Summary, chỉ hiển thị form refund. Mặc định false |
walletAddress | string | — | Điền sẵn trường ví đích (?wallet_address=). Cho phép một merchant đã biết ví người mua bỏ qua việc nhập lại thủ công |
onSuccess | (data: { linkToken: string; refundId: string }) => void | — | Phát sau khi người mua submit form. linkToken → trang trạng thái /r/:linkToken để chia sẻ với người mua. refundId → dùng với B2B API để approve / reject |
onCancel | () => void | — | Phát khi người mua đóng popup/embed mà không submit |
onError | (err: InfraIoError) => void | — | Phát khi iframe load fail hoặc args không hợp lệ. Trường hợp token hết hạn / hủy được trang do hệ thống host xử lý, không qua onError |
Trạng thái token được surface qua onError
Nếu người mua mở một token đã cũ, bản thân trang xử lý hiển thị (render
prompt “Expired — request new link”, v.v.), và SDK không phát
onError cho các trường hợp đó — người mua đang ở trong luồng form
và code của bạn không cần phản ứng. onError chỉ phát cho những thứ
code của bạn có thể xử lý (args sai, network failure khi load iframe).
openRefundRequest ghi nhận intent refund — nó không di chuyển
vốn. Sau onSuccess, bản ghi refund ở trạng thái PENDING (hoặc
APPROVED nếu cấu hình merchant của bạn auto-approve refund của
khách hàng). Bạn vẫn cần ký và broadcast giao dịch chuyển on-chain
từ ví merchant của bạn, rồi POST tx hash đến
POST /b2b/v1/refunds/:id/submit-tx. Xem
Khái niệm → Hoàn tiền cho vòng đời đầy đủ.
Class Error
import { InfraIoError } from "@lartech/infraio-checkout-js";
sdk.checkout({
sessionId,
onError: (err: InfraIoError) => {
switch (err.code) {
case "invalid_request_error": /* sessionId / args sai */ break;
case "iframe_load_error": /* iframe load fail */ break;
case "iframe_timeout_error": /* vượt timeoutMs */ break;
case "already_open_error": /* một checkout khác đang mở */ break;
case "network_error": /* vấn đề mạng tạm thời với origin checkout */ break;
case "api_error": /* backend trả về non-2xx cho call do SDK phát */ break;
}
},
});sdk.openRefundRequest() chỉ throw invalid_request_error (thiếu
hoặc token / args không hợp lệ), đồng bộ. iframe_load_error (iframe
refund-request load fail) được giao bất đồng bộ qua onError,
không throw. Nó không phát iframe_timeout_error hay
already_open_error — popup refund-request không có load-timeout và
cho phép nhiều popup đồng thời.
Ghi chú chế độ
Popup
- Overlay căn giữa với backdrop nửa trong suốt tối
z-index: 2147483647(max int32) — nằm trên mọi thứ khác- Cuộn body bị khóa khi mở; phục hồi khi đóng
- Nút close nhận focus ban đầu; Tab bị bẫy trong popup
- Đóng bởi: nút close, Escape, click bên ngoài,
sdk.close(). Tất cả đều gọionCancel - Trang checkout có thể yêu cầu resize qua
postMessage— SDK kẹp trong giới hạnwidth/height
Redirect
- Điều hướng cứng qua
window.location.href - Tự động nối thêm
?return_url=<current-page>để người mua quay về nơi họ đến. Nếusuccess_url/cancel_urltrên session đã cover điều này, round-trip bỏ quareturn_url
Embed
- iframe với
allow="payment; clipboard-write"(chỉ thị HTML5 Feature Policy — không phải thuộc tínhsandbox). iframe được serve từ origin checkout, nên popup ví và clipboard write từ phía người mua hoạt động mà không cần opt-in thêm. - Container width 100%; height tự sizing qua postMessage
INFRAIO_RESIZE, kẹp[200, 2000]px - Không có CSS isolation ngoài biên iframe — style trang parent của bạn không bleed vào
- Luôn wire
onReadyđể bạn có thể ẩn loading state của riêng mình khi checkout trở nên interactive
TypeScript
Tất cả types được bundle. Các export hữu ích nhất:
import type {
CheckoutOptions,
RefundRequestOptions,
LoadOptions,
InfraIoInstance,
InfraIoErrorCode,
} from "@lartech/infraio-checkout-js";
import { loadInfraIo, InfraIoError, VERSION } from "@lartech/infraio-checkout-js";VERSION là chuỗi phiên bản của SDK — hữu ích trong bug report.
Tiếp theo
- Wrapper framework React / Vue — đang được lên kế hoạch cho lần
lặp post-launch khi surface vanilla JS ổn định qua các merchant pilot.
SDK vanilla hoạt động ổn trong React hôm nay; các wrapper sẽ chỉ
loại bỏ phần
useRefthủ công + vòng đời. - Khôi phục session đa tab — mở checkout ở tab A, hoàn tất ở tab B. Hữu ích khi một người mua follow một magic-link giữa luồng. Đang được theo dõi cho bản minor tiếp theo.
- Theming qua CSS variable — surface một bộ design token nhỏ (radius, accent colour) trên iframe để merchant có thể match brand mà không phải fork trang.
- Helper server-side — một gói nhỏ
@lartech/infraio-serverexposeverifyWebhook()+signedRequest()để code backend không cần copy thao tác HMAC. Cho đến khi nó được ship, trang xác thực chữ ký liệt kê các cài đặt drop-in trong TypeScript, Go, Python, và Ruby.