Learn how to configure the Aeropay button component for Android.
At minimum, the Aeropay button requires an Aeropay-enabled session and valid transaction data on SDK initialisation. You can then create the component with its default presentation.
Configure onPreAuthorisation and return true when the transaction can proceed so shoppers can complete payment. If you omit the callback, submission doesn't proceed and the popup stays open.
import com.pxp.checkout.components.aeropaybutton.types.AeropayButtonComponentConfig
import com.pxp.checkout.types.ComponentType
val config = AeropayButtonComponentConfig().apply {
onPreAuthorisation = { true }
onPostAuthorisation = { result ->
verifyPaymentOnBackend(result)
}
onError = { error ->
// Handle flow errors using error.errorCode and error.message
}
}
val aeropayButton = checkout.createComponent(
ComponentType.AERO_PAY_BUTTON,
config,
)Always verify the transaction on your backend before fulfilling an order or confirming a payout. Client callbacks can be manipulated by malicious users.
Configure the session and transaction before creating the Aeropay button:
import com.pxp.checkout.models.Environment
import com.pxp.checkout.models.EntryType
import com.pxp.checkout.models.PxpSdkConfig
import com.pxp.checkout.models.TransactionData
import com.pxp.checkout.models.TransactionIntentData
import com.pxp.checkout.models.AeropayIntentType
import com.pxp.checkout.services.models.transaction.Shopper
import java.time.Instant
val sdkConfig = PxpSdkConfig(
environment = Environment.TEST,
session = sessionConfig,
transactionData = TransactionData(
amount = 25.00,
currency = "USD",
entryType = EntryType.Ecom,
intent = TransactionIntentData(aeropay = AeropayIntentType.Authorisation),
merchant = "your-merchant-id",
merchantTransactionId = java.util.UUID.randomUUID().toString(),
merchantTransactionDate = { Instant.now().toString() },
),
clientId = "your-client-id",
ownerType = "MerchantGroup",
ownerId = "MERCHANT_GROUP_1",
onGetShopper = {
Shopper(
id = "shopper-123",
firstName = "John",
lastName = "Doe",
email = "john.doe@example.com",
phoneNumber = "+14155550123",
)
},
)The following SDK options affect the Aeropay component:
| Property | Description |
|---|---|
sessionSessionConfig required | Session data from your backend. It must include allowedFundingTypes.payByBanks.aeropay with non-blank externalMerchantId and configurationId. |
ownerIdstring required | Your merchant group identifier. |
transactionData.currencystring required | The transaction currency. Aeropay supports USD. |
transactionData.entryTypeEntryType required | The transaction entry type. Set this to EntryType.Ecom. |
transactionData.intent.aeropayAeropayIntentType required | Aeropay transaction intent. Possible values:
|
onGetShopper() -> Shopper? | Optional. When set, supplies shopper details to prefill the consumer data screen (firstName, lastName, email, phoneNumber). Required for skipConsumerDataCollection. |
Use these properties when configuring AeropayButtonComponentConfig:
| Property | Description |
|---|---|
userIdString? | A verified Aeropay user ID. The SDK validates that the user is active, then skips consumer data collection and OTP verification. |
skipConsumerDataCollectionBoolean | When true, skips the consumer data screen if onGetShopper supplies all four required fields and editableFields is omitted, null, or empty. Defaults to false. |
labelString? | Custom text for the payment button when the intent isn't Payout. If omitted, the SDK uses PxpSdkConfig.localisation?.aeropay?.payByBankButton?.label, or the default (en-US: Pay by bank). For Payout, label is ignored. Override payout text with PxpSdkConfig.localisation?.aeropay?.payByBankButton?.labelPayout (en-US default: Withdraw by Bank). |
disabledBoolean | Whether the payment button starts disabled. Defaults to false. After creation, call setDisabled() to change the button state. |
stylesButtonStateStyles? | Styles for the payment button. See Button styles. |
popupConfigAeropayPopupConfig? | Styles for the popup container, shared action buttons, and intro cards. |
consumerDataCollectionConfigConsumerDataCollectionConfig? | Field behaviour and styling for the consumer data screen. |
otpVerificationConfigOtpVerificationConfig? | Styling for the OTP verification screen. |
bankSelectionConfigBankSelectionConfig? | Behaviour and styling for bank selection and the Aerosync experience. |
To override pay or payout button text through localisation:
localisation = LocalisationConfig(
aeropay = AeropayLocalisation(
payByBankButton = AeropayPayByBankButtonLocalisation(
label = "Pay with my bank",
labelPayout = "Withdraw to bank",
),
),
)Don't set userId when the shopper doesn't have a verified Aeropay account. onGetShopper is optional on PxpSdkConfig. When omitted, the consumer data screen opens with empty fields. When set, the SDK can prefill firstName, lastName, email, and phoneNumber. Prefill and skipConsumerDataCollection depend on onGetShopper returning those four values.
val config = AeropayButtonComponentConfig().apply {
onUserVerificationSuccess = { user ->
saveAeropayUserId(user.id)
}
}Store user.id securely after verification so you can identify the shopper on future visits.
Set skipConsumerDataCollection to true to start the new-shopper flow at OTP verification:
val sdkConfig = PxpSdkConfig(
// ...session and transaction configuration
onGetShopper = {
Shopper(
firstName = "John",
lastName = "Doe",
email = "john.doe@example.com",
phoneNumber = "+14155550123",
)
},
)
val config = AeropayButtonComponentConfig().apply {
skipConsumerDataCollection = true
}The component skips the consumer data screen only when all of these conditions are met:
onGetShopperreturns valid, non-emptyfirstName,lastName,email, andphoneNumbervalues.skipConsumerDataCollectionistrue.consumerDataCollectionConfig.editableFieldsis omitted,null, or empty.
If a value is missing or empty, or editableFields contains a field, the component shows the consumer data screen. If a supplied non-empty value is invalid, the SDK calls onError with SDK1300 and doesn't open the popup.
Pass a verified Aeropay user ID to skip data collection and OTP verification:
val config = AeropayButtonComponentConfig().apply {
userId = "c7582e95-d9a1-42c3-b0e3-ee6bc98764ec"
}If the user isn't active, onError receives SDK1307. If the get-user API returns a recognised failure (including user not found), onError receives SDK1308. Network or transport errors on the same call use SDK0500 or SDK0000. The popup doesn't open in these cases. See Returning-shopper validation.
Use popupConfig to customise the popup container, shared action buttons, and intro cards:
config.popupConfig = AeropayPopupConfig(
styles = AeropayViewStyleConfig(
fontFamily = "Source Code Pro",
foregroundColor = Color.Black,
backgroundColor = Color.White,
cornerRadius = 20.dp,
padding = PaddingValues(16.dp),
),
actionButtonStyles = ButtonStateStyles(
base = FieldStyle(
backgroundColor = Color(0xFF2F3BFF),
color = Color.White,
),
),
introStyles = ScreenIntroStyleConfig(
backgroundColor = Color(0xFFDBEDFA),
cornerRadius = 12.dp,
),
)Configure the popup with these properties:
| Property | Description |
|---|---|
stylesAeropayViewStyleConfig? | Popup container styles for font, colours, border, corner radius, and padding. |
actionButtonStylesButtonStateStyles? | Shared styles for action buttons on popup screens. Screen-level button styles override these values. |
introStylesScreenIntroStyleConfig? | Styles for the intro card on the consumer data and OTP screens. |
Use consumerDataCollectionConfig to control which prefilled fields remain editable and to customise the form:
config.consumerDataCollectionConfig = ConsumerDataCollectionConfig(
editableFields = listOf(
ConsumerDataField.EMAIL,
ConsumerDataField.PHONE_NUMBER,
),
fieldConfig = ConsumerDataFieldConfig(
labelStyles = FieldLabelStateStyles(
base = FieldLabelStyle(color = Color(0xFF333333)),
),
inputStyles = FieldInputStateStyles(
base = FieldInputStyle(borderColor = Color(0xFFCCCCCC)),
invalid = FieldInputStyle(borderColor = Color(0xFFD32F2F)),
),
invalidTextStyle = FieldMessageStyle(color = Color(0xFFD32F2F)),
phoneNumberGuideTextStyle = FieldMessageStyle(fontSize = 12f),
),
buttonStyles = ButtonStateStyles(
base = FieldStyle(backgroundColor = Color(0xFF2F3BFF)),
),
)The consumer data screen supports these properties:
| Property | Description |
|---|---|
editableFieldsList<ConsumerDataField>? | Prefilled fields that the shopper can edit. When null or empty, prefilled fields are read-only. Possible values:
|
fieldConfig.labelStylesFieldLabelStateStyles? | Label styles for the base, valid, and invalid states. |
fieldConfig.inputStylesFieldInputStateStyles? | Input styles for the base, valid, and invalid states. |
fieldConfig.invalidTextStyleFieldMessageStyle? | Styles for validation messages. |
fieldConfig.phoneNumberGuideTextStyleFieldMessageStyle? | Styles for the phone number guidance text. |
buttonStylesButtonStateStyles? | Styles for the screen's action button. |
Fields returned by onGetShopper are disabled by default. Add a field to editableFields if the shopper needs to change its value.
Use otpVerificationConfig to customise the OTP inputs, validation message, and action button:
config.otpVerificationConfig = OtpVerificationConfig(
inputStyles = FieldInputStateStyles(
base = FieldInputStyle(
borderColor = Color.Gray,
cornerRadius = 8.dp,
),
active = FieldInputStyle(
borderColor = Color.Blue,
borderWidth = 2.dp,
),
invalid = FieldInputStyle(borderColor = Color.Red),
),
invalidTextStyles = FieldMessageStyle(color = Color(0xFFD32F2F)),
buttonStyles = ButtonStateStyles(
base = FieldStyle(backgroundColor = Color(0xFF2F3BFF)),
),
)Configure the OTP verification screen with these properties:
| Property | Description |
|---|---|
inputStylesFieldInputStateStyles? | Styles for each OTP input in the base, active, and invalid states. |
invalidTextStylesFieldMessageStyle? | Styles for the validation message below the OTP inputs. |
buttonStylesButtonStateStyles? | Styles for the verification button. |
Use bankSelectionConfig to customise bank selection and the embedded Aerosync experience:
config.bankSelectionConfig = BankSelectionConfig(
payButtonStyles = ButtonStateStyles(
base = FieldStyle(backgroundColor = Color(0xFF2F3BFF)),
),
linkBankButtonStyles = ButtonStateStyles(
base = FieldStyle(
backgroundColor = Color.White,
color = Color(0xFF2F3BFF),
),
),
bankSelectedIndicatorColor = Color(0xFF2F3BFF),
bankItemStyles = BankItemStateStyles(
base = BankItemStyle(
bankNameStyle = BankItemTextStyle(fontSize = 16f),
),
selected = BankItemStyle(
containerStyle = BankItemContainerStyle(
backgroundColor = Color(0xFFDBEDFA),
),
),
),
excludedBankAccountIds = listOf(1895986, 1895988),
allowLinkBankOnPayout = false,
aerosyncTheme = AerosyncTheme.LIGHT,
)Configure the bank selection screen with these properties:
| Property | Description |
|---|---|
payButtonStylesButtonStateStyles? | Styles for the pay or withdraw button. |
linkBankButtonStylesButtonStateStyles? | Styles for the link-bank button. |
bankSelectedIndicatorColorColor? | Accent colour for the selected-bank indicator. When bankItemStyles isn't set, the SDK can derive bank item styles from this colour. |
bankItemStylesBankItemStateStyles? | Styles for funding bank list items in the base and selected states. |
excludedBankAccountIdsList<Number>? | Bank account IDs to hide from the linked-banks list (e.g., listOf(1895986, 1895988)). When omitted or empty, all linked accounts are shown. |
allowLinkBankOnPayoutBoolean | Whether to show the link-bank button for Payout transactions. Defaults to false. |
aerosyncThemeAerosyncTheme? | Theme for the embedded Aerosync widget. Use AerosyncTheme.LIGHT or AerosyncTheme.DARK. When omitted, the SDK resolves light theme. |
The top-level styles property and each screen's button style property use ButtonStateStyles:
val buttonStyles = ButtonStateStyles(
base = FieldStyle(
backgroundColor = Color(0xFF2F3BFF),
color = Color.White,
cornerRadius = 8.dp,
padding = PaddingValues(horizontal = 16.dp, vertical = 14.dp),
),
disabled = FieldStyle(
backgroundColor = Color(0xFF2F3BFF).copy(alpha = 0.5f),
),
)Configure button states with these properties:
| Property | Description |
|---|---|
baseFieldStyle? | Styles for the default state. |
disabledFieldStyle? | Styles applied when the button is disabled. |
loadingFieldStyle? | Styles applied while the button is in a loading state. |
Configure callbacks on the component to respond to shopper actions, validation, verification, transaction submission, and errors:
val config = AeropayButtonComponentConfig().apply {
onClick = {
clearPaymentErrors()
}
onCustomValidation = {
// Must return Boolean; e.g. a ready-state flag or a function that returns Boolean
checkoutReady
}
onUserVerificationSuccess = { user ->
saveAeropayUserId(user.id)
}
onCancel = {
resetCheckoutState()
}
onPreAuthorisation = { true }
onPostAuthorisation = { result ->
verifyPaymentOnBackend(result)
}
onSubmitError = { error ->
// Handle FailedSubmitResult from transaction submission
}
onError = { error ->
// Handle BaseSdkException from the Aeropay flow
}
}The component supports these callbacks:
| Callback | Description |
|---|---|
onClick() -> Unit | Called when the shopper taps the Aeropay button, before custom validation and popup opening. |
onCustomValidationsuspend () -> Boolean | Called after onClick. Return true to continue or false to stop before the Aeropay flow starts. |
onUserVerificationSuccess(AeropayUser) -> Unit | Called after OTP verification succeeds. Store user.id for returning-shopper flows. |
onCancel() -> Unit | Called when the shopper dismisses the popup. Programmatic dismissal after a successful payment doesn't invoke it. |
onPreAuthorisationsuspend () -> Boolean | Called before transaction submission. Return true to submit, or false to stop. If the callback is omitted, submission doesn't proceed and the popup stays open. |
onPostAuthorisation(MerchantSubmitResult) -> Unit | Called after the transaction is submitted successfully. |
onSubmitError(BaseSubmitResult) -> Unit | Called when transaction submission fails. At runtime, failed responses typically use FailedSubmitResult. |
onError(BaseSdkException) -> Unit | Called when an SDK or provider error occurs during the Aeropay flow outside successful or failed transaction submission. |
For callback payloads and handling guidance, see Events.
Render the Aeropay button in your Compose UI:
aeropayButton.Content(modifier = Modifier.fillMaxWidth())Create the component through checkout.createComponent(ComponentType.AERO_PAY_BUTTON, config). Direct instantiation isn't supported.