Learn about how to configure PayPal payout components for Android.
The PayPal Android SDK provides configurable components for integrating PayPal payouts into your Android application. Each component is built with Jetpack Compose and offers comprehensive configuration options for styling, behaviour, and event handling.
All payout components follow a consistent configuration pattern:
// Create component with configuration
val config = ComponentConfig(
// Required properties
requiredProperty = value,
// Optional properties
optionalProperty = value,
// Styling
style = StyleConfig(),
// Event handlers
onEvent = { data ->
// Handle event
}
)
val component = pxpCheckout.createComponent(
type = ComponentType.COMPONENT_NAME,
config = config
)
// Render with Compose
pxpCheckout.buildComponentView(
component = component,
modifier = Modifier.fillMaxWidth()
)Authentication and environment are configured at SDK initialisation via PxpCheckout.builder(), not at the component level.
At minimum, each component requires a few essential properties:
import com.pxp.checkout.components.payoutamount.PayoutAmountComponentConfig
import com.pxp.checkout.components.paypalpayoutreceiver.PaypalPayoutReceiverComponentConfig
import com.pxp.checkout.components.payoutsubmission.PayoutSubmissionComponentConfig
import com.pxp.checkout.types.ComponentType
// Payout amount component (display only)
val amountConfig = PayoutAmountComponentConfig(
label = "Withdrawal Amount"
)
// PayPal receiver component (display only)
val receiverConfig = PaypalPayoutReceiverComponentConfig(
label = "PayPal Account",
showMaskToggle = true
)
// Payout submission component
val submitConfig = PayoutSubmissionComponentConfig(
recipientWallet = "Paypal",
buttonText = "Withdraw with"
)For more complex implementations, you can configure styling, callbacks, and additional features:
import com.pxp.checkout.components.payoutsubmission.PayoutSubmissionComponentConfig
import com.pxp.checkout.models.payout.PrePayoutSubmitResult
val submitConfig = PayoutSubmissionComponentConfig(
// Required
recipientWallet = "Paypal",
// Custom button text
buttonText = "Withdraw Funds",
// Styling for different states
style = PayoutSubmissionStyle(
// Custom styling options
),
// Event handlers
onClick = {
Log.d("Payout", "Button tapped")
},
onPrePayoutSubmit = {
val confirmed = showConfirmationDialog()
PrePayoutSubmitResult(
isApproved = confirmed
)
},
onPostPayout = { result ->
handlePayoutSuccess(result)
},
onError = { error ->
handlePayoutError(error)
}
)All components come with PayPal-branded default styling:
- Payout amount: Standard read-only display with customisable label.
- Receiver display: Read-only field with optional masking and toggle.
- Submission button (PayPal): Gold button with PayPal branding, customisable text.
Each component offers comprehensive styling options using Compose styling:
import com.pxp.checkout.components.payoutamount.PayoutAmountStyle
import com.pxp.checkout.components.payoutamount.PayoutAmountComponentConfig
// Amount component styling
val amountConfig = PayoutAmountComponentConfig(
label = "Withdrawal Amount",
style = PayoutAmountStyle(
// Add your custom styling properties here
)
)
// Receiver component styling
val receiverConfig = PaypalPayoutReceiverComponentConfig(
label = "PayPal Email",
showMaskToggle = true,
applyMask = true,
style = PaypalPayoutReceiverStyle(
// Add your custom styling properties here
)
)All components provide event handlers for user interactions and lifecycle events. For a full list of supported callbacks and their payloads, see Events.
| Pattern | Description | Example callbacks |
|---|---|---|
| Tap handlers | Called when user taps. | onClick |
| Pre-action handlers | Called before processing, can approve/reject. | onPrePayoutSubmit |
| Success handlers | Called when operations complete. | onPostPayout, onAccountVerified |
| Error handlers | Called when errors occur. | onError |
| Cancel handlers | Called when user cancels. | onCancel |
val submitConfig = PayoutSubmissionComponentConfig(
recipientWallet = "Paypal",
// Tap handling (before validation)
onClick = {
Log.d("Payout", "Withdrawal button tapped")
showLoadingState()
},
// Pre-payout approval (can approve/reject)
onPrePayoutSubmit = {
val confirmed = showConfirmationDialog()
PrePayoutSubmitResult(
isApproved = confirmed
)
},
// Success handling
onPostPayout = { result ->
Log.d("Payout", "Payout successful: ${result.systemTransactionId}")
navigateToSuccessScreen(result.merchantTransactionId)
},
// Error handling
onError = { error ->
Log.e("Payout", "Payout failed: ${error.errorReason}")
showErrorMessage(error.errorReason)
}
)Unlike web components that mount to DOM elements, Android components are rendered using Jetpack Compose:
@Composable
fun PayoutScreen() {
// Create component
val amountComponent = remember {
pxpCheckout.createComponent(
type = ComponentType.PAYOUT_AMOUNT,
config = PayoutAmountComponentConfig(
label = "Amount"
)
)
}
// Render component
pxpCheckout.buildComponentView(
component = amountComponent,
modifier = Modifier.fillMaxWidth()
)
}@Composable
fun PayoutForm() {
val amountComponent = remember { createAmountComponent() }
val receiverComponent = remember { createReceiverComponent() }
val submitComponent = remember { createSubmitComponent() }
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
pxpCheckout.buildComponentView(
component = amountComponent,
modifier = Modifier.fillMaxWidth()
)
pxpCheckout.buildComponentView(
component = receiverComponent,
modifier = Modifier.fillMaxWidth()
)
pxpCheckout.buildComponentView(
component = submitComponent,
modifier = Modifier.fillMaxWidth()
)
}
}Customise the styling to match your app's design:
// Define brand styles
object BrandStyles {
val primary = Color(0xFF0066CC)
val surface = Color(0xFFF8F9FA)
val onSurface = Color(0xFF212529)
val accent = Color(0xFFFFC438)
}
// Apply to components
val submitConfig = PayoutSubmissionComponentConfig(
recipientWallet = "Paypal",
style = PayoutSubmissionStyle(
// Apply your brand styling
)
)Implement comprehensive event handling:
val submitConfig = PayoutSubmissionComponentConfig(
recipientWallet = "Paypal",
onClick = { handleTap() },
onPrePayoutSubmit = { handlePreSubmit() },
onPostPayout = { result -> handleSuccess(result) },
onError = { error -> handleError(error) }
)For more information about events, see Events.
Components are automatically cleaned up by Compose when they leave the composition. However, you can explicitly handle cleanup if needed:
@Composable
fun PayoutScreen() {
val component = remember { createComponent() }
// Automatic cleanup with DisposableEffect
DisposableEffect(component) {
onDispose {
// Component resources are cleaned up automatically
Log.d("Payout", "Component disposed")
}
}
pxpCheckout.buildComponentView(component)
}Test your components in various scenarios:
- Light and dark themes.
- Different screen sizes and orientations.
- Various payout amounts and currencies.
- Error conditions.
- Network failures.
Here's a comprehensive example showing all configuration options:
import com.pxp.checkout.PxpCheckout
import com.pxp.checkout.models.*
import com.pxp.checkout.components.payoutamount.PayoutAmountComponentConfig
import com.pxp.checkout.components.paypalpayoutreceiver.PaypalPayoutReceiverComponentConfig
import com.pxp.checkout.components.payoutsubmission.PayoutSubmissionComponentConfig
import com.pxp.checkout.models.payout.PrePayoutSubmitResult
import com.pxp.checkout.types.ComponentType
import java.util.UUID
// Initialise SDK
val pxpCheckout = PxpCheckout.builder()
.withConfig(
PxpSdkConfig(
environment = Environment.TEST,
session = sessionData,
ownerId = "Unity",
ownerType = "MerchantGroup",
clientId = "your-client-id",
transactionData = TransactionData(
amount = 100.0,
currency = "USD",
merchant = "your-merchant-id",
entryType = EntryType.Ecom,
intent = TransactionIntentData(paypal = IntentType.Payout),
merchantTransactionId = UUID.randomUUID().toString(),
merchantTransactionDate = { System.currentTimeMillis() }
),
paypalConfig = PaypalConfig(
payout = PayoutConfig(
proceedPayoutWithSdk = true,
paypalWallet = PayPalPayOutWalletConfig(
email = "customer@example.com",
payerId = "PAYER123456"
)
)
)
)
)
.withContext(context)
.build()
// Create amount component with full configuration
val amountComponent = pxpCheckout.createComponent(
type = ComponentType.PAYOUT_AMOUNT,
config = PayoutAmountComponentConfig(
label = "Withdrawal Amount",
style = PayoutAmountStyle(
// Custom styling
)
)
)
// Create receiver component with full configuration
val receiverComponent = pxpCheckout.createComponent(
type = ComponentType.PAYPAL_PAYOUT_RECEIVER,
config = PaypalPayoutReceiverComponentConfig(
label = "PayPal Email",
showMaskToggle = true,
applyMask = true,
style = PaypalPayoutReceiverStyle(
// Custom styling
)
)
)
// Create submission component with full configuration
val submitComponent = pxpCheckout.createComponent(
type = ComponentType.PAYOUT_SUBMISSION,
config = PayoutSubmissionComponentConfig(
// Required
recipientWallet = "Paypal",
// Button text
buttonText = "Withdraw to PayPal",
// Full styling
style = PayoutSubmissionStyle(
// Custom styling
),
// Event handlers
onClick = {
Log.d("Payout", "Button tapped")
trackEvent("payout_button_tapped")
},
onPrePayoutSubmit = {
Log.d("Payout", "Pre-payout check")
// Show confirmation modal
val confirmed = showConfirmationDialog(
title = "Confirm Withdrawal",
message = "Are you sure you want to withdraw $100.00 to your PayPal account?"
)
if (!confirmed) {
PrePayoutSubmitResult(isApproved = false)
} else {
// Perform validation
val validation = validateWithdrawal()
if (!validation.valid) {
showErrorMessage(validation.message)
PrePayoutSubmitResult(isApproved = false)
} else {
PrePayoutSubmitResult(isApproved = true)
}
}
},
onPostPayout = { result ->
Log.d("Payout", "Payout successful: ${result.systemTransactionId}")
// Track success
trackEvent("payout_completed", mapOf(
"transactionId" to result.systemTransactionId,
"amount" to 100.0
))
// Redirect
navigateToSuccessScreen(result.merchantTransactionId)
},
onError = { error ->
Log.e("Payout", "Payout error: ${error.errorReason}")
// Log error
logError("payout_error", mapOf(
"code" to error.errorCode,
"message" to error.errorReason
))
// Show error message
showErrorMessage("Withdrawal failed. Please try again.")
}
)
)
// Render components
@Composable
fun PayoutScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
pxpCheckout.buildComponentView(
component = amountComponent,
modifier = Modifier.fillMaxWidth()
)
pxpCheckout.buildComponentView(
component = receiverComponent,
modifier = Modifier.fillMaxWidth()
)
pxpCheckout.buildComponentView(
component = submitComponent,
modifier = Modifier.fillMaxWidth()
)
}
}Now that you understand component configuration fundamentals, dive into the detailed documentation for each component:
- Amount component: Configure the payout amount display.
- PayPal receiver component: Display and configure PayPal receiver.
- Submission component: Configure the withdrawal button for returning customers.