<!-- Source: https://docs.infraio.xyz/ja/sdks/javascript -->
<!-- Last updated: 2026-10-04 -->

# JavaScript / ブラウザ SDK

`@lartech/infraio-checkout-js` は現在公開している唯一の SDK です。
ブラウザで動作し、ホスト型チェックアウトを開きます。バックエンド
SDK はまだありません。API を直接呼び出してください。HMAC 署名ヘルパーは
[クイックスタート](https://docs.infraio.xyz/ja/get-started/quickstart) にあります。

- 現在のバージョン: `0.1.1-beta.17` (1.0 未満; マイナーな破壊的変更があり得ます)
- フォーマット: **ESM** (`index.js`)、**CJS** (`index.cjs`)、**IIFE** (`index.global.js`)
- 型定義同梱 (`index.d.ts`)
- ランタイム依存ゼロ — React、jQuery などの依存なし

> **Note:**
>
> **サーバーサイドエントリは存在しません。** Webhook の署名検証ヘルパーは
> 同梱されていません — `crypto` を使って自前で実装してください
> ([署名検証ページ](https://docs.infraio.xyz/ja/webhooks/signature-verification) に 4 言語の
> コピペ可能なコードがあります)。

## インストール

**npm**

```bash
npm install @lartech/infraio-checkout-js
```

**pnpm**

```bash
pnpm add @lartech/infraio-checkout-js
```

**yarn**

```bash
yarn add @lartech/infraio-checkout-js
```

**bun**

```bash
bun add @lartech/infraio-checkout-js
```

**CDN**

```html
<script src="https://unpkg.com/@lartech/infraio-checkout-js/dist/index.global.js"></script>
<script>
  const sdk = await InfraIo.loadInfraIo("pk_live_yourkeyhere");
  sdk.checkout({ sessionId, checkoutUrl });
</script>
```

## `loadInfraIo(publicKey, options?)`

`Promise<InfraIoInstance>` を返します。

```ts
import { loadInfraIo } from "@lartech/infraio-checkout-js";

const sdk = await loadInfraIo("pk_live_yourkeyhere", {
  // 任意。本番以外の環境を指す場合のみ上書きしてください。
  checkoutUrl: "https://checkout-dev.infraio.xyz",
});
```

| パラメータ | 型 | 必須 | 備考 |
| --- | --- | --- | --- |
| `publicKey` | `string` | ✓ | `pk_(live\|test)_…` に一致する必要があります |
| `options.checkoutUrl` | `string` | — | チェックアウトのベース URL を上書き。デフォルト: `https://checkout.infraio.xyz`。チェックアウトページは対応する API に自動的に接続します。 |

## `sdk.checkout({ … })`

ホスト型チェックアウトを開きます。`void` を返します (状態はコールバックで取得)。

| フィールド | 型 | 必須 | 備考 |
| --- | --- | --- | --- |
| `sessionId` | `string` | ✓ | `POST /b2b/v1/checkout-sessions/quick` が返す `session_key` |
| `checkoutUrl` | `string` | — | 同じエンドポイントが返す完全な URL。省略された場合、SDK は `loadInfraIo()` の `checkoutUrl` (またはデフォルト) + `sessionId` から構築します |
| `mode` | `"popup" \| "redirect" \| "embed"` | — | デフォルト `"popup"` |
| `container` | `string \| HTMLElement` | embed のみ | iframe をマウントする CSS セレクタまたは DOM 要素 |
| `width` | `number` | — | popup のみ。デフォルト `560`。`[320, 1280]` の範囲にクランプ |
| `height` | `number` | — | popup のみ。デフォルト `780`。`[400, 1000]` の範囲にクランプ |
| `timeoutMs` | `number` | — | popup のみ。iframe ロードタイムアウト。デフォルト `30000`。`0` を渡すと無効化 |
| `locale` | `string` | — | BCP-47 タグ。`?locale=` としてチェックアウトページに転送 (`en`、`vi`、`ja`、`ko`、`es`、`pt-BR`、`ru`、`tr`、`zh-CN`、`zh-TW`) |
| `hideSummary` | `boolean` | — | 注文サマリー列を非表示。デフォルト `false` |
| `hideHeader` | `boolean` | — | InfraIO Pay ヘッダーと組み込みのウォレット接続ボタンを非表示。デフォルト `false`。完全なホワイトラベル化には `walletAddress` と組み合わせてください |
| `walletAddress` | `string` | — | バイヤーのウォレットを事前接続。`onSignRequest` が必要 |
| `walletChainId` | `number` | — | 事前接続したウォレットの EVM チェーン ID |
| `onReady` | `() => void` | — | iframe がインタラクティブになったときに発火。popup/embed のみ |
| `onSignRequest` | `(req: { method: string; params: unknown[] }) => Promise<string>` | `walletAddress` 設定時 | SDK はウォレット RPC をこのハンドラにプロキシします; 署名済み hex を返してください |
| `onSuccess` | `({ sessionId }) => void` | — | 決済成功時に発火。**信頼できる情報源ではありません — Webhook が信頼源です** |
| `onCancel` | `() => void` | — | バイヤーが支払いをせずに popup/embed を閉じたときに発火 |
| `onError` | `(err: InfraIoError) => void` | — | iframe ロード失敗時に発火 (popup + embed モード)。不正な引数は同期的に throw され、ここには **渡されません**。redirect モードにはランタイムエラーサーフェスがありません — 失敗はリダイレクト先のページで観測されます。 |

> **Warning:**
>
> `onSuccess` は **信頼できる** ものではありません。Webhook 側で
> 支払いが失敗と判定された場合でも発火する可能性があります (テストネットの
> reorg、バイヤー側のタイミングなど)。UX 用途のみで使ってください
> (「ありがとうございます!」表示、リダイレクト)。フルフィル前には
> 必ず Webhook で確認してください。

## `sdk.close()`

開いている popup または embed をプログラムから閉じます。redirect
モードでは何もしません。

```ts
sdk.checkout({ sessionId, mode: "popup", /* … */ });
// 後で、たとえばユーザーがページ遷移するときに
sdk.close();
```

## `sdk.openRefundRequest({ … })`

バックエンドが `POST /b2b/v1/merchants/{merchant_id}/refund-requests`
で発行したワンタイムトークン向けに、ホスト型の **返金リクエスト
フォーム** を開きます。バイヤーは弊社のページで返金先アドレス + 理由 +
(任意の) メタデータを入力します; あなたのページは開閉のライフサイクルを
扱うだけです。**`close()` 関数** を返します — 呼び出すと popup を
プログラムから閉じる、または embed iframe をデタッチします。redirect
モードでは返される関数は何もしません。

> **Note:**
>
> フォームは `https://checkout.infraio.xyz/refund-request/:token` に
> あります。このメソッドはその URL を popup / redirect / embed で
> ラップするだけなので、バイヤーはあなたのドメインを離れない
> (popup / embed)、または自動的に戻ります (redirect)。トークンを発行する
> ためにバックエンドが叩くエンドポイントは
> `POST /b2b/v1/merchants/{merchant_id}/refund-requests` — シークレット
> キーで HMAC 署名し、B2B サーフェスのほかの呼び出しと同じ認証を使います。
> [コンセプト → 返金](https://docs.infraio.xyz/ja/concepts/refunds#mint-via-b2b-api) を参照。

```ts
import { loadInfraIo } from "@lartech/infraio-checkout-js";

const sdk = await loadInfraIo("pk_live_yourkeyhere");

// トークンをサーバー側で発行し、ブラウザの SDK に渡します。
const { token } = await fetch("/api/mint-refund-token", { method: "POST" }).then(r => r.json());

const close = sdk.openRefundRequest({
  token,
  mode: "popup",
  onSuccess: ({ linkToken, refundId }) => {
    // バイヤーがフォームを送信しました。
    // linkToken → /r/:linkToken ステータスページ (バイヤーと共有)。
    // refundId  → B2B API で承認 / 拒否に使用。
    window.location.href = `/r/${linkToken}`;
  },
  onCancel: () => { /* バイヤーが送信せずに閉じた */ },
});

// 必要に応じて後で popup をプログラムから閉じる:
// close();
```

| フィールド | 型 | 必須 | 備考 |
| --- | --- | --- | --- |
| `token` | `string` | ✓ | `POST /b2b/v1/merchants/{merchant_id}/refund-requests` が返す `rfqt_…` トークン |
| `mode` | `"popup" \| "redirect" \| "embed"` | — | デフォルト `"popup"`。`sdk.checkout()` と同じサーフェスセマンティクス — [モードの注意点](#mode-notes) を参照 |
| `container` | `string \| HTMLElement` | embed のみ | iframe をマウントする CSS セレクタまたは DOM 要素 |
| `locale` | `string` | — | BCP-47 タグ。`?locale=` として転送 (`en`、`vi`、`ja`、`ko`、`es`、`pt-BR`、`ru`、`tr`、`zh-CN`、`zh-TW`) |
| `hideHeader` | `boolean` | — | iframe 内の InfraIO Pay ヘッダーを非表示。popup/embed では SDK が独自のモーダルクロームを描画するため、ページヘッダーは通常不要です。デフォルト `false` |
| `hideSummary` | `boolean` | — | 注文サマリー列を非表示にし、返金フォームのみを表示します。デフォルト `false` |
| `walletAddress` | `string` | — | 送信先ウォレットフィールドに事前入力 (`?wallet_address=`)。バイヤーのウォレットがすでに分かっているマーチャントが、手動の再入力を省略できます |
| `onSuccess` | `(data: { linkToken: string; refundId: string }) => void` | — | バイヤーがフォームを送信した後に発火。`linkToken` → `/r/:linkToken` ステータスページ (バイヤーと共有)。`refundId` → B2B API で承認 / 拒否に使用 |
| `onCancel` | `() => void` | — | バイヤーが送信せずに popup/embed を閉じたときに発火 |
| `onError` | `(err: InfraIoError) => void` | — | iframe ロード失敗または不正な引数で発火。トークンの期限切れ / キャンセルはホスト側のページが処理するため `onError` 経由ではありません |

**`onError` で表面化するトークン状態**

バイヤーが古いトークンを開いた場合、ページ自体が表示を処理し
(「期限切れ — 新しいリンクをリクエスト」のプロンプトなど)、SDK は
そのケースで `onError` を **発火しません** — バイヤーはフォームフロー内に
おり、あなたのコードは反応する必要がありません。`onError` は、あなたの
コードが対処できることだけに発火します (不正な引数、iframe を読み込む
ネットワーク障害)。

> **Warning:**
>
> `openRefundRequest` は返金の意図を記録するだけで、**資金を移動しません**。
> `onSuccess` の後、返金行は `PENDING` 状態 (またはマーチャント設定で
> カスタマー返金が自動承認される場合は `APPROVED`) です。あなたは依然として
> ご自身のウォレットからオンチェーン送金に署名・ブロードキャストし、
> その後 tx ハッシュを `POST /b2b/v1/refunds/:id/submit-tx` に
> ポストする必要があります。ライフサイクル全体については
> [コンセプト → 返金](https://docs.infraio.xyz/ja/concepts/refunds) を参照してください。

## エラークラス

```ts
import { InfraIoError } from "@lartech/infraio-checkout-js";

sdk.checkout({
  sessionId,
  onError: (err: InfraIoError) => {
    switch (err.code) {
      case "invalid_request_error":   /* 不正な sessionId / 引数 */ break;
      case "iframe_load_error":       /* iframe ロード失敗 */ break;
      case "iframe_timeout_error":    /* timeoutMs を超過 */ break;
      case "already_open_error":      /* 別のチェックアウトが既に開いている */ break;
      case "network_error":           /* チェックアウト origin との通信での一時的なネットワーク障害 */ break;
      case "api_error":               /* SDK が発行した呼び出しに対しバックエンドが non-2xx を返した */ break;
    }
  },
});
```

`sdk.openRefundRequest()` は `invalid_request_error` (トークン / 引数の
欠落または不正) のみを同期的に throw します。`iframe_load_error`
(返金リクエスト iframe のロード失敗) は **`onError` 経由で非同期に**
配信され、throw はされません。`iframe_timeout_error` や
`already_open_error` は **発火しません** — 返金リクエストの popup には
ロードタイムアウトはなく、複数の popup を同時に開けます。

## モードの注意点

### Popup
- 中央寄せのオーバーレイ、半透明の暗い背景
- `z-index: 2147483647` (int32 最大値) — 他のすべての上に乗ります
- 開いている間は body のスクロールがロックされ、閉じると復元されます
- 閉じるボタンが初期フォーカスを取得; Tab は popup 内にトラップ
- 閉じる手段: 閉じるボタン、Escape、外側クリック、`sdk.close()`。
  これらすべてが `onCancel` を呼び出します
- チェックアウトページは `postMessage` でリサイズを要求できます — SDK は
  `width`/`height` の制限内にクランプします

### Redirect
- `window.location.href` によるハードナビゲーション
- 自動的に `?return_url=<current-page>` を付加するので、バイヤーが
  来た場所に戻れます。セッションの `success_url` / `cancel_url` が
  既にこれをカバーしている場合、往復は `return_url` を無視します

### Embed
- `allow="payment; clipboard-write"` (HTML5 Feature Policy ディレクティブ —
  `sandbox` 属性ではありません) の iframe。iframe はチェックアウトの
  origin から配信されるため、ウォレット popup とクリップボード書き込みは
  バイヤー側からそれ以上のオプトインなしに動作します。
- コンテナ幅は 100%、高さは `INFRAIO_RESIZE` postMessage で自動サイズ調整、
  `[200, 2000]px` にクランプ
- iframe 境界を越える CSS の分離はありません — 親ページのスタイルが
  入り込むことはありません
- チェックアウトがインタラクティブになったときに自前のローディング状態を
  隠せるよう、必ず `onReady` を結線してください

## TypeScript

すべての型は同梱されています。よく使うエクスポート:

```ts
import type {
  CheckoutOptions,
  RefundRequestOptions,
  LoadOptions,
  InfraIoInstance,
  InfraIoErrorCode,
} from "@lartech/infraio-checkout-js";
import { loadInfraIo, InfraIoError, VERSION } from "@lartech/infraio-checkout-js";
```

`VERSION` は SDK 自身のバージョン文字列です — バグレポートに便利です。
