TRADOM PaymentDocs

Hosted Checkout

TRADOM Paymentがhostする決済画面へ買い手をredirectする

Hosted Checkoutは、決済画面を自社で構築せずにステーブルコイン決済を導入する方法です。マーチャントのbackendは注文を作成し、返されたURLへ買い手をredirectします。

Quickstartで実装を始める →

仕組み

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",
});
FieldRequired説明
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・数量・通貨・networkstatus.txHash / paidAmount / paidCurrency / paidNetwork
現在の処理段階status.state.state
終了状態かstatus.state.isTerminal
不足・超過入金かstatus.state.matchStatus
買い手に表示中のmessagestatus.message
実行モードstatus.mode
testnet faucetstatus.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.attemptsRemaining

resetVerification は 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_...

このページの内容