Sandbox
Help

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

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

PropertyDescriptionTypeRequired
nameCardholder name in format 'FirstName LastName' for card payment flowsstringNo
emailCustomer's email address Note: Required for payment if not set on order via API. In embeddedCheckout(), if provided, the email field is hidden from the checkout formstringNo
phoneCustomer's phone number in international format (e.g., +447950630319)stringNo
dateOfBirthCustomer's date of birth. Currently used only for Revolut Pay. See DateOfBirth propertiesobjectNo
billingAddressCustomer's billing address Note: Required for card payments in widget flows that use this object. In embeddedCheckout(), a valid billingAddress hides the billing form entirely; an invalid one shows the form with pre-filled values. For the form to be hidden, countryCode, postcode, streetLine1, and city must be present and validAddressYes*
shippingAddressCustomer's shipping address. Displayed only in order details on Merchant DashboardAddressNo

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

DateOfBirth properties

When dateOfBirth is provided, all three properties are required:

PropertyDescriptionTypeRequired
dayDay of month (1-31)numberYes
monthMonth (1-12)numberYes
yearFour-digit year (e.g., 1990)numberYes

Usage

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

Pre-filling embedded checkout

When you provide billingAddress in embeddedCheckout(), the widget hides the billing form if the address is valid. If the address is invalid or incomplete, the form is shown with the pre-filled values for the customer to review and correct. Similarly, if email is provided, the email field is hidden from the checkout form.

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

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)

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

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

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

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:

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

Rate this page