Hosted Checkout
TRADOM Paymentがhostする決済画面へ買い手をredirectする
Hosted Checkoutは、決済画面を自社で構築せずにステーブルコイン決済を導入する方法です。マーチャントのbackendは注文を作成し、返されたURLへ買い手をredirectします。
仕組み
Merchant backend ── createOrder ──> TRADOM Payment
│ │
└──── buyerをcheckoutUrlへ ────────> Hosted Checkout
│
token / network選択
QR表示・入金確認
│
Merchant backend <── checkoutStatus ───────┘Checkoutを作成
const checkout = await gatewayClient.gateway.createOrder({
orderId: "order_12345",
amount: 178.25,
currency: "USD",
buyerName: "Taro Yamada",
buyerEmail: "taro@example.com",
country: "JP",
items: [{ name: "T-shirt", category: "apparel" }],
returnUrl: "https://shop.example/thanks",
cancelUrl: "https://shop.example/cart",
mode: "live",
});| Field | Required | 説明 |
|---|---|---|
orderId | 必須 | 自社の注文ID。同じIDでの作成は冪等 |
amount | 必須 | 指定通貨の主単位。0より大きい有限数 |
currency | 任意 | JPY(省略時の既定)または USD |
buyerEmail / country / items | 推奨 | compliance screeningに使用 |
buyerName | 任意 | 買い手名 |
returnUrl | 強く推奨 | 支払い後の戻り先 |
cancelUrl | 任意 | キャンセル・審査却下時の戻り先 |
mode | 任意 | live(既定)/ testnet / simulate。staging(Fireblocks sandbox)では live は testnet に強制変換されます。実際のmodeはresponseの mode で確認してください |
Responseを処理
if (checkout.status === "ok") {
return redirectTo(checkout.checkoutUrl);
}
// kyc_declinedも通常のresponse。案内用URLへredirectする
return redirectTo(checkout.checkoutUrl);kyc_declined はexceptionではありません。通信・validation errorのみ PaymentError としてthrowされます。
ok responseの amount は送信した値をそのまま返すdecimal string、currency は正規化された JPY / USD です。保存時にJPYは整数、USDは小数第2位に丸められるため、checkoutStatus が返す amount は丸め後の値(例: "178" → "178.00")になります。JPYは整数、USDは小数第2位までで送ってください。
currency: "USD" はproductionで利用できます。JPY注文はUSD/JPY参照rate、USD注文はstablecoinの1:1 USD pegで見積もります。
支払い状態を確認
const status = await gatewayClient.gateway.checkoutStatus(checkoutToken);checkoutStatus は公開tokenで照合し、API keyを送信しません。redirectだけを信用せず、保存した orderId とcheckout tokenをbackendで関連付けてください。
| 確認したいこと | Field |
|---|---|
| 注文金額と法定通貨 | status.amount / status.currency |
| 全額の入金を確認したか | status.confirmed |
| 入金が不足しているか | status.underpaid(sentAmount / expectedAmount に数量) |
| 入金のtx hash・数量・通貨・network | status.txHash / paidAmount / paidCurrency / paidNetwork |
| 現在の処理段階 | status.state.state |
| 終了状態か | status.state.isTerminal |
| 不足・超過入金か | status.state.matchStatus |
| 買い手に表示中のmessage | status.message |
| 実行モード | status.mode |
| testnet faucet | status.faucets |
confirmed は「全額の入金を確認した」フラグです。不足入金では confirmed: false かつ underpaid: true(state.matchStatus: "underpaid")になります。「未入金」と「不足入金」を区別するには underpaid を見てください。
checkoutStatus はHosted Checkoutのpollingと同じendpointです。読み取り専用ではなく、未紐付けの入金を注文に紐付け、不足入金の分類を記録することがあります(注文の進行やキャンセルは行いません)。message は入金待ちの間 null です(M-5は表示されません)。
全状態は 状態リファレンス を参照してください。
Sessionと見積り
- Checkout session: 初回表示から45分(wallet確認のため
extendSessionで1回だけ+5分) - 入金用見積り: 15分
- 見積り更新: 最大2回
期限切れの場合は新しいcheckoutを作成します。sessionはHosted Checkoutの初回表示で開始します。SDKだけで操作し画面を開いていない注文では sessionExpired は false のままです。
Checkout操作
通常のredirect型integrationでは、Hosted Checkoutが次の操作を行います。SDK methodは自動smoke testや、token-scoped flowをbackendで制御する場合に使用します。これらはcheckout tokenで認可され、API keyを送信しません。
const quote = await gatewayClient.gateway.selectAsset(checkoutToken, {
token: "usdc",
network: "ethereum",
});
const refreshed = await gatewayClient.gateway.refreshQuote(checkoutToken);
const accepted = await gatewayClient.gateway.acceptTos(checkoutToken);selectAsset と refreshQuote は法定通貨の currency、depositAddress、token数量、rate、chain情報、mode、faucets を返します。JPY注文はUSD/JPY参照rate、USD注文はstablecoinの1:1 USD pegを使います。見積り更新は最大2回です。
simulate 注文はasset選択後に、資金を移動せず完了できます。
const completed = await gatewayClient.gateway.simulateDeposit(checkoutToken);simulateDeposit は live / testnet 注文を拒否します。詳しくは テスト方法 を参照してください。
参照見積りとwallet確認
Hosted Checkoutの設定画面が使う補助endpointもSDKから呼べます。
// 現在rateでの「≈ 数量」(拘束力なし・約12秒cache)
const ref = await gatewayClient.gateway.referenceQuote(checkoutToken);
if (ref.status === "ok") {
console.log(ref.quotes.usdc?.amounts.ethereum); // "329.87"
}
// 買い手walletの事前確認(少額テスト送金)の状態
const verify = await gatewayClient.gateway.verifyStatus(checkoutToken);
// verify.screening: "pending" | "clear" | "received" | "blocked"
// wallet確認中のsession延長(注文ごとに1回、+5分)
const ext = await gatewayClient.gateway.extendSession(checkoutToken);
// ext.extended: 初回のみtrue
// blockedになった確認をresetして別walletで再試行(注文ごとに最大2回)
const reset = await gatewayClient.gateway.resetVerification(checkoutToken);
// reset.screening: "pending" | "not_required"、reset.attemptsRemainingresetVerification は blocked 以外の状態では not_blocked(409)、上限到達時は reset_limit_reached(409)をthrowします。session期限切れ後はいずれも session_expired(409)です。
TRONとslippage判定
TRON / USDTは、マーチャントで有効化されている場合にasset選択に使用できます。
const verdict = await gatewayClient.gateway.slippageCheck(checkoutToken, {
token: "usdt",
network: "tron",
});
if (verdict.status === "exceeded") {
return showAnotherAsset();
}判定は ok、exceeded、skipped、unavailable のいずれかです。実際のasset選択時にもbackendが再検証します。
slippageCheck はproductionで利用できます。TRON / USDTの提供はマーチャント設定(Tron決済の有効化)に依存します。slippageCheck は正規のnetwork名(ethereum / polygon / tron)のみ受け付け、selectAsset が受け付ける別名(eth / pol / trx)は unsupported_asset になります。
認証
SDKは既定で X-Api-Key を使います。REST APIは次のどちらも受け付けます。
X-Api-Key: gw_live_...
Authorization: Bearer gw_live_...