# `embeddedCheckout()`

Mounts the Revolut Checkout widget to a DOM element, providing access to all enabled payment methods through a single, unified interface. The widget aggregates Revolut Pay, Card, Apple Pay, Google Pay, Pay by Bank, and other payment methods configured in your Business Dashboard.

**Key features:**

- Unified widget for all payment methods
- Dashboard-configured (no code changes to add/reorder methods)
- Automatic payment method optimisation
- Built-in customisation options

:::info
For a complete implementation guide with examples, see: [Accept payments via Revolut Checkout - Web](/docs/guides/merchant/accept-payments/online-payments/revolut-checkout/web)
:::

## Prerequisites

This payment method requires [direct initialisation](/docs/sdks/merchant-web-sdk/initialisation/direct).

## Type signature

```typescript
RevolutCheckout.embeddedCheckout: (
  options: EmbeddedCheckoutOptions
) => Promise<EmbeddedCheckoutInstance>

interface EmbeddedCheckoutOptions {
  publicToken: string
  mode: 'prod' | 'sandbox'
  locale?: Locale | 'auto'
  target: HTMLElement
  createOrder: () => Promise<{ publicId: string }>
  onSuccess?: (payload: { orderId: string }) => void
  onError?: (payload: { error: RevolutCheckoutError; orderId: string }) => void
  onCancel?: (payload: { orderId: string | undefined }) => void
  email?: string
  billingAddress?: Address
  shippingOptions?: ShippingOption[]
  onShippingAddressChange?: (address: Address) => Promise<ShippingAddressChangeResult>
  onShippingOptionChange?: (option: ShippingOption) => Promise<ShippingChangeResult>
}

interface EmbeddedCheckoutInstance {
  destroy: () => void
}
```

## Parameters

| Parameter | Description                                           | Type                                                            | Required |
| --------- | ----------------------------------------------------- | --------------------------------------------------------------- | -------- |
| `options` | Configuration object for the embedded checkout widget | [`EmbeddedCheckoutOptions`](#embeddedcheckoutoptions-interface) | Yes      |

### `EmbeddedCheckoutOptions` interface

| Parameter                 | Description                                                                                                                        | Type                                                                | Required |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -------- |
| `publicToken`             | Your Merchant API Public key                                                                                                       | `string`                                                            | Yes      |
| `mode`                    | API environment                                                                                                                    | `'prod' \| 'sandbox'`                                               | Yes      |
| `locale`                  | Widget language                                                                                                                    | `Locale \| 'auto'` (default: `'auto'`)                              | No       |
| `target`                  | DOM element where the widget should be mounted                                                                                     | `HTMLElement`                                                       | Yes      |
| `createOrder`             | Async function that calls your backend to [create an order](/docs/api/merchant#create-order) and returns the order token           | `() => Promise<{publicId: string}>`                                 | Yes      |
| `onSuccess`               | Callback triggered when payment completes successfully                                                                             | `(payload: {orderId: string}) => void`                              | No       |
| `onError`                 | Callback triggered when payment fails. Receives [`RevolutCheckoutError`](/docs/sdks/merchant-web-sdk/types/revolut-checkout-error) | `(payload: {error: RevolutCheckoutError, orderId: string}) => void` | No       |
| `onCancel`                | Callback triggered when user cancels payment. `orderId` may be `undefined` if order creation failed                                | `(payload: {orderId?: string}) => void`                             | No       |
| `email`                   | Provide customer's email address. If provided, the email field is hidden from the checkout form                                      | `string`                                                            | No       |
| `billingAddress`          | Provide or skip the billing address form. If the provided address is valid, the billing form is hidden completely. If the address is invalid or incomplete, the form is shown with the pre-filled values. For the form to be hidden, `countryCode`, `postcode`, `streetLine1`, and `city` must be present and valid | [`Address`](/docs/sdks/merchant-web-sdk/types/address)              | No       |
| `shippingOptions`         | Available shipping options for the customer                                                                                        | [`ShippingOption[]`](#shippingoption)                               | No       |
| `onShippingAddressChange` | Callback triggered when customer changes shipping address                                                                          | `(address: Address) => Promise<ShippingAddressChangeResult>`        | No       |
| `onShippingOptionChange`  | Callback triggered when customer selects a different shipping option                                                               | `(option: ShippingOption) => Promise<ShippingChangeResult>`         | No       |

#### `ShippingOption`

```typescript
interface ShippingOption {
  id: string
  label: string
  amount: number
  description?: string
}
```

Defines a shipping option available to the customer.

| Property      | Description                                       | Type     | Required   |
| ------------- | ------------------------------------------------- | -------- | ---------- |
| `id`          | Unique identifier for the shipping option         | `string` | Yes        |
| `label`       | Display name (e.g., "Standard Shipping")          | `string` | Yes        |
| `amount`      | Shipping cost in lowest currency denomination     | `number` | Yes        |
| `description` | Additional details (e.g., "Delivery in 5-7 days") | `string` | No         |

#### `ShippingChangeResult`

```typescript
type ShippingChangeResult = {
  status: 'success' | 'fail'
  total: {
    amount: number
    label?: string
  }
}
```

Response from `onShippingOptionChange` callback with updated total.

#### `ShippingAddressChangeResult`

```typescript
type ShippingAddressChangeResult = {
  status: 'success' | 'fail'
  shippingOptions?: ShippingOption[]
  total: {
    amount: number
    label?: string
  }
}
```

Response from `onShippingAddressChange` callback with updated shipping options and total.

## Return value

```typescript
Promise<EmbeddedCheckoutInstance>

interface EmbeddedCheckoutInstance {
  destroy: () => void
}
```

The promise resolves with an `EmbeddedCheckoutInstance` object containing:

| Property  | Description                                                        | Type         |
| --------- | ------------------------------------------------------------------ | ------------ |
| `destroy` | Function to remove the widget from the page and clean up resources | `() => void` |

## Callback events

The embedded checkout widget provides the following callback functions for handling payment lifecycle events in your frontend.

:::warning
Widget callbacks are not guaranteed to fire due to network issues, browser closures, or ad-blockers. Always use [webhooks](/docs/guides/merchant/monitor-and-observe/webhooks/using-webhooks) for critical backend operations like order fulfilment.
:::

:::info
In all callbacks, `orderId` refers to the order's public token (`order.token` from the API response), not the internal `order.id`. This is the public identifier used in your frontend code.
:::

### `onSuccess`

```typescript
(payload: { orderId: string }) => void
```

Triggered when the payment completes successfully.

**Use cases:**

- Display success message to the customer
- Redirect to order confirmation page
- Update UI to reflect successful payment
- Show success animations

**Example:**

```typescript
onSuccess: ({ orderId }) => {
  console.log('Payment successful!', orderId)
  window.location.href = `/confirmation?orderId=${orderId}`
}
```

### `onError`

```typescript
(payload: { error: RevolutCheckoutError; orderId: string }) => void
```

Triggered when the payment fails. The `error` parameter is a [`RevolutCheckoutError`](/docs/sdks/merchant-web-sdk/types/revolut-checkout-error) object containing error details.

**Use cases:**

- Display error message to the customer
- Log error for debugging
- Re-enable checkout form
- Show retry option

**Example:**

```typescript
onError: ({ error, orderId }) => {
  console.error('Payment failed:', error.message, orderId)
  alert(`Payment failed: ${error.message}`)
}
```

### `onCancel`

```typescript
(payload: { orderId: string | undefined }) => void
```

Triggered when the user cancels the payment. The `orderId` may be `undefined` if the order was not created yet.

**Use cases:**

- Display cancellation message
- Re-enable checkout form
- Track abandonment analytics

**Example:**

```typescript
onCancel: ({ orderId }) => {
  console.log('Payment cancelled', orderId)
  alert('Payment was cancelled. You can try again.')
}
```

### `onShippingAddressChange`

```typescript
(address: Address) => Promise<ShippingAddressChangeResult>
```

Triggered when the customer changes their shipping address. Validate the address and return updated shipping options and order total.

**Use cases:**

- Validate delivery availability for the provided address
- Update shipping options based on the customer's region
- Recalculate order total with applicable shipping cost

**Example:**

```typescript
const shippingOptions: ShippingOption[] = [
  { id: 'standard', label: 'Standard Shipping', amount: 500, description: 'Delivery in 5-7 days' },
  { id: 'express', label: 'Express Shipping', amount: 1000, description: 'Delivery in 1-2 days' }
]

const { destroy } = await RevolutCheckout.embeddedCheckout({
  // ... other configuration
  shippingOptions,
  onShippingAddressChange: async (address) => {
    const isValidRegion = await validateDeliveryRegion(address)

    if (!isValidRegion) {
      return {
        status: 'fail',
        total: { amount: 5000 }
      }
    }

    return {
      status: 'success',
      shippingOptions,
      total: { amount: 5000 + shippingOptions[0].amount }
    }
  }
})
```

### `onShippingOptionChange`

```typescript
(option: ShippingOption) => Promise<ShippingChangeResult>
```

Triggered when the customer selects a different shipping option. Return the updated order total.

**Use cases:**

- Recalculate order total with the selected shipping cost
- Update pricing display

**Example:**

```typescript
onShippingOptionChange: async (selectedOption) => {
  return {
    status: 'success',
    total: {
      amount: 5000 + selectedOption.amount,
      label: 'Total'
    }
  }
}
```

## Error handling

**Throws:** [`RevolutCheckoutError`](/docs/sdks/merchant-web-sdk/types/revolut-checkout-error)

The embedded checkout can throw errors in the following scenarios:

- Invalid `publicToken`
- Failed order creation in the `createOrder` callback
- Network connectivity issues
- Invalid configuration options
- Widget loading failures

**Example error handling:**

```typescript
try {
  const { destroy } = await RevolutCheckout.embeddedCheckout({
    // ... configuration
  })
} catch (error) {
  if (error.name === 'RevolutCheckout') {
    console.error('Checkout initialisation failed:', error.message)
    // Handle initialisation error
  }
}
```

For error handling within callbacks, see the [onError callback](#onerror) section.

## Usage example

- ![With async await]

  ```typescript
  import RevolutCheckout from '@revolut/checkout'

  // Initialise and mount the embedded checkout
  const { destroy } = await RevolutCheckout.embeddedCheckout({
    publicToken: process.env.REVOLUT_PUBLIC_KEY,
    mode: 'prod',
    locale: 'auto',
    target: document.getElementById('checkout-container'),

    createOrder: async () => {
      // Call your backend to create an order
      const response = await fetch('/api/create-order', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          amount: 1000,
          currency: 'GBP',
        }),
      })
      const order = await response.json()
      return { publicId: order.token }
    },

    onSuccess: ({ orderId }) => {
      console.log('Payment successful!', orderId)
      window.location.href = `/confirmation?orderId=${orderId}`
    },

    onError: ({ error, orderId }) => {
      console.error('Payment failed:', error.message, orderId)
      alert(`Payment failed: ${error.message}`)
    },

    onCancel: ({ orderId }) => {
      console.log('Payment cancelled', orderId)
      alert('Payment was cancelled.')
    },
  })

  // Later, if you need to remove the widget:
  // destroy()
  ```

- ![Without async await]

  ```typescript
  import RevolutCheckout from '@revolut/checkout'

  // Initialise and mount the embedded checkout
  RevolutCheckout.embeddedCheckout({
    publicToken: process.env.REVOLUT_PUBLIC_KEY,
    mode: 'prod',
    locale: 'auto',
    target: document.getElementById('checkout-container'),

    createOrder: () => {
      // Call your backend to create an order
      return fetch('/api/create-order', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          amount: 1000,
          currency: 'GBP',
        }),
      })
        .then((response) => response.json())
        .then((order) => ({ publicId: order.token }))
    },

    onSuccess: ({ orderId }) => {
      console.log('Payment successful!', orderId)
      window.location.href = `/confirmation?orderId=${orderId}`
    },

    onError: ({ error, orderId }) => {
      console.error('Payment failed:', error.message, orderId)
      alert(`Payment failed: ${error.message}`)
    },

    onCancel: ({ orderId }) => {
      console.log('Payment cancelled', orderId)
      alert('Payment was cancelled.')
    },
  }).then(({ destroy }) => {
    // You can use destroy() later if needed
  })
  ```

### Provide customer information

You can improve the checkout experience by providing customer information upfront:

```typescript
const { destroy } = await RevolutCheckout.embeddedCheckout({
  // ... other configuration
  email: 'customer@example.com',
  billingAddress: {
    countryCode: 'GB',
    region: 'Greater London',
    city: 'London',
    postcode: 'EC1A 1BB',
    streetLine1: '1 Example Street',
    streetLine2: 'Flat 2B',
  },
})
```

When you provide `billingAddress`, the widget applies the following behaviour:

- **Valid address** - the billing address form is **hidden completely**. The customer does not need to enter or review any address fields.
- **Invalid or incomplete address** - the billing address form is **shown with the pre-filled values**. The customer can review and correct any fields that failed validation.

For the form to be hidden, the widget pre-validates the address. The fields `countryCode`, `postcode`, `streetLine1`, and `city` must be present and valid. `streetLine2` and `region` are not validated by the embedded checkout.

If `email` is provided — either in the widget configuration or on the order via the API — the email field is hidden from the checkout form.

## See also

- [Accept payments via Revolut Checkout - Web](/docs/guides/merchant/accept-payments/online-payments/revolut-checkout/web)
- [Customise Revolut Checkout in Revolut Business](/docs/guides/merchant/accept-payments/online-payments/revolut-checkout/web#customise-revolut-checkout)
- [Address type reference](/docs/sdks/merchant-web-sdk/types/address)
- [RevolutCheckoutError type reference](/docs/sdks/merchant-web-sdk/types/revolut-checkout-error)
- [Use webhooks to keep track of the payment lifecycle](/docs/guides/merchant/monitor-and-observe/webhooks/using-webhooks)