# `Address`

Address interface used for collecting customer billing and shipping address information. Required for payment processing compliance and fraud prevention.

:::info
For card payments, `billingAddress` should be provided in the checkout flow.

`shippingAddress` is optional. If you provide it, include at least the required address fields: `countryCode` and `postcode`. Avoid passing an empty address object.
:::

## Type signature

```typescript
interface Address {
  countryCode: CountryCode
  postcode: string
  region?: string
  city?: string
  streetLine1?: string
  streetLine2?: string
}

type CountryCode = 'GB' | 'US' | 'FR' | 'DE' | ... // ISO 3166-1 alpha-2
```

## Properties

| Property      | Description                                            | Type          | Required |
| ------------- | ------------------------------------------------------ | ------------- | -------- |
| `countryCode` | Two-letter ISO 3166-1 alpha-2 country code             | `CountryCode` | Yes      |
| `postcode`    | Postal code, ZIP code, or equivalent                   | `string`      | Yes      |
| `region`      | State, province, county, or region                     | `string`      | No       |
| `city`        | City or town name                                      | `string`      | No       |
| `streetLine1` | First line of street address                           | `string`      | No       |
| `streetLine2` | Second line of street address (apartment, suite, etc.) | `string`      | No       |

## `CountryCode`

The `CountryCode` type is a union of all supported, valid ISO 3166-1 alpha-2 country codes. Over 250 countries and territories are supported.

### Common country codes

| Code | Country        |
| ---- | -------------- |
| `GB` | United Kingdom |
| `US` | United States  |
| `FR` | France         |
| `DE` | Germany        |
| `ES` | Spain          |
| `IT` | Italy          |
| `NL` | Netherlands    |
| `PL` | Poland         |
| `PT` | Portugal       |
| `CA` | Canada         |
| `AU` | Australia      |
| `JP` | Japan          |
| `CN` | China          |
| `IN` | India          |
| `BR` | Brazil         |

:::info
The complete `CountryCode` type is available in the SDK's [`src/types.ts`](https://github.com/revolut-engineering/revolut-checkout/blob/master/src/types.ts) file.

After installing the package, access it via:

- IDE autocomplete when importing `CountryCode`
- In `node_modules/@revolut/checkout/types/types.d.ts`
  :::

## US state codes

For US addresses, the `region` field should use the 2-letter state abbreviation:

| Code | State         | Code | State          |
| ---- | ------------- | ---- | -------------- |
| `AL` | Alabama       | `MT` | Montana        |
| `AK` | Alaska        | `NE` | Nebraska       |
| `AZ` | Arizona       | `NV` | Nevada         |
| `AR` | Arkansas      | `NH` | New Hampshire  |
| `CA` | California    | `NJ` | New Jersey     |
| `CO` | Colorado      | `NM` | New Mexico     |
| `CT` | Connecticut   | `NY` | New York       |
| `DE` | Delaware      | `NC` | North Carolina |
| `FL` | Florida       | `ND` | North Dakota   |
| `GA` | Georgia       | `OH` | Ohio           |
| `HI` | Hawaii        | `OK` | Oklahoma       |
| `ID` | Idaho         | `OR` | Oregon         |
| `IL` | Illinois      | `PA` | Pennsylvania   |
| `IN` | Indiana       | `RI` | Rhode Island   |
| `IA` | Iowa          | `SC` | South Carolina |
| `KS` | Kansas        | `SD` | South Dakota   |
| `KY` | Kentucky      | `TN` | Tennessee      |
| `LA` | Louisiana     | `TX` | Texas          |
| `ME` | Maine         | `UT` | Utah           |
| `MD` | Maryland      | `VT` | Vermont        |
| `MA` | Massachusetts | `VA` | Virginia       |
| `MI` | Michigan      | `WA` | Washington     |
| `MN` | Minnesota     | `WV` | West Virginia  |
| `MS` | Mississippi   | `WI` | Wisconsin      |
| `MO` | Missouri      | `WY` | Wyoming        |

:::info
See a complete list of [U.S. state and territory abbreviations](https://en.wikipedia.org/wiki/List_of_U.S._state_and_territory_abbreviations)
:::

## Usage

Examples of using the `Address` type across different SDK methods and payment flows.

### Billing address in embedded checkout

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

const billingAddress: Address = {
  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 () => {
    /* ... */
  },
  billingAddress, // Pre-fill address
})
```

### US address example

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

const usAddress: Address = {
  countryCode: 'US',
  region: 'CA', // California
  city: 'San Francisco',
  streetLine1: '1 Market Street',
  streetLine2: 'Suite 300',
  postcode: '94105',
}
```

### Minimal address (required fields only)

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

const minimalAddress: Address = {
  countryCode: 'FR',
  postcode: '75001',
}
```

### With card field submission

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

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

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

const billingAddress: Address = {
  countryCode: 'DE',
  postcode: '10115',
  city: 'Berlin',
  streetLine1: 'Friedrichstraße 123',
}

// Submit with billing address
cardField.submit({
  name: 'Example Customer',
  email: 'example.customer@example.com',
  billingAddress,
})
```

### Collecting address from form

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

function getAddressFromForm(form: HTMLFormElement): Address {
  const formData = new FormData(form)

  return {
    countryCode: formData.get('country') as CountryCode,
    postcode: formData.get('postcode') as string,
    region: formData.get('region') as string | undefined,
    city: formData.get('city') as string | undefined,
    streetLine1: formData.get('streetLine1') as string | undefined,
    streetLine2: formData.get('streetLine2') as string | undefined,
  }
}

// Use in checkout
const address = getAddressFromForm(document.querySelector('form')!)

const { destroy } = await RevolutCheckout.embeddedCheckout({
  // ... configuration
  billingAddress: address,
})
```

## Validation

Examples of client-side validation for address fields and postcode formats.

### Required field validation

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

function validateAddress(address: Partial<Address>): address is Address {
  if (!address.countryCode) {
    throw new Error('Country code is required')
  }

  if (!address.postcode) {
    throw new Error('Postcode is required')
  }

  return true
}

// Use with type guard
const userInput: Partial<Address> = {
  countryCode: 'GB',
  postcode: 'EC1A 1BB',
}

if (validateAddress(userInput)) {
  // TypeScript knows userInput is Address now
  const { destroy } = await RevolutCheckout.embeddedCheckout({
    billingAddress: userInput,
    // ... other options
  })
}
```

### Postcode format validation

Different countries have different postcode formats. Consider using a validation library:

```typescript
function validatePostcode(postcode: string, countryCode: CountryCode): boolean {
  const postcodePatterns: Partial<Record<CountryCode, RegExp>> = {
    GB: /^[A-Z]{1,2}\d{1,2}[A-Z]?\s?\d[A-Z]{2}$/i,
    US: /^\d{5}(-\d{4})?$/,
    CA: /^[A-Z]\d[A-Z]\s?\d[A-Z]\d$/i,
    DE: /^\d{5}$/,
    FR: /^\d{5}$/,
  }

  const pattern = postcodePatterns[countryCode]
  if (!pattern) return true // No validation for unknown countries

  return pattern.test(postcode)
}

// Example usage
const isValid = validatePostcode('EC1A 1BB', 'GB') // true
const isValid2 = validatePostcode('12345', 'US') // true
```

## Error handling

If the address is invalid, the SDK will return an error:

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

  onError: ({ error }) => {
    if (error.type === 'error.invalid-postcode') {
      alert('Please check your postcode format')
    }
    if (error.type === 'error.invalid-address') {
      alert('Please provide a valid address')
    }
  },
})
```

## See also

- [CustomerDetails](/docs/sdks/merchant-web-sdk/types/customer-details) - Full customer information including address
- [RevolutCheckoutError](/docs/sdks/merchant-web-sdk/types/revolut-checkout-error) - Address validation errors