Accept Aeropay pay-by-bank payments with automatic consumer verification, bank linking via Aerosync, and the same Drop-in callbacks as other payment methods.
Aeropay is included in Checkout Drop-in when it's enabled in your session and the transaction meets Aeropay eligibility rules. When the shopper selects Pay by bank via Aeropay and taps the pay button, the SDK mounts an internal Aeropay button component and drives consumer data collection (when required), OTP verification, bank selection or linking, and Unity transaction authorisation.
There's no separate Aeropay factory call in Drop-in. Configure Aeropay through CheckoutDropInConfig and DropInMethodConfig.aeropay.
Aeropay in Drop-in gives you these benefits:
- Aeropay appears automatically in the payment method list when the session includes Aeropay funding, the currency is
USD, and the entry type is.ecom. - Drop-in handles consumer verification, Aerosync bank linking, and payment authorisation. You don't need Aeropay-specific UI code.
- Aeropay uses the same
onSuccessandonErrorcallbacks as other payment methods for a unified integration. - Site branding from the Unity Portal is applied automatically to the Aeropay launcher button, popup, and form fields.
- Currency and entry-type gating is enforced automatically.
When a shopper selects Aeropay in Checkout Drop-in and taps the pay button:
- The shopper selects the Aeropay panel. The SDK shows the Aeropay launcher in the panel.
- The shopper taps Pay by bank.
- Your
onBeforeSubmitcallback runs (if configured). Returnfalseto stop the flow before the popup opens. - Consumer data collection runs when required (skipped for a non-empty
userId, or whenskipConsumerDataCollectionistruewith all four validonGetShopperfields and empty/nileditable fields). - OTP verification runs when required (skipped when
userIdis set). - Aerosync bank selection or bank linking runs.
- Your
onSubmitcallback fires, then the SDK submits the Unity transaction. Drop-in always proceeds afteronSubmit(there's no merchantonPreAuthorisationgate). - Your
onSuccesscallback fires withpaymentMethod == .aeropay.
If the shopper closes the Aeropay popup without completing, methodConfig.global.onCancel fires with .aeropay and a nil payload. Errors during setup or the flow are delivered to onError.
How the SDK decides whether to collect consumer data:
- userId provided: When
methodConfig.aeropay.userIdis set to a non-empty value, skip consumer data collection and OTP. Open Aerosync (bank selection) directly after validating that the user is active. - Skip data collection: When
skipConsumerDataCollectionistrue,onGetShopperreturns all four fields (firstName,lastName,email, andphoneNumber), andeditableConsumerDataFieldsisnilor empty, auto-create the Aeropay user, skip the data screen, and go to OTP. - Otherwise: Show the consumer data collection screen (prefilled from
onGetShopper). Prefill fields with values are read-only unless listed ineditableConsumerDataFields. Missing fields stay available for the shopper to complete.
Configure Aeropay-specific behaviour at methodConfig.aeropay. All properties are optional.
The following properties are available for Aeropay configuration:
| Property | Description |
|---|---|
userIdString? | Pre-configured Aeropay user ID. When provided, consumer data collection and OTP are skipped and the flow opens directly at bank selection (Aerosync). The SDK validates that the user is active before opening the popup. When userId is set, Drop-in also skips shopper-data validation at load. |
editableConsumerDataFields[ConsumerDataField]? | Fields returned from onGetShopper that remain editable on the consumer data collection screen. Possible values: .firstName, .lastName, .email, .phoneNumber. When nil or empty, prefilled fields are read-only. Must be empty or nil when using skipConsumerDataCollection. |
excludedBankAccountIds[AeropayBankAccountId]? | Bank account IDs to hide from the bank selection screen. Use string or integer literals (e.g., ["12345"] or [12345]). |
skipConsumerDataCollectionBool | When true, onGetShopper provides all four consumer fields, and editableConsumerDataFields is empty or nil, the consumer data screen is skipped and the flow goes directly to OTP verification (the user is created automatically). Defaults to false. |
Don't set skipConsumerDataCollection to true together with a non-empty editableConsumerDataFields list. The skip path requires editable fields to be nil or empty.
Aeropay inherits the following setting from methodConfig.global:
| Property | Description |
|---|---|
onCancel(DropInPaymentMethod, Any?) -> Void | Called when the shopper closes the Aeropay popup. For Aeropay, the payload is nil. Cancellation doesn't call onError. |
onGetConsent doesn't apply to Aeropay in Drop-in (Card, PayPal, and Apple Pay only).
The following are handled internally from your Unity site branding and Drop-in wiring:
- Popup, OTP, bank selection, and launcher button styling.
- Component-level callbacks such as
onClickandonUserVerificationSuccess. - Merchant-controlled
onPreAuthorisation(Drop-in always proceeds afteronSubmit). - Payout intent and
allowLinkBankOnPayout.
If you need merchant-controlled pre-authorisation gating, payout intent, or styling and callbacks beyond Drop-in's unified surface, those capabilities aren't part of the Drop-in Aeropay integration. See What Drop-in exposes vs what it manages.
This example shows Aeropay intent, shopper identity, cancellation handling, and optional methodConfig.aeropay settings. The skip path below is consistent: all four consumer fields are provided and editable fields are omitted.
import PXPCheckoutSDK
let dropInConfig = CheckoutDropInConfig(
environment: .test,
session: sessionData,
transactionData: DropInTransactionData(
amount: Decimal(string: "25.00") ?? 0,
currency: "USD",
entryType: .ecom,
intent: DropInTransactionIntentData(
aeropay: .authorisation
),
merchantTransactionId: UUID().uuidString,
merchantTransactionDate: { Date() }
),
merchantShopperId: "shopper-001",
ownerId: "MERCHANT_GROUP_1", // Merchant group ID (ownerType is always "MerchantGroup")
methodConfig: DropInMethodConfig(
global: DropInGlobalConfig(
onCancel: { paymentMethod, _ in
guard paymentMethod == .aeropay else { return }
// Shopper closed Pay by Bank — not an error
}
),
aeropay: DropInAeropayConfig(
// userId: "existing-aeropay-user-id",
skipConsumerDataCollection: true
// editableConsumerDataFields must stay nil or empty when skip is true
)
),
onGetShopper: {
TransactionShopper(
id: "shopper-001",
firstName: "John",
lastName: "Doe",
email: "shopper@example.com",
// When non-empty: +1 followed by 10 digits (e.g. +16465180948). Omit or leave empty to collect in the popup.
phoneNumber: "+16465180948"
)
},
onBeforeSubmit: { paymentMethod async in
guard paymentMethod == .aeropay else { return true }
return await validateCheckoutForm()
},
onSubmit: { paymentMethod in
// Unity transaction is about to submit for Aeropay
print("Submit: \(paymentMethod.rawValue)")
},
onSuccess: { result in
guard result.paymentMethod == .aeropay else { return }
verifyPaymentOnBackend(result)
},
onError: { paymentMethod, error in
guard paymentMethod == .aeropay else { return }
showError(error.errorCode, error.errorMessage)
}
)
let checkoutDropIn = try CheckoutDropIn(config: dropInConfig)
// create() does not throw for Aeropay eligibility or render failures — those arrive on onError after create completes.
await checkoutDropIn.create()Aeropay requires the following to function correctly:
- Currency: Transaction currency must be
USD. If another currency is set, the Aeropay panel isn't shown and Drop-in firesonErrorwithSDK0116. - Entry type: Must be
.ecom. If it isn't, the Aeropay panel isn't shown and Drop-in firesonErrorwithSDK0114. - Unity Portal: Aeropay must be enabled for your merchant site. The session response must contain
allowedFundingTypes.payByBanks.aeropaywithexternalMerchantIdandconfigurationId. If Aeropay funding is absent, the panel isn't shown and noonErrorfires. - Intent:
transactionData.intent.aeropaymust be set to.authorisation,.purchase, or.estimatedAuthorisation. If it's missing, Drop-in callsonErrorwithSDK0115and the Aeropay panel doesn't load. - Shopper identity: Implement
onGetShopperwith valid consumer data when values are provided, or setmethodConfig.aeropay.userId. Non-empty invalid shopper fields at Drop-in load fireSDK1300and hide the Aeropay panel. Nil shopper, empty fields, and empty phone are allowed at load and collected in the popup when needed. When you supplyphoneNumberinonGetShopper, use+1followed by 10 digits (for example+16465180948). Omit or leave empty to collect in the popup. - Site branding: Checkout Drop-in site configuration must be available from Unity for branding and styling.
- Placement: Aeropay appears in the Drop-in payment method list with the label Pay by bank via Aeropay (localisable). Panel order follows site
paymentMethodOrdering. onErrorbeforecreate(): Aeropay eligibility and render failures duringawait create()surface ononError, not as thrown errors fromcreate(). KeeponErrorimplemented before callingcreate().
Aeropay works through the standard Drop-in implementation. Set the Aeropay intent, provide shopper data or a userId, and use the shared success and error callbacks.
Enable Aeropay in the Unity Portal for your merchant and site. Create a session with the standard Sessions API and include the Aeropay intent.
{
"merchant": "MERCHANT-1",
"site": "SITE-1",
"sessionTimeout": 120,
"merchantTransactionId": "0ce72cfd-014d-4256-a006-a56601b2ffc4",
"transactionMethod": {
"intent": {
"card": "Authorisation",
"paypal": "Purchase",
"aeropay": "Authorisation"
}
},
"amounts": {
"currencyCode": "USD",
"transactionValue": 25.00
},
"allowTransaction": true,
"serviceType": "CheckoutDropIn"
}When Aeropay is enabled, the session response includes:
{
"sessionId": "...",
"hmacKey": "...",
"encryptionKey": "...",
"allowedFundingTypes": {
"payByBanks": {
"aeropay": {
"externalMerchantId": "...",
"configurationId": "..."
}
}
}
}Pass the session credentials and funding types into SessionData when you initialise Drop-in. If allowedFundingTypes.payByBanks.aeropay is absent, the Aeropay panel isn't shown. If externalMerchantId or configurationId is blank, the panel doesn't load and Drop-in calls onError with SDK0113.
Aeropay credentials (externalMerchantId, configurationId) come from the Unity Portal on the session response. Don't hardcode production values in the app.
Set the Aeropay intent in transactionData.intent.aeropay:
intent: DropInTransactionIntentData(
aeropay: .authorisation
// or .purchase
// or .estimatedAuthorisation
)Supported Aeropay intents in Drop-in:
| Intent value (Sessions API) | SDK value | Supported | Notes |
|---|---|---|---|
Authorisation | .authorisation | Yes | Recommended for checkout. There is no SDK default; you must set intent.aeropay. |
Purchase | .purchase | Yes | None |
EstimatedAuthorisation | .estimatedAuthorisation | Yes | None |
Payout | Not available | No | Not available on DropInAeropayIntentType. |
When userId isn't provided, Drop-in validates non-empty onGetShopper fields before showing the Aeropay panel. Invalid formats raise SDK1300 through onError and hide Aeropay. Nil shopper, empty or omitted fields, and empty phone don't fail this load check.
| Field | Rules |
|---|---|
firstName | If provided and non-empty: letters and spaces only (Unicode), max 100 characters |
lastName | If provided and non-empty: letters and spaces only (Unicode), max 100 characters |
email | If provided and non-empty: valid email format, max 128 characters |
phoneNumber | If provided and non-empty: US format +1 + 10 digits matching ^\+1\d{10}$ (for example +16465180948). Values without the +1 prefix (for example 6465180948) fail load validation with SDK1300. Empty or nil is OK at load; omit or leave empty to collect in the popup. |
skipConsumerDataCollection additionally requires all four values to be non-empty.
Use updateAmount(amount:) when the order total changes. This updates all enabled payment methods, including Aeropay.
await checkoutDropIn.create()
checkoutDropIn.updateAmount(amount: Decimal(150))When an Aeropay payment succeeds, your onSuccess callback receives a DropInSubmitResult:
onSuccess: { result in
guard result.paymentMethod == .aeropay else { return }
// result.systemTransactionId
// result.merchantTransactionId
// result.paymentData is nil for Aeropay
verifyPaymentOnBackend(result)
}Handle shopper cancellation with methodConfig.global.onCancel. Don't treat this as an error.
methodConfig: DropInMethodConfig(
global: DropInGlobalConfig(
onCancel: { paymentMethod, _ in
guard paymentMethod == .aeropay else { return }
// Shopper closed the Aeropay popup
}
)
)Handle Aeropay-specific Drop-in errors by branching on error.errorCode:
onError: { paymentMethod, error in
guard paymentMethod == .aeropay else { return }
switch error.errorCode {
case "SDK0114":
showError("Pay by Bank is only available for e-commerce checkout.")
case "SDK0116":
showError("Pay by Bank only supports USD.")
case "SDK0113":
showError("Aeropay isn't configured for this session. Choose another payment method.")
case "SDK0115":
showError("Aeropay intent is missing. Choose another payment method.")
case "SDK1300":
showError(
"Please check your name, email, and US phone number (+1 followed by 10 digits)."
)
case "SDK1125":
// Fallback when Aeropay fails to render for unexpected reasons.
// Credential and intent setup failures usually keep SDK0113 or SDK0115.
showError(
"Aeropay is temporarily unavailable. Please try another payment method."
)
case "SDK1126":
// Fallback when Drop-in can't map a richer failed-submit result.
// Mapped Unity failures often deliver the API errorCode from FailedSubmitResult instead.
showError(
"Aeropay payment failed. Please try again or use a different payment method."
)
default:
// Mapped submit failures may use the API errorCode from FailedSubmitResult.
showError(error.errorMessage)
}
}The following table describes common Aeropay error scenarios:
| Scenario | How to detect | Recommended action |
|---|---|---|
| Shopper cancelled | methodConfig.global.onCancel with .aeropay | No alert needed. The shopper action was intentional. |
| Currency not USD | Aeropay panel not shown, and onError with SDK0116 | Use currency = "USD" when Aeropay is in the session. |
Entry type not .ecom | Aeropay panel not shown, and onError with SDK0114 | Use entryType: .ecom. |
| Aeropay not in session | Panel not shown (no onError) | Enable Aeropay in the Unity Portal. Ensure the session includes payByBanks.aeropay. |
| Blank credentials or missing intent | Expect SDK0113 (blank credentials) or SDK0115 (missing intent) via onError. SDK1125 is only the fallback when Aeropay fails to render for other unexpected reasons (not the usual code for credential or intent setup). | Check externalMerchantId, configurationId, and intent.aeropay. |
| Invalid shopper data at load | SDK1300 via onError; Aeropay panel not shown | Check onGetShopper field formats (especially phone +1XXXXXXXXXX), or provide userId. |
| User not active | SDK1307 via onError | The user must complete Aeropay verification before paying. |
| Transaction declined | API errorCode from the failed submit result on onError when present; otherwise SDK1126. Don't expect SDK1326 as the Drop-in merchant onError code for mapped submit failures (SDK1326 is a component-level analytics code). | Suggest another payment method. |
Always verify Aeropay payments on your backend before fulfilling orders:
onSuccess: { result in
guard result.paymentMethod == .aeropay else { return }
Task {
let verified = await verifyPaymentOnBackend(
systemTransactionId: result.systemTransactionId,
merchantTransactionId: result.merchantTransactionId
)
if verified {
navigateToConfirmation(result.systemTransactionId)
} else {
showError("Payment verification failed")
}
}
}Confirm the transaction state, merchant transaction ID, amount, and funding type (PayByBank) against your order records using the Transactions API.
Create and payment failures surface through onError. Branch on error.errorCode.
| Error code | When it occurs |
|---|---|
SDK1125 | Fallback when Aeropay fails to load in Drop-in for unexpected reasons. Expect SDK0113 or SDK0115 for credential or intent setup failures; those codes are preserved on onError when the underlying create error is a BaseSdkException. |
SDK1126 | Fallback when a Unity Aeropay submit fails and there is no API errorCode on FailedSubmitResult. When the failed result includes an API errorCode, Drop-in delivers that code on onError instead. |
| Error code | Message | When it occurs in Drop-in |
|---|---|---|
SDK0114 | Aeropay only supports Ecom entry type | entryType isn't .ecom (panel hidden). Fired directly via onError. |
SDK0116 | Aeropay only supports USD currency | currency isn't USD (panel hidden). Fired directly via onError. |
SDK0113 | Aeropay is missing in allow funding types | Session Aeropay credentials are blank. The panel doesn't load and onError returns SDK0113. |
SDK0115 | Intent type for Aeropay is required but not provided | intent.aeropay is missing. The panel doesn't load and onError returns SDK0115. |
During the popup flow, Aeropay component errors may also surface through onError. Representative codes:
| Error code | Scenario |
|---|---|
SDK1300 | Invalid onGetShopper data (at Drop-in load when malformed and non-empty, or during the popup flow) |
SDK1301 | User creation API failure |
SDK1302 | OTP verification failure (including provider code AP112) |
SDK1303 | Missing or invalid Aerosync payload (including bank-list load when no verified user ID is available yet). Prefer this over SDK1311 for that diagnosis. |
SDK1304 | Aerosync widget error |
SDK1305 | Bank account linking failure |
SDK1306 | Bank account list retrieval failure |
SDK1307 | Pre-configured userId isn't active |
SDK1308 | Get user API failure (including when retrieving a returning userId fails) |
SDK1319 | Aeropay aggregator credentials lookup failure |
API errorCode or SDK1126 | Unity transaction failure. Drop-in onError receives the API errorCode from FailedSubmitResult when present; otherwise SDK1126. SDK1326 is an internal component analytics code for mapped failed submits, not the primary Drop-in merchant onError code. There is no separate merchant onSubmitError callback in Drop-in. |
Aeropay in Drop-in uses a fixed merchant surface. Use this table as the Drop-in contract:
| Concern | Drop-in behaviour |
|---|---|
| UI placement | Panel inside CheckoutDropIn.buildContent() |
| Branding | Unity Portal Drop-in site configuration (launcher, popup, fields) |
| Merchant callbacks | Unified Drop-in sequence: onBeforeSubmit, onSubmit, onSuccess, onError, and methodConfig.global.onCancel |
| Pre-authorisation gate | Always proceeds after onSubmit (no merchant veto after bank confirmation) |
| Payout intent | Not available (DropInAeropayIntentType has no payout case) |
| Eligibility failures | Panel hidden; some failures also call onError (see Error codes) |
How Drop-in's unified callbacks relate to the Aeropay flow:
| Drop-in callback | When it fires for Aeropay |
|---|---|
onBeforeSubmit | Shopper taps Pay by bank, before the popup opens. Return false to stop. |
onSubmit | Bank selected and Unity transaction is about to submit. Drop-in always continues afterward. |
onSuccess | Unity authorises the transaction. |
methodConfig.global.onCancel | Shopper closes the popup. Payload is nil. Doesn't call onError. |
onError | Setup, flow, or transaction error. For Unity transaction failure: API errorCode from FailedSubmitResult when present; otherwise SDK1126. SDK1326 is internal component analytics, not the primary Drop-in merchant callback code. |
Drop-in doesn't expose merchant callbacks for button click, user-verification success, or a separate submit-error channel. Handle those concerns through the unified callbacks and analytics events above.
Use these checks when Aeropay doesn't appear or the pay-by-bank flow fails.
Verify these conditions:
allowedFundingTypes.payByBanks.aeropayis present in the session response with non-blankexternalMerchantIdandconfigurationId.transactionData.currencyis"USD".transactionData.entryTypeis.ecom.transactionData.intent.aeropayis set to a supported intent.onErrormay fire withSDK0116(currency),SDK0114(entry type),SDK1300(invalid shopper data at load),SDK0113(credentials),SDK0115(missing intent), orSDK1125(Aeropay failed to load).
Look for these symptoms:
- Non-empty invalid
onGetShopperfields at Drop-in load hide the Aeropay panel and callonError. - Name, email, or US phone format (
+1+ 10 digits) is wrong, andmethodConfig.aeropay.userIdisn't set.
Aeropay eligibility and render failures during await create() surface on onError, not as thrown errors from create(). Keep onError implemented before calling create().
Check the following:
- The session is missing Aeropay credentials, or
intent.aeropayisn't set. - Branch on
error.errorCode. ExpectSDK0113orSDK0115for credential or intent setup failures.SDK1125indicates Aeropay failed to render for other unexpected reasons (not the usual code for those setup failures). - Log
error.errorMessagefor extra detail.
Check the following:
methodConfig.aeropay.userIdis empty or missing after trim.- If the user isn't active,
onErrorreceivesSDK1307. If retrieving the user fails,onErrorreceivesSDK1308. Clear or replace the storeduserIdand restart the new-shopper flow.
Check the following:
- Confirm
onBeforeSubmitis implemented onCheckoutDropInConfig. If it's omitted, Drop-in doesn't register the Aeropay pre-popup validation hook and the flow always opens after the button tap. onBeforeSubmitreturnsfalsefor.aeropay.- The callback is set on
CheckoutDropInConfig, not only insidemethodConfig.
Check the following:
- One or more of
firstName,lastName,email, andphoneNumberis missing fromonGetShopper. editableConsumerDataFieldsis set to a non-empty list.
Before you go live with Aeropay, confirm the following:
- Enable Aeropay in the Unity Portal for your merchant site.
- Confirm the session includes
allowedFundingTypes.payByBanks.aeropaywithexternalMerchantIdandconfigurationId. - Include
"aeropay": "Authorisation"(or another supported intent) in the session intent. - Set
transactionData.currencyto"USD"andentryTypeto.ecom. - Set
transactionData.intent.aeropayto a supported Drop-in intent. - Implement
onGetShopperwith valid formats when you supply values, or providemethodConfig.aeropay.userId. - Implement
onSuccessandonError. - Optionally configure
methodConfig.aeropayfor user ID, skip data collection, editable fields, or excluded bank accounts. - Optionally handle cancellation via
methodConfig.global.onCancel. - Verify payments on your backend before fulfilling orders.