> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clinkbill.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Reference

> Client options, account APIs, attach options, and checkout methods in the Agent Vault SDK.

Use this page with the [Agent Vault SDK guide](https://docs.clinkbill.com/guides/agent/vault_sdk), which explains the payment flow and how to handle each step.

> [!NOTE]
>
> Call every API from your server. Inputs and outputs on `ClinkVault` are camelCase; values returned during checkout, such as from `pay()` and `reconcile()`, are snake\_case.

## Create a client

```typescript theme={null}
const vault = new ClinkVault(options);
```

Creates the client. It obtains and refreshes the OAuth token automatically.

**clientId** `string` *required*

Client ID issued by Clink.

**clientSecret** `string` *required*

Client secret issued by Clink. Keep it on the server.

**environment** `string` (default: sandbox)

`sandbox` or `production`.

**timeoutMs** `number` (default: 15000)

Request timeout in milliseconds.

**authorizationTimeoutMs** `number` (default: 60000)

Authorization timeout in milliseconds.

**submitTimeoutMs** `number` (default: 30000)

How long the SDK waits after `submit` for the PSP request or the PayPal approval link.

## ClinkVault methods

**vault.attach(page, options)** `Promise\<CheckoutController\>`

Attaches to a Playwright `Page`, local or in a cloud browser, and starts intercepting payment requests. See [attach options](#attach-options).

**vault.attachToCdp(cdp, pageSessionId, options)** `Promise\<CheckoutController\>`

Attaches directly to a CDP connection without Playwright. `cdp` is a CDP connection in flatten mode, and `pageSessionId` is the checkout page's session. Takes the same [attach options](#attach-options), except `routeScope` and `detectPaymentMethods`.

**vault.sessions.create(\{ email, externalUserId })** `object`

Creates a card setup session outside checkout. `email` is required.

Returns `{ sessionId, type: 'bind', url, expiresAt, customerId }`.

**vault.sessions.retrieve(sessionId)** `object`

Reads the result of a card setup session.

Returns `{ type, status, expiresAt?, cardToken?, card?, window? }`. `status` is `pending`, `opened`, `completed`, `failed`, `locked`, or `expired`.

**vault.cards.list(\{ customerId })** `array`

Lists the cards a user has authorized for the current developer.

Each item is `{ cardToken, brand, last4, expMonth, expYear, status, window? }`. A `window: { expiresAt }` means the payment window is still open.

**vault.getCoverage()** `object`

Lists the PSPs currently enabled.

Returns `{ psps: [{ psp, mode, status, limits }] }`.

## Attach options

Options for `vault.attach()` and `vault.attachToCdp()`.

**customerId** `string`

Identifies a user who already has a card. Omit it on first use.

**cardToken** `string`

The user's saved card token. Omit it on first use.

**email** `string`

Used to create a card setup session when no usable card exists. Without it, `pay()` returns `failed` with `card_not_bound` or `window_expired`.

**externalUserId** `string`

Your own user ID.

**onUserAction(action)** `function`

Called when the user needs to act. `action` is:

```typescript theme={null}
{ type, url?, expires_at?, customer_id?, card_token?, authorization_id?,
  method?, qr_image_base64?, qr_data? }
```

`type` is `bind_card`, `pay_qr`, `3ds`, or `redirect`. `pay_qr` carries a PNG QR code image; PayPal uses `redirect` with the approval link. Deliver links and QR codes to the user from your code; do not have an LLM relay them.

**onCardBound(card)** `function`

Called once after card setup completes and the card is confirmed. `card` is `{ customerId, cardToken }`; persist it.

**onStateChange(state)** `function`

Called when the checkout state changes. `state` matches `getState()`.

**resolveMerchantResult(state)** `function`

Called by `reconcile()`. Return the merchant's order result in one of these forms:

```typescript theme={null}
{
  status: 'completed' | 'failed' | 'pending' | 'unknown';
  order_id?;
  payment_confirmed_unpaid?;
}
// or
{ status: 'requires_user_action'; reason: '3ds' | 'redirect' }
```

A QR code payment falls back to a card only when the result is `failed` with `payment_confirmed_unpaid: true`.

**routeScope** `string` (default: context)

`context` covers cross-origin iframes; `page` covers only the page. Applies to `attach` only.

**rules** `object`

Custom matching rules. When omitted, rules are synced from Clink Vault.

**detectPaymentMethods(page)** `function`

Custom card detection for `getPaymentMethods()`. Return `[{ method, psp?, source }]`; it replaces the SDK's own card detection, while QR wallets and PayPal are still detected by the SDK. Applies to `attach` only.

**resolveQrCode, resolvePayNowQr, resolvePayPalUrl** `function`

Custom functions that extract a QR code or PayPal link from the page. A QR code's `image_base64` must be a base64 PNG, JPEG, GIF, or WebP; SVG and remote URLs are rejected.

## CheckoutController methods

`vault.attach()` and `vault.attachToCdp()` return a `CheckoutController` for a single checkout.

**getPaymentMethods()** `object`

Detects the payment methods on the page and returns each one's status for this user's cards. Cards are recognized before they are filled, by scanning the PSP scripts and card iframes the page loads. QR wallets and PayPal are detected locally and are not sent to Clink Vault.

Returns `{ default, methods: [{ method, psp?, status, card?: { brand, last4 }, reason? }] }`. `status` is `ready`, `needs_bind`, `needs_user`, or `unsupported`.

**pay(options?)** `PayStep`

Advances the payment. Each call returns the next thing to do; see [pay() return value](#pay-return-value).

* `method`: `card` (default), `paynow`, `wechat_pay`, `upi_qr`, `bcmc_mobile`, `pix`, or `paypal`
* `fallback`: `card`

**bind()** `PayStep`

Starts card setup on demand, for example when the user wants to add or change a card. Requires `email` in the attach options. New cards and CVV re-entry use the same link, and an unfinished session is reused. Returns `wait_user` / `bind_card`; the link is delivered through `onUserAction`. Without `email`, returns `failed` / `card_not_bound`. Once a payment attempt is under way, returns `failed` / `invalid_checkout_state`.

**reconcile()** `CheckoutState`

Reads the merchant's order result through `resolveMerchantResult` and reports it to Clink Vault. Returns `{ status, authorization_id?, order_id?, reason? }`. For how each result maps to `status`, see [Reconcile and detach](https://docs.clinkbill.com/guides/agent/vault_sdk#get-started).

**retry()** `void`

Starts a new attempt after you confirm no charge occurred. Available only in `declined`, `failed`, `cancelled`, or `unsupported`; other states throw `retry_not_allowed`.

**requestUserAction(reason)** `void`

Moves to the waiting-for-user state manually when the page shows 3DS or a redirect only after receiving the card token. `reason` is `3ds` or `redirect`.

**cancel()** `void`

Cancels a payment that has no result yet. If the card request may already have reached the PSP and cancellation cannot be confirmed, the state becomes `outcome_unknown`.

**getState()** `CheckoutState`

Reads the current checkout state.

**detach()** `void`

Removes interception. Always call it when checkout ends.

## pay() return value

```typescript theme={null}
interface PayStep {
  status:
    | 'requires_action' | 'succeeded' | 'declined'
    | 'outcome_unknown' | 'unsupported' | 'failed';
  next_action?:
    // fill_card carries the placeholder card, not the real card
    | { type: 'fill_card'; card: { number; exp_month; exp_year; cvc } }
    | { type: 'submit' }
    | {
        type: 'wait_user';
        reason: 'bind_card' | 'pay_qr' | '3ds' | 'redirect';
        expires_at;
        url?;
        qr_image_base64?;
        qr_data?;
      }
    | { type: 'select_method'; method };
  authorization_id?: string;
  // Payment method actually used
  method_used?: string;
  // Whether the payment fell back to a card
  fell_back?: boolean;
  // QR code PNG (data URL), shown directly by the host
  qr_image_base64?: string;
  // Decoded QR content, only with BarcodeDetector support
  qr_data?: string;
  // Such as card_not_bound, 3ds, or redirect
  reason?: string;
}
```

For how to handle each `next_action`, see [Get started](https://docs.clinkbill.com/guides/agent/vault_sdk#get-started).

`CheckoutState.status` is one of `idle`, `awaiting_user`, `ready_to_submit`, `processing`, `requires_user_action`, `awaiting_merchant`, `completed`, `declined`, `outcome_unknown`, `cancelled`, `unsupported`, or `failed`.

## Errors

On error, the SDK throws a `VaultError`. Its `code` is the error code, such as `card_not_bound`, `window_expired`, `rule_not_matched`, `retry_not_allowed`, or `api_error`. Its `message` has card numbers and CVVs removed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.