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 APIstringNo
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 objectAddressYes*
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

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