Skip to content

About configuration

Learn about how to configure PayPal payout components for Android.

Overview

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.

Configuration structure

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.

Basic configuration

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"
)

Advanced configuration

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)
    }
)

Styling components

Default styling

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.

Custom styling

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
    )
)

Event handling

All components provide event handlers for user interactions and lifecycle events. For a full list of supported callbacks and their payloads, see Events.

Common event patterns

PatternDescriptionExample callbacks
Tap handlersCalled when user taps.onClick
Pre-action handlersCalled before processing, can approve/reject.onPrePayoutSubmit
Success handlersCalled when operations complete.onPostPayout, onAccountVerified
Error handlersCalled when errors occur.onError
Cancel handlersCalled when user cancels.onCancel

Submission component events

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)
    }
)

Component rendering

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()
    )
}

Compose integration

@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()
        )
    }
}

Best practices

Configure for your brand

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
    )
)

Handle all events

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.

Clean up components

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 different configurations

Test your components in various scenarios:

  • Light and dark themes.
  • Different screen sizes and orientations.
  • Various payout amounts and currencies.
  • Error conditions.
  • Network failures.

Complete configuration example

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()
        )
    }
}

Next steps

Now that you understand component configuration fundamentals, dive into the detailed documentation for each component: