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

# Add Card

> Details on working with the Add Card frame used in the [Pay with card](/platform/guides/pay-with-card) flow.

## URL

```
https://blocks.moonpay.com/platform/v1/add-card
```

## Requirements

### Size

Render the frame in a modal or sheet. Width and height are flexible — size the
container to fit your UI.

<Note>
  The Add Card frame uses MoonPay's existing card input UI. A redesign is
  planned to streamline the experience and explore hosted fields for full design
  customization.
</Note>

## Initialization parameters

| Property      | Type     | Required | Description                                                                                                                                                                                    |
| ------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clientToken` | `string` | ✅        | The [client token](/platform/guides/api-and-sdk-credentials#client-token) returned from the [connect flow](/platform/guides/connect-a-customer).                                               |
| `channelId`   | `string` | ✅        | A unique identifier for the frame generated on your client. This value is attached to each `postMessage` payload to help identify messages.<br /><br />The format of this string is up to you. |
| `theme`       | `string` |          | Pass `dark` or `light` to force a specific appearance. If you omit this, the frame uses the user's system appearance.                                                                          |

## Events

All events are dispatched using the message pattern described in the [frames
protocol](/platform/frames/overview#frames-protocol#messages). Below are the
event payloads specific to the Add Card frame.

### Outbound events

<Badge size="md" className="px-2" color="purple">
  frame->parent
</Badge>

These events are sent from this frame to the parent window.

#### `handshake`

The frame requests that you open a message channel.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "handshake"
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type HandshakeEvent = Message<{
    kind: "handshake";
  }>;
  ```
</CodeGroup>

#### `ready`

The frame finished loading and the card input UI is fully rendered.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "ready"
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type ReadyEvent = Message<{
    kind: "ready";
  }>;
  ```
</CodeGroup>

#### `complete`

The card was added successfully. Use `card.id` to get a quote without
re-fetching payment methods.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "complete",
    "payload": {
      "card": {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "type": "card",
        "cardType": "credit",
        "brand": "visa",
        "last4": "4242",
        "expirationMonth": "12",
        "expirationYear": "2027",
        "availability": { "active": true }
      }
    }
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type CardResponse = {
    id: string;
    type: "card";
    cardType: "credit" | "debit" | "unknown";
    brand: "visa" | "mastercard" | "maestro" | "american_express" | "other";
    last4: string;
    expirationMonth: string;
    expirationYear: string;
    availability: { active: boolean };
  };

  type AddCardCompleteEvent = Message<{
    kind: "complete";
    payload: {
      card: CardResponse;
    };
  }>;
  ```
</CodeGroup>

#### `error`

An error occurred during card addition.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "error",
    "payload": {
      "code": "generic",
      "message": "Card creation failed."
    }
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type AddCardErrorEvent = Message<{
    kind: "error";
    payload: {
      code: "configurationError" | "generic";
      /** A developer-facing error message. Not intended to be rendered in UI. */
      message: string;
    };
  }>;
  ```
</CodeGroup>

| Code                 | Description                      |
| -------------------- | -------------------------------- |
| `configurationError` | Missing or invalid `clientToken` |
| `generic`            | Card creation failed             |

### Inbound events

<Badge size="md" className="px-2">
  parent->frame
</Badge>

These events are sent from the parent window to this frame.

#### `ack`

Acknowledge the [handshake](#handshake).

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "ack"
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type AckEvent = Message<{
    kind: "ack";
  }>;
  ```
</CodeGroup>
