# How it works

Learn about PXP's Aeropay component for iOS.

## Overview

Aeropay is a US pay-by-bank payment method. PXP's Aeropay button component for iOS renders a payment button and guides shoppers through identity verification, bank account selection, and transaction submission in a modal popup.

With the Aeropay component, you can benefit from:

* **Pay-by-bank checkout:** Allow shoppers to pay directly from a linked bank account.
* **Built-in verification:** Collect shopper details and verify new Aeropay users with a one-time passcode (OTP) sent to the shopper's phone.
* **Bank linking:** Let shoppers link a bank account through the embedded Aerosync experience.
* **Faster returning-shopper flows:** Use a verified Aeropay user ID to skip data collection and OTP verification.
* **Flexible transaction processing:** Support authorisations, purchases, estimated authorisations, and payouts.
* **Customisable presentation:** Configure the button, popup, form fields, OTP screen, and bank selection screen.


Aeropay supports `USD` transactions with the `Ecom` entry type. Your session response must include `allowedFundingTypes.payByBanks.aeropay` with non-empty `externalMerchantId` and `configurationId` from the Unity Portal setup. See [Onboarding](/guides/checkout/components/ios/aeropay/onboarding).

## Shopper journeys

The component adapts the checkout flow based on whether the shopper has a verified Aeropay user ID:

| Journey | Configuration | Experience |
|  --- | --- | --- |
| New shopper | Don't set `userId`. | The shopper provides their details, verifies their identity with an OTP, and selects or links a bank account. |
| New shopper with known details | Return all required details from `onGetShopper`. You can also set `skipConsumerDataCollection` to `true`. | The component prefills valid shopper details. When data collection is skipped, the flow starts with OTP verification. |
| Returning shopper | Set `userId` to a verified, active Aeropay user ID. | The shopper goes directly to the Aerosync bank-selection screen without completing data collection or OTP verification. |


## Payment flow

The Aeropay payment flow has five steps.

### Step 1: Component initialisation

When you create the component, the SDK validates the session and transaction configuration, then makes the Aeropay button available with `buildContent()`.

`pxpCheckout.create(.aeropayButton, componentConfig:)` fails with these codes when validation fails:

| Check | Error code |
|  --- | --- |
| Missing `transactionData.intent.aeropay` | `SDK0115` |
| Entry type isn't `.ecom` | `SDK0114` |
| Currency isn't `USD` | `SDK0116` |
| Missing or empty Aeropay session funding config (`allowedFundingTypes.payByBanks.aeropay.externalMerchantId` or `configurationId`) | `SDK0113` |


### Step 2: Shopper identification

When the shopper taps the button, the SDK runs optional `onCustomValidation`, then checks the component configuration:

* If `userId` contains a verified, active Aeropay user ID, the SDK opens the Aerosync bank-selection screen.
* If `userId` isn't set, the SDK gets available shopper details from `onGetShopper` and starts the new-shopper flow.


For a new shopper, the component collects their first name, last name, email address, and phone number. You can prefill these fields through `onGetShopper` when their values are valid. If a supplied name, email address, or phone number is non-empty but invalid, the SDK invokes `onError` with `SDK1300` and doesn't open the popup.

If you return `phoneNumber` from `onGetShopper`, use US E.164 format with a leading `+` (for example `+14155550123`). Values such as `4155550123` without `+1` are invalid and trigger `SDK1300` before the popup opens. Omit the field or leave it empty when the shopper will enter it on the data-collection screen.

### Step 3: User verification

The component creates the Aeropay user and sends an OTP to the shopper's phone. After the shopper enters the correct code, the SDK calls `onUserVerificationSuccess` with the verified user details.

Store the returned `user.id` securely if you want to use the returning-shopper flow on future visits.

### Step 4: Bank selection

The component loads the shopper's linked bank accounts. The shopper can select an existing account or link a new one through Aerosync.

For payouts, the bank-linking option is hidden by default. Set `bankSelectionConfig.allowLinkBankOnPayout` to `true` to let shoppers link a bank account during a payout flow.

### Step 5: Transaction submission

After the shopper selects a bank account and confirms the transaction, the SDK:

1. Calls `onPreAuthorisation` on `AeropayButtonComponentConfig`. Return `true` to submit. Return `false` (or omit `onPreAuthorisation`) to abort submission without calling `onCancel` or `onError` — the bank-selection screen stays open and no transaction is sent. You must set `onPreAuthorisation` to return `true` (after any merchant-side checks) or payments never complete.
2. Builds and submits the pay-by-bank transaction to PXP.
3. Calls `onPostAuthorisation` after a successful submission or `onSubmitError` if submission fails.


Always verify the transaction on your backend before fulfilling an order or confirming a payout.

## Consumer data collection

When `userId` isn't set, the SDK uses the result from `onGetShopper` to determine how the data collection screen behaves:

| Shopper data | Component behaviour |
|  --- | --- |
| `onGetShopper` isn't provided | Shows all fields as empty and editable. |
| Some required fields are provided | Prefills and disables the valid provided fields unless you include them in `consumerDataCollectionConfig.editableFields`. Missing fields remain empty and editable. |
| All required fields are provided | Prefills and disables all fields when they're valid, unless you include them in `consumerDataCollectionConfig.editableFields`. |
| All required fields are provided and `skipConsumerDataCollection` is `true` | Creates the Aeropay user in the background and opens the OTP verification screen when all fields are valid. `editableFields` must be omitted, `nil`, or empty. |


The required shopper details are `firstName`, `lastName`, `email`, and `phoneNumber`. Providing all four fields doesn't skip the data collection screen by itself. You must also set `skipConsumerDataCollection` to `true` and omit `editableFields` or set it to `nil` or an empty array.

When `editableFields` is `nil` or empty, prefilled fields are read-only. Add a field to `editableFields` only when the shopper needs to change it.

## Returning shoppers

For a returning shopper, pass the verified Aeropay user ID to the component as `userId`. The SDK validates that the user is active before opening the Aerosync bank-selection screen.

If looking up the user fails or the user isn't active, the component calls `onError` and doesn't open the popup. Listen for `onError` with `SDK1307` (inactive user) or `SDK1308` (user lookup failed), then clear `userId` and restart the new-shopper flow. See [Events](/guides/checkout/components/ios/aeropay/events) for callback handling.

## Supported transaction intents

When you initiate a transaction, you provide key information about the transaction method, amount, and currency.

The transaction method consists of:

* The **entry type**, which describes the origin of the transaction. For Aeropay, this is always `Ecom` (set `entryType` to `.ecom` in the SDK).
* The **funding type**, which describes the payment method used (pay by bank via Aeropay).
* The **intent**, which describes the purpose and flow of the transaction.


Aeropay supports the following intents. In the Sessions API, set `transactionMethod.intent.aeropay` to the PascalCase value. In the SDK, set `transactionData.intent.aeropay` to the matching `AeropayIntentType` case:

| Intent | Description | iOS implementation |
|  --- | --- | --- |
| `Authorisation` | Authorise funds for later capture. | Set `aeropay: .authorisation` on `TransactionIntentData`. |
| `Purchase` | Complete the payment immediately. | Set `aeropay: .purchase` on `TransactionIntentData`. |
| `EstimatedAuthorisation` | Submit an authorisation for an estimated amount. | Set `aeropay: .estimatedAuthorisation` on `TransactionIntentData`. |
| `Payout` | Send funds to the shopper's selected bank account. | Set `aeropay: .payout` on `TransactionIntentData`. For payout intent, the main button label becomes **Withdraw by Bank** (default en-US). On the Aerosync bank-selection screen, the confirm action becomes **Withdraw** plus the formatted amount (for example `Withdraw $25.00`), not `Withdraw by Bank`. Labels are localisable through `localisation` and resource overrides. |


## What's next?

Continue with the Aeropay integration guides:

* **[Onboarding](/guides/checkout/components/ios/aeropay/onboarding):** Configure Aeropay in the Unity Portal.
* **[Implementation](/guides/checkout/components/ios/aeropay/implementation):** Integrate and render the Aeropay button.
* **[Configuration](/guides/checkout/components/ios/aeropay/configuration):** Customise the component's appearance and behaviour.
* **[Events](/guides/checkout/components/ios/aeropay/events):** Handle component callbacks and transaction results.