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

# Blocks reference

> Every option, event, result shape, and error code in the Ionic Blocks browser API.

This page is the reference for Ionic Blocks. For the integration itself, follow
[Build a payment page](/guides/payment-fields) or
[Save a card for later](/guides/save-cards). The same API is available from the
`https://js.ionicfi.com/v1/ionic.js` script tag and from the
[`@ionicfi/js`](/sdks/browser) loader.

## Available Blocks

Ionic Blocks currently provides one Block, which collects the card number,
expiry, and CVC and shows the save-card consent checkbox when saving is
possible. It is available under two type names:

| Type      | Description                                                                                             |
| --------- | ------------------------------------------------------------------------------------------------------- |
| `payment` | The Payment Block. Use this type; it is the Block that carries whatever payment methods Ionic supports. |
| `card`    | The same Block, declared card-only. Identical fields, consent, and behavior today.                      |

The only difference at runtime is the wrapper attribute, `data-ionic-block="payment"`
or `data-ionic-block="card"`, which your CSS can target.

Wallet buttons are available on [hosted and embedded checkout](/guides/apple-pay).
Listing previously saved cards and 3DS challenges are not available in Blocks;
your application owns any saved-card selection UI, using the
[payment methods API](/api-reference/overview).

## Create a client

The script tag exposes `Ionic(publishableKey, options)`. With the npm loader:

```ts theme={null}
import { loadIonic } from "@ionicfi/js";
const ionic = await loadIonic("pk_v1_test_...", { account: "mer_BBBBBBBBBBBBBB" });
```

| Argument          | Type     | Description                                                                                                                                                            |
| ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `publishableKey`  | `string` | Your publishable key (`pk_v1_test_…` or `pk_v1_live_…`). A platform passes its platform publishable key.                                                               |
| `options.account` | `string` | Optional. The connected merchant's ID (`mer_…`) for [Connect](/guides/connect-overview). Fixed for the life of the client; create another client for another merchant. |

A malformed key or `account` throws an `invalid_request` [error](#error-codes)
synchronously.

## Create Blocks

```ts theme={null}
const blocks = ionic.blocks({ clientSecret });
```

| Argument       | Type     | Description                                                                                                         |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `clientSecret` | `string` | The `client_secret` of a PaymentIntent (`pi_…_secret_…`) or SetupIntent (`seti_…_secret_…`) created on your server. |

Returns an `IonicBlocks` instance bound to that intent, with `create` and
`destroy`. The calls below describe individual methods; placeholders refer to
values provided by your application. One instance serves one intent; a new intent
requires a new instance. A malformed secret throws `invalid_request`.

## Create a Block

```ts theme={null}
const payment = blocks.create("payment", options);
```

| Argument  | Type                    | Description                                                            |
| --------- | ----------------------- | ---------------------------------------------------------------------- |
| `type`    | `"payment"` \| `"card"` | The Block type. See [Available Blocks](#available-blocks).             |
| `options` | `PaymentBlockOptions`   | Optional. Layout, fields, styles, and consent placement, listed below. |

Each `IonicBlocks` instance creates one Block. A second `create` call, an
unknown type, or an unsupported `saveConsent` value throws `invalid_request`
synchronously. The remaining options are validated when the Block mounts: an
unknown option or an invalid value makes `mount` reject with
`collection_unavailable`. Options are read at creation; to change them, destroy
the Blocks instance and create a new one.

### Options

| Option              | Type                                   | Default       | Description                                                                                                                                                                 |
| ------------------- | -------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `layout`            | `"split"` \| `"stacked"` \| `"inline"` | `"split"`     | `split` places the card number above expiry and CVC. `stacked` places each field on its own row. `inline` places all three on one row.                                      |
| `gap`               | `number`                               | Ionic default | Space between fields in pixels. An integer from 0 to 32.                                                                                                                    |
| `fields.cardNumber` | `FieldConfig`                          |               | Options for the card number field.                                                                                                                                          |
| `fields.cardExpiry` | `FieldConfig`                          |               | Options for the expiry field.                                                                                                                                               |
| `fields.cardCvc`    | `FieldConfig`                          |               | Options for the CVC field.                                                                                                                                                  |
| `styles`            | `FieldStyles`                          | Ionic default | Per-state styles, listed under [Styles](#styles).                                                                                                                           |
| `saveConsent`       | `"auto"` \| `"external"`               | `"auto"`      | `auto` renders the consent checkbox inside the Block when saving is possible. `external` leaves consent to your page; pass the choice as `confirmParams.savePaymentMethod`. |

`FieldConfig`:

| Key           | Type      | Description                                                         |
| ------------- | --------- | ------------------------------------------------------------------- |
| `title`       | `string`  | Accessible name for the field.                                      |
| `placeholder` | `string`  | Placeholder text. Placeholders never prefill a value.               |
| `hideIcon`    | `boolean` | Hides the brand indicator on `cardNumber` or the icon on `cardCvc`. |

### Styles

`styles` takes one object per state. Each value is a CSS value string.
Selectors, URLs, fonts loaded from other origins, and stylesheets are not
accepted.

| State         | Applies to                              | Accepted properties       |
| ------------- | --------------------------------------- | ------------------------- |
| `base`        | Every field at rest                     | Text and field properties |
| `focus`       | The focused field                       | Text and field properties |
| `invalid`     | A field with a visible validation error | Text and field properties |
| `placeholder` | Placeholder text                        | Text properties only      |

Text properties: `color`, `fontFamily`, `fontSize`, `fontWeight`, `fontStyle`,
`lineHeight`, `letterSpacing`, `textAlign`.

Field properties: `backgroundColor`, `borderColor`, `borderRadius`,
`borderStyle`, `borderWidth`, `boxShadow`, `outlineColor`, `outlineOffset`,
`outlineStyle`, `outlineWidth`, `padding`.

An alternative configuration for the `create` call above:

```ts theme={null}
const payment = blocks.create("payment", {
  layout: "stacked",
  gap: 8,
  fields: { cardNumber: { placeholder: "Card number", hideIcon: true } },
  styles: {
    base: { fontFamily: "Inter, sans-serif", fontSize: "16px", borderRadius: "6px" },
    placeholder: { color: "#8a8f98" },
    focus: { borderColor: "#111111", boxShadow: "0 0 0 1px #111111" },
    invalid: { borderColor: "#b42318" },
  },
});
```

## Mount

```ts theme={null}
await payment.mount("#payment");
```

| Argument | Type                      | Description                                                               |
| -------- | ------------------------- | ------------------------------------------------------------------------- |
| `target` | `string` \| `HTMLElement` | A CSS selector or element. The element must be in the document and empty. |

Resolves after the fields are ready and emits `ready`. Mounting a Block twice,
or into an element that is missing, detached, or not empty, rejects with
`invalid_request`. If the fields cannot load, or an option passed to `create`
is invalid, `mount` rejects with `collection_unavailable` and emits the same
error.

When the intent is no longer collectable, for example after it has succeeded
on a previous page load, `mount` renders a short status line instead of the
fields and resolves. Your page can read the intent's state from a `change`
event or from [`retrievePaymentIntent`](#retrieve).

## Events

`payment.on(eventName, listener)` subscribes to a Block event.

`on` returns a function that removes the listener. Exceptions thrown by a
listener are ignored.

| Event    | Payload       | When                                                                                                                |
| -------- | ------------- | ------------------------------------------------------------------------------------------------------------------- |
| `ready`  | none          | Mount initialization completed. The Block may show intent status instead of fields.                                 |
| `change` | `BlockChange` | Field completion or card metadata changed, or the intent's state was refreshed.                                     |
| `error`  | `BlockError`  | The fields could not load, the collection session was replaced, or a mount failed. See [Error codes](#error-codes). |

`BlockChange`:

| Field           | Type                     | Description                                                                                                                                        |
| --------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `complete`      | `boolean`                | Whether every field passed its latest validation. Advisory; confirmation validates again.                                                          |
| `paymentIntent` | `BlockIntent`            | The PaymentIntent's current state, once known. Present for PaymentIntent Blocks.                                                                   |
| `setupIntent`   | `BlockIntent`            | The SetupIntent's current state, once known. Present for SetupIntent Blocks.                                                                       |
| `card`          | `CardMetadata` \| `null` | Optional. Present on field changes: provisional card metadata, or `null` when unavailable. Omitted when the event reports an intent-state refresh. |

`BlockIntent`:

| Field            | Type                                   | Description                                                                                                                          |
| ---------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `id`             | `string`                               | The intent ID (`pi_…` or `seti_…`).                                                                                                  |
| `object`         | `"payment_intent"` \| `"setup_intent"` | The intent type.                                                                                                                     |
| `status`         | `string`                               | `requires_payment_method`, `requires_confirmation`, `processing`, `requires_action`, `requires_capture`, `succeeded`, or `canceled`. |
| `amount`         | `number`                               | Amount in minor units. PaymentIntents only.                                                                                          |
| `currency`       | `string`                               | Three-letter currency code.                                                                                                          |
| `payment_method` | `string`                               | The saved payment method ID (`pm_…`), when one exists.                                                                               |

`CardMetadata` carries the card's `bin` (the first 6 to 8 digits, or `null`),
`brand` (or `null`), `funding` (`credit`, `debit`, `prepaid`, or `unknown`), and
`source` (`lookup` while the customer types, `tokenize` after submission). It is provisional and
never a basis for fees, acceptance, or fulfillment.

## Destroy

```ts theme={null}
blocks.destroy();
```

Removes the Block's UI and listeners. Both `blocks.destroy()` and
`payment.destroy()` destroy the whole instance. A confirmation already sent
continues to completion on the intent; destroying never creates a replacement
intent. Call it when the payment view unmounts, and before creating a Blocks
instance for another intent or merchant.

## Confirm

| Intent type   | Method                                            |
| ------------- | ------------------------------------------------- |
| PaymentIntent | `ionic.confirmPayment({ blocks, confirmParams })` |
| SetupIntent   | `ionic.confirmSetup({ blocks, confirmParams })`   |

These are alternative operations for their respective intent types. The method
is called in response to the customer's submission after mounting.

| Argument                          | Type                  | Description                                                                                                                                                                      |
| --------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `blocks`                          | `IonicBlocks`         | The instance whose Block collected the card. `confirmPayment` requires a PaymentIntent instance and `confirmSetup` a SetupIntent instance; a mismatch returns `invalid_request`. |
| `confirmParams.billingDetails`    | `BlockBillingDetails` | Optional. `name`, `email`, `phone`, and `address` with `line1`, `line2`, `city`, `state`, `postal_code`, and `country`.                                                          |
| `confirmParams.savePaymentMethod` | `boolean`             | Only with `saveConsent: "external"`. `true` requests saving; `false` or omission does not. Passing it in `auto` mode returns `invalid_request`.                                  |

Results:

| Field                           | Type          | Description                                                                                                                                                      |
| ------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `paymentIntent` / `setupIntent` | `BlockIntent` | The intent's state after the call, when known.                                                                                                                   |
| `savedPaymentMethod`            | `string`      | `confirmPayment` only. The payment method ID when the card was saved in this response.                                                                           |
| `error`                         | `BlockError`  | Present when the call did not reach a successful state. Can accompany an intent, for example `payment_failed` with the intent back in `requires_payment_method`. |

Behavior:

* Concurrent calls share one in-flight confirmation; the second call receives
  the same promise.
* Confirmation validates consent and card details before submitting a new
  attempt. Missing required consent returns `consent_required`; incomplete
  fields return `incomplete_payment_details`. An uncertain earlier attempt is
  checked before collecting new details.
* Each attempt sends one idempotency key. After `payment_status_unknown`,
  calling again with the same `blocks` instance checks the existing intent and
  can replay the original request if the intent remains collectable. The
  attempt's key, token, and saving choice are kept in memory on that instance;
  they do not survive a reload.
* A card decline returns `payment_failed` with the intent in
  `requires_payment_method`; the customer corrects the card and your page calls
  confirm again on the same instance.
* `requires_action` returns `authentication_required`. Blocks does not run 3DS
  challenges; the intent still requires action and has not succeeded.
* Requests time out after 30 seconds.

## Retrieve

| Intent type   | Method                                      |
| ------------- | ------------------------------------------- |
| PaymentIntent | `ionic.retrievePaymentIntent(clientSecret)` |
| SetupIntent   | `ionic.retrieveSetupIntent(clientSecret)`   |

Reads the intent's current state with the publishable key and client secret,
without a Blocks instance. Returns the matching intent and/or `error`.
`savedPaymentMethod` is not returned by retrieval. A malformed secret, request
failure, or unreadable response returns `payment_status_unknown`; a well-formed
secret of the other intent type returns `invalid_request`. See
[Payment events](/guides/payment-fields#payment-events) for server-side state.

## Error codes

Errors are `{ type, code, message }`. `message` is written for the customer
and safe to display. `type` groups the codes: `validation_error` (the
customer or your page can correct it), `payment_error` (the payment itself),
and `api_error` (the form or the connection).

| Code                         | Type               | When                                                                                                                                                                                                                                                                                                  | What to do                                                                                                     |
| ---------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `invalid_request`            | `validation_error` | A malformed key, secret, or `account`; `create` called twice, with an unknown type, or with an unsupported `saveConsent`; an invalid mount target; `savePaymentMethod` outside external consent mode; consent given on an intent that does not allow saving; a rejected request other than a decline. | Fix the integration.                                                                                           |
| `incomplete_payment_details` | `validation_error` | A field is empty or invalid at confirmation.                                                                                                                                                                                                                                                          | Keep the same Block; the fields show which entry needs attention.                                              |
| `consent_required`           | `validation_error` | A save-only intent was confirmed without consent.                                                                                                                                                                                                                                                     | Ask the customer to check the consent box, then confirm again.                                                 |
| `card_details_required`      | `validation_error` | The collection session was replaced, for example after it expired, and the entered card was cleared.                                                                                                                                                                                                  | Ask the customer to enter their card again on the same Block.                                                  |
| `payment_failed`             | `payment_error`    | The card was declined or the confirmation left the intent collectable.                                                                                                                                                                                                                                | Show `message`; let the customer try another card on the same intent.                                          |
| `authentication_required`    | `payment_error`    | The intent requires an authentication step that Blocks does not run.                                                                                                                                                                                                                                  | The intent still requires authentication and has not succeeded.                                                |
| `payment_canceled`           | `payment_error`    | The intent is `canceled`.                                                                                                                                                                                                                                                                             | Show `message`; create a new intent if the customer wants to pay again.                                        |
| `not_ready`                  | `api_error`        | Confirm was called before `mount` resolved, or while the fields were being refreshed.                                                                                                                                                                                                                 | Wait for mount to resolve or the field refresh to finish. A refresh does not emit another `ready` event.       |
| `destroyed`                  | `api_error`        | A call after `destroy`.                                                                                                                                                                                                                                                                               | Create a new Blocks instance.                                                                                  |
| `collection_unavailable`     | `api_error`        | The secure fields could not load or stopped working, or an option passed to `create` is invalid.                                                                                                                                                                                                      | Let the customer try again; mount a new Block if the error came from `mount`. Check the options if it repeats. |
| `payment_status_unknown`     | `api_error`        | No verifiable result arrived, for example a timeout during confirmation.                                                                                                                                                                                                                              | Call confirm again on the same instance or retrieve the intent. Do not create a new intent.                    |
