# `CustomerDetails`

Customer information interface used to pre-fill or collect customer data during checkout. Improves conversion rates by reducing form friction and enables personalised payment experiences.

## Type signature

```typescript
interface CustomerDetails {
  name?: string
  email?: string
  phone?: string
  dateOfBirth?: {
    day: number // 1-31
    month: number // 1-12
    year: number // Four-digit year
  }
  billingAddress?: Address
  shippingAddress?: Address
}
```

## Properties

| Property          | Description                                                                                                          | Type                                                   | Required |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -------- |
| `name`            | Cardholder name in format `'FirstName LastName'` for card payment flows                                              | `string`                                               | No       |
| `email`           | Customer's email address _Note: Required for payment if not set on order via API_                                    | `string`                                               | No       |
| `phone`           | Customer's phone number in international format (e.g., `+447950630319`)                                              | `string`                                               | No       |
| `dateOfBirth`     | Customer's date of birth. Currently used only for Revolut Pay. See [DateOfBirth properties](#dateofbirth-properties) | `object`                                               | No       |
| `billingAddress`  | Customer's billing address _Note: Required for card payments in widget flows that use this object_                   | [`Address`](/docs/sdks/merchant-web-sdk/types/address) | Yes\*    |
| `shippingAddress` | Customer's shipping address. Displayed only in order details on Merchant Dashboard                                   | [`Address`](/docs/sdks/merchant-web-sdk/types/address) | No       |

\* In card flows, provide `billingAddress` in the widget configuration that uses this object.

### DateOfBirth properties

When `dateOfBirth` is provided, all three properties are required:

| Property | Description                  | Type     | Required |
| -------- | ---------------------------- | -------- | -------- |
| `day`    | Day of month (1-31)          | `number` | Yes      |
| `month`  | Month (1-12)                 | `number` | Yes      |
| `year`   | Four-digit year (e.g., 1990) | `number` | Yes      |

## Usage

Examples of using the `CustomerDetails` type to pre-fill customer information in different payment flows.

### Pre-filling embedded checkout

```typescript
import RevolutCheckout from '@revolut/checkout'
import type { CustomerDetails } from '@revolut/checkout'

const customerDetails: CustomerDetails = {
  name: 'John Smith',
  email: 'john.smith@example.com',
  phone: '+447950630319',
  billingAddress: {
    countryCode: 'GB',
    postcode: 'EC1A 1BB',
    region: 'Greater London',
    city: 'London',
    streetLine1: '1 Example Street',
    streetLine2: 'Flat 2B',
  },
}

const { destroy } = await RevolutCheckout.embeddedCheckout({
  publicToken: 'pk_...',
  environment: 'prod',
  target: document.getElementById('checkout'),
  createOrder: async () => {
    /* ... */
  },
  email: customerDetails.email,
  billingAddress: customerDetails.billingAddress,
})
```

### Card field with customer details

```typescript
import RevolutCheckout from '@revolut/checkout'
import type { CustomerDetails } from '@revolut/checkout'

const instance = await RevolutCheckout(orderToken, 'prod')

const cardField = instance.createCardField({
  target: document.getElementById('card-field'),
  onSuccess: () => console.log('Payment successful'),
})

const customerDetails: CustomerDetails = {
  name: 'Maria García',
  email: 'maria@example.com',
  phone: '+34123456789',
  billingAddress: {
    countryCode: 'ES',
    postcode: '28001',
    city: 'Madrid',
    streetLine1: 'Calle de Alcalá 1',
  },
}

// Submit with customer details
cardField.submit({
  ...customerDetails,
  savePaymentMethodFor: 'customer',
})
```

### With date of birth (Revolut Pay)

```typescript
import RevolutCheckout from '@revolut/checkout'
import type { CustomerDetails } from '@revolut/checkout'

const customerWithDOB: CustomerDetails = {
  name: 'Pierre Dubois',
  email: 'pierre@example.com',
  phone: '+33123456789',
  dateOfBirth: {
    day: 15,
    month: 6,
    year: 1990,
  },
  billingAddress: {
    countryCode: 'FR',
    postcode: '75001',
    city: 'Paris',
  },
}

const paymentsModule = await RevolutCheckout.payments({
  publicToken: 'pk_...',
  mode: 'prod',
})

paymentsModule.revolutPay.mount('#revolut-pay-button', {
  createOrder: async () => {
    /* ... */
  },
  customer: customerWithDOB,
})
```

### Separate billing and shipping addresses

```typescript
import type { CustomerDetails, Address } from '@revolut/checkout'

const billingAddress: Address = {
  countryCode: 'US',
  region: 'NY',
  city: 'New York',
  streetLine1: '123 Work Street',
  postcode: '10001',
}

const shippingAddress: Address = {
  countryCode: 'US',
  region: 'CA',
  city: 'Los Angeles',
  streetLine1: '456 Home Avenue',
  postcode: '90001',
}

const customerDetails: CustomerDetails = {
  name: 'Jane Doe',
  email: 'jane@example.com',
  phone: '+12125551234',
  billingAddress,
  shippingAddress,
}
```

## Validation

Examples of client-side validation for customer details fields.

### Email validation

```typescript
function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return emailRegex.test(email)
}

import type { CustomerDetails } from '@revolut/checkout'

function validateCustomerDetails(details: Partial<CustomerDetails>): string[] {
  const errors: string[] = []

  if (details.email && !isValidEmail(details.email)) {
    errors.push('Invalid email format')
  }

  if (details.name && details.name.trim().split(' ').length < 2) {
    errors.push('Name must include first and last name')
  }

  if (details.phone && !details.phone.startsWith('+')) {
    errors.push('Phone number must include country code (e.g., +44)')
  }

  return errors
}
```

### Date of birth validation

```typescript
import type { CustomerDetails } from '@revolut/checkout'

function validateDateOfBirth(dob: CustomerDetails['dateOfBirth']): boolean {
  if (!dob) return true // Optional field

  const { day, month, year } = dob

  // Check ranges
  if (day < 1 || day > 31) return false
  if (month < 1 || month > 12) return false
  if (year < 1900 || year > new Date().getFullYear()) return false

  // Check valid date
  const date = new Date(year, month - 1, day)
  if (date.getDate() !== day) return false // Invalid date like Feb 31

  // Check minimum age (18 years)
  const eighteenYearsAgo = new Date()
  eighteenYearsAgo.setFullYear(eighteenYearsAgo.getFullYear() - 18)
  if (date > eighteenYearsAgo) return false

  return true
}

// Example usage
const dob = { day: 15, month: 6, year: 1990 }
if (validateDateOfBirth(dob)) {
  // Valid date of birth
}
```

## Error handling

Handle customer detail validation errors from the SDK:

```typescript
const { destroy } = await RevolutCheckout.embeddedCheckout({
  publicToken: 'pk_...',
  environment: 'prod',
  target: document.getElementById('checkout'),
  createOrder: async () => {
    /* ... */
  },

  onError: ({ error }) => {
    switch (error.type) {
      case 'error.invalid-email':
        alert('Please provide a valid email address')
        break
      case 'error.invalid-name':
        alert('Please provide your full name (first and last name)')
        break
      case 'error.invalid-address':
        alert('Please check your address details')
        break
      case 'error.invalid-postcode':
        alert('Please provide a valid postcode')
        break
      default:
        alert(`Error: ${error.message}`)
    }
  },
})
```

## See also

- [Address](/docs/sdks/merchant-web-sdk/types/address) - Address interface details
- [RevolutCheckoutError](/docs/sdks/merchant-web-sdk/types/revolut-checkout-error) - Customer validation errors
- [ValidationError](/docs/sdks/merchant-web-sdk/types/validation-error) - Form field validation errors