Skip to content

Pre-built PayPal component

Learn about how to configure the composite pre-built PayPal component.

Basic usage

Minimal configuration

At minimum, the pre-built PayPal component requires the following configuration to function:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    paypalConfig = PayPalComponentConfig(
        renderType = "standalone",
        fundingSources = "paypal",
        shippingPreference = "NoShipping",
        userAction = "PayNow"
    )
)
PropertyDescription
paypalConfig
PayPalComponentConfig
required
Configuration for the PayPal component. Controls the PayPal button's appearance and behaviour. See PayPal component.

Advanced configuration

For more complex implementations, you can configure additional components and settings:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    // PayPal button configuration
    paypalConfig = PayPalComponentConfig(
        renderType = "standalone",
        fundingSources = "paypal",
        shippingPreference = "NoShipping",
        userAction = "PayNow",
        payeeEmailAddress = "merchant@example.com",
        paymentDescription = "Premium subscription",
        enableOneClickPayment = true,
        style = PayPalButtonStyle(
            layout = "horizontal",
            color = "blue",
            shape = "rect",
            height = 48,
            label = "pay"
        )
    ),
    
    // Toggle component configuration
    toggleConfig = ToggleComponentConfig(
        label = "Use a different PayPal account",
        initialChecked = false,
        toggleStyle = ToggleVisualStyle(
            activeTrackColor = Color(0xFF0070BA),
            inactiveTrackColor = Color(0xFFE5E5E5)
        )
    ),
    
    // Layout configuration
    layoutMode = PreBuiltPayPalLayoutMode.VERTICAL
)
PropertyDescription
toggleConfig
ToggleComponentConfig?
Configuration for the toggle component. Controls the toggle switch for payment method switching. See Toggle component. Defaults to null.
layoutMode
PreBuiltPayPalLayoutMode
The component layout orientation. Defaults to PreBuiltPayPalLayoutMode.VERTICAL.

Possible values:
  • VERTICAL: Stacked layout

The pre-built component automatically links the PayPal button with the toggle component, handling the one-click payment flow for you.

Styling

Default styling

The pre-built PayPal component renders with these default styles:

style = PreBuiltPayPalStyle(
    colorStyles = PreBuiltPayPalStyle.ColorStyles(
        backgroundColor = PxpThemeValues.Colors.surfaceColor,
        containerBackgroundColor = PxpThemeValues.Colors.surfaceColor,
        textColor = PxpThemeValues.Colors.onSurfaceColor
    ),
    layoutStyles = PreBuiltPayPalStyle.LayoutStyles(
        containerPadding = 16.dp,
        spacingBetweenElements = 16.dp
    ),
    componentStyles = PreBuiltPayPalStyle.ComponentStyles(
        containerShape = RoundedCornerShape(8.dp)
    )
)

The pre-built component inherits PayPal button styling from the PayPal component configuration and adds container-specific styling options.

Custom styling

You can override the default appearance by providing custom styles for the container:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    paypalConfig = paypalConfig,
    toggleConfig = toggleConfig,
    
    style = PreBuiltPayPalStyle(
        // Color styles
        colorStyles = PreBuiltPayPalStyle.ColorStyles(
            backgroundColor = Color.White,
            containerBackgroundColor = Color(0xFFF8F9FA),
            textColor = Color(0xFF212529)
        ),
        
        // Text styles
        textStyles = PreBuiltPayPalStyle.TextStyles(
            textStyle = TextStyle(
                fontSize = 14.sp,
                fontWeight = FontWeight.Normal,
                color = Color(0xFF495057)
            ),
            labelTextStyle = TextStyle(
                fontSize = 12.sp,
                fontWeight = FontWeight.Medium,
                color = Color(0xFF6C757D)
            )
        ),
        
        // Layout styles
        layoutStyles = PreBuiltPayPalStyle.LayoutStyles(
            containerPadding = 20.dp,
            spacingBetweenElements = 16.dp
        ),
        
        // Component styles
        componentStyles = PreBuiltPayPalStyle.ComponentStyles(
            containerShape = RoundedCornerShape(12.dp),
            borderWidth = 1.dp,
            borderColor = Color(0xFFDEE2E6),
            elevation = 4.dp
        )
    )
)
PropertyDescription
style
PreBuiltPayPalStyle?
Custom styling configuration for the pre-built component container. Defaults to null.
style.colorStyles
ColorStyles
Colour-related style configuration.
style.colorStyles.backgroundColor
Color
The main background colour of the component. Defaults to the theme's surface colour.
style.colorStyles.containerBackgroundColor
Color
The background colour of the container. Defaults to the theme surface colour.
style.colorStyles.textColor
Color
The primary text colour. Defaults to the theme's onSurface colour.
style.textStyles
TextStyles
Text-related style configuration.
style.textStyles.textStyle
TextStyle
The text style for body text. Defaults to the default text style.
style.textStyles.labelTextStyle
TextStyle
The text style for labels. Defaults to the default label style.
style.layoutStyles
LayoutStyles
Layout-related style configuration.
style.layoutStyles.containerPadding
Dp
The padding around the container. Defaults to 16.dp.
style.layoutStyles.spacingBetweenElements
Dp
The spacing between child components (toggle and PayPal button). Defaults to 16.dp.
style.componentStyles
ComponentStyles
Component-related style configuration.
style.componentStyles.containerShape
Shape
The shape of the container (corners). Defaults to RoundedCornerShape(8.dp).
style.componentStyles.borderWidth
Dp
The width of the container border. Defaults to 0.dp.
style.componentStyles.borderColor
Color
The colour of the container border. Defaults to transparent.
style.componentStyles.elevation
Dp
The elevation/shadow of the container. Defaults to 0.dp.

Event handling

The pre-built PayPal component provides event handlers through its child components:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    paypalConfig = PayPalComponentConfig(
        // PayPal event handlers
        onSuccess = { data: String -> },
        onError = { error: String -> },
        onCancel = { -> },
        onShippingAddressChange = { data: String -> String? },
        onShippingOptionsChange = { data: String -> String? },
        onOrderCreated = { orderData: String -> },
        onSubmitError = { error: String -> },
        onScriptLoaded = { -> },
        onGetConsent = { -> Boolean }
    ),
    toggleConfig = ToggleComponentConfig(
        // Toggle event handler
        onToggleChanged = { isChecked: Boolean -> }
    )
)

PayPal event handlers

CallbackDescription
onSuccess: ((String) -> Unit)?Event handler for when the PayPal payment succeeds with payment approval data.
onError: ((String) -> Unit)?Event handler for when the PayPal payment encounters an error.
onCancel: (() -> Unit)?Event handler for when the user cancels the PayPal payment flow.
onShippingAddressChange: ((String) -> String?)?Event handler for when the shipping address changes in the PayPal checkout.
onShippingOptionsChange: ((String) -> String?)?Event handler for when shipping options change in PayPal checkout.
onOrderCreated: ((String) -> Unit)?Event handler for when the PayPal order is successfully created.
onSubmitError: ((String) -> Unit)?Event handler for when order creation or submission fails.
onScriptLoaded: (() -> Unit)?Event handler for when the PayPal SDK script loads successfully.
onGetConsent: (() -> Boolean)?Event handler to get user consent for vaulting their PayPal account.

Toggle event handler

CallbackDescription
onToggleChanged: ((Boolean) -> Unit)?Event handler for when the toggle's state changes for payment method switching.

For detailed information about event data structures and usage patterns, see Events.

Methods

The pre-built PayPal component provides methods for lifecycle management.

Content()

Renders the pre-built component in Jetpack Compose:

@Composable
fun PaymentScreen() {
    val prebuiltComponent = remember {
        pxpCheckout.createComponent(
            type = ComponentType.PREBUILT_PAYPAL,
            config = prebuiltConfig
        )
    }
    
    pxpCheckout.buildComponentView(
        component = prebuiltComponent,
        modifier = Modifier.fillMaxWidth()
    )
}

getValue()

Retrieves the current component state:

val componentValue = prebuiltComponent.getValue()

Examples

Basic pre-built component

A straightforward implementation with essential configuration:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    paypalConfig = PayPalComponentConfig(
        renderType = "standalone",
        fundingSources = "paypal",
        shippingPreference = "NoShipping",
        userAction = "PayNow",
        payeeEmailAddress = "merchant@example.com",
        paymentDescription = "Product purchase",
        enableOneClickPayment = false,
        
        onSuccess = { data ->
            val jsonObject = JSONObject(data)
            val orderID = jsonObject.getString("orderID")
            Log.d("PreBuilt", "Payment successful: $orderID")
            navigateToSuccessScreen(orderID)
        },
        
        onError = { error ->
            Log.e("PreBuilt", "Payment failed: $error")
            showErrorMessage("Payment failed. Please try again.")
        }
    )
)

Pre-built with one-click payment

Implementation with toggle for returning customers:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    // PayPal configuration
    paypalConfig = PayPalComponentConfig(
        renderType = "standalone",
        fundingSources = "paypal",
        shippingPreference = "NoShipping",
        userAction = "PayNow",
        payeeEmailAddress = "merchant@example.com",
        paymentDescription = "Order payment",
        enableOneClickPayment = true,
        scriptParams = PayPalScriptParams(
            userIdToken = getUserIdToken()
        ),
        style = PayPalButtonStyle(
            layout = "horizontal",
            color = "blue",
            shape = "rect",
            height = 48,
            label = "pay"
        ),
        
        onSuccess = { data ->
            handlePaymentSuccess(data)
        },
        
        onError = { error ->
            handlePaymentError(error)
        }
    ),
    
    // Toggle configuration
    toggleConfig = ToggleComponentConfig(
        label = "Use a different PayPal account",
        initialChecked = false,
        labelStyle = ToggleLabelStyle(
            color = Color(0xFF0070BA),
            fontSizeSp = 14f,
            fontWeight = FontWeight.Medium
        ),
        toggleStyle = ToggleVisualStyle(
            activeTrackColor = Color(0xFF0070BA),
            inactiveTrackColor = Color(0xFFE5E5E5)
        ),
        
        onToggleChanged = { isChecked ->
            Log.d("PreBuilt", "Toggle changed: $isChecked")
            if (isChecked) {
                trackAnalyticsEvent("change_payment_method")
            }
        }
    ),
    
    layoutMode = PreBuiltPayPalLayoutMode.VERTICAL
)

Enterprise pre-built with full customisation

A comprehensive implementation with custom styling and complete event handling:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    // PayPal configuration
    paypalConfig = PayPalComponentConfig(
        renderType = "standalone",
        fundingSources = "paypal",
        shippingPreference = "NoShipping",
        userAction = "PayNow",
        payeeEmailAddress = "enterprise@example.com",
        paymentDescription = "Enterprise subscription",
        enableOneClickPayment = true,
        
        scriptParams = PayPalScriptParams(
            userIdToken = getUserIdToken(),
            clientToken = getClientToken(),
            pageType = "checkout"
        ),
        
        style = PayPalButtonStyle(
            layout = "horizontal",
            color = "blue",
            shape = "pill",
            height = 48,
            borderRadius = 24,
            label = "buynow"
        ),
        
        queryParams = PayPalQueryParams(
            debug = BuildConfig.DEBUG,
            integrationDate = "2025-07-01"
        ),
        
        componentLayoutConfig = PayPalComponentLayoutConfig(
            minHeightPercent = 0.1f,
            maxHeightPercent = 0.8f
        ),
        
        onScriptLoaded = {
            Log.d("PreBuilt", "PayPal SDK loaded")
            hideLoadingIndicator()
        },
        
        onOrderCreated = { orderId ->
            Log.d("PreBuilt", "Order created: $orderId")
            trackAnalyticsEvent("order_created", mapOf("orderId" to orderId))
        },
        
        onSuccess = { data ->
            hideLoadingIndicator()
            
            val jsonObject = JSONObject(data)
            val orderID = jsonObject.getString("orderID")
            val payerID = jsonObject.getString("payerID")
            
            trackAnalyticsEvent("payment_success", mapOf(
                "orderId" to orderID,
                "payerId" to payerID,
                "method" to "prebuilt_paypal"
            ))
            
            showPaymentSuccessMessage()
            setTimeout({
                navigateToSuccessScreen(orderID)
            }, 2000)
        },
        
        onError = { error ->
            hideLoadingIndicator()
            
            val errorMessage = when {
                error.contains("SDK") -> "Failed to load PayPal. Check connection."
                error.contains("transaction") -> "Payment processing error."
                else -> "Payment error: $error"
            }
            
            Log.e("PreBuilt", "Payment error: $error")
            trackAnalyticsEvent("payment_error", mapOf("error" to error))
            showErrorDialog(errorMessage)
        },
        
        onCancel = {
            Log.d("PreBuilt", "Payment cancelled")
            trackAnalyticsEvent("payment_cancelled")
            showMessage("Payment was cancelled.")
        }
    ),
    
    // Toggle configuration
    toggleConfig = ToggleComponentConfig(
        label = "Change preferred payment method",
        initialChecked = false,
        
        labelStyle = ToggleLabelStyle(
            color = Color(0xFF212529),
            fontSizeSp = 15f,
            fontWeight = FontWeight.SemiBold,
            position = LabelPosition.START,
            spacing = 16.dp
        ),
        
        toggleStyle = ToggleVisualStyle(
            width = 54.dp,
            height = 32.dp,
            borderWidth = 2.dp,
            borderColor = Color(0xFFDEE2E6),
            borderRadius = 16.dp,
            activeTrackColor = Color(0xFF0070BA),
            inactiveTrackColor = Color(0xFFE9ECEF),
            activeThumbColor = Color.White,
            inactiveThumbColor = Color(0xFF6C757D)
        ),
        
        onToggleChanged = { isChecked ->
            Log.d("PreBuilt", "Toggle state: $isChecked")
            
            trackAnalyticsEvent("toggle_payment_method", mapOf(
                "action" to if (isChecked) "change" else "use_saved"
            ))
            
            if (isChecked) {
                showPaymentMethodChangeFlow()
            } else {
                useVaultedPaymentMethod()
            }
        }
    ),
    
    // Container styling
    style = PreBuiltPayPalStyle(
        colorStyles = PreBuiltPayPalStyle.ColorStyles(
            backgroundColor = Color.White,
            containerBackgroundColor = Color(0xFFF8F9FA),
            textColor = Color(0xFF212529)
        ),
        
        textStyles = PreBuiltPayPalStyle.TextStyles(
            textStyle = TextStyle(
                fontSize = 14.sp,
                fontWeight = FontWeight.Normal,
                color = Color(0xFF495057)
            ),
            labelTextStyle = TextStyle(
                fontSize = 12.sp,
                fontWeight = FontWeight.Medium,
                color = Color(0xFF6C757D)
            )
        ),
        
        layoutStyles = PreBuiltPayPalStyle.LayoutStyles(
            containerPadding = 24.dp,
            spacingBetweenElements = 20.dp
        ),
        
        componentStyles = PreBuiltPayPalStyle.ComponentStyles(
            containerShape = RoundedCornerShape(16.dp),
            borderWidth = 1.dp,
            borderColor = Color(0xFFDEE2E6),
            elevation = 4.dp
        )
    ),
    
    layoutMode = PreBuiltPayPalLayoutMode.VERTICAL
)

Pre-built with multiple funding sources

Implementation supporting PayPal and Pay Later:

val prebuiltConfig = PreBuiltPayPalComponentConfig(
    paypalConfig = PayPalComponentConfig(
        renderType = "setOfButtons",
        fundingSources = listOf("paypal", "paylater"),
        shippingPreference = "NoShipping",
        userAction = "PayNow",
        payeeEmailAddress = "merchant@example.com",
        paymentDescription = "Product purchase",
        
        style = PayPalButtonStyle(
            layout = "vertical",
            color = "gold",
            shape = "rect",
            height = 45
        ),
        
        message = PayPalMessage(
            amount = 299.99,
            align = "center",
            color = "black",
            position = "bottom"
        ),
        
        onSuccess = { data ->
            val jsonObject = JSONObject(data)
            val orderID = jsonObject.getString("orderID")
            val paymentSource = jsonObject.optString("paymentSource", "paypal")
            
            Log.d("PreBuilt", "Payment via $paymentSource: $orderID")
            trackAnalyticsEvent("payment_success", mapOf(
                "source" to paymentSource,
                "orderId" to orderID
            ))
            navigateToSuccessScreen(orderID)
        }
    ),
    
    style = PreBuiltPayPalStyle(
        layoutStyles = PreBuiltPayPalStyle.LayoutStyles(
            containerPadding = 16.dp,
            spacingBetweenElements = 12.dp
        )
    )
)

Dynamic pre-built component

Example showing conditional toggle based on vault status:

@Composable
fun DynamicPreBuiltPayPal() {
    var hasVaultedAccount by remember { mutableStateOf(false) }
    
    LaunchedEffect(Unit) {
        hasVaultedAccount = checkVaultStatus()
    }
    
    val prebuiltConfig = remember(hasVaultedAccount) {
        PreBuiltPayPalComponentConfig(
            paypalConfig = PayPalComponentConfig(
                renderType = "standalone",
                fundingSources = "paypal",
                shippingPreference = "NoShipping",
                userAction = "PayNow",
                enableOneClickPayment = hasVaultedAccount,
                scriptParams = if (hasVaultedAccount) {
                    PayPalScriptParams(userIdToken = getUserIdToken())
                } else null,
                onSuccess = { handlePaymentSuccess(it) }
            ),
            toggleConfig = if (hasVaultedAccount) {
                ToggleComponentConfig(
                    label = "Use different PayPal account",
                    onToggleChanged = { handleToggleChange(it) }
                )
            } else null
        )
    }
    
    val prebuiltComponent = remember(prebuiltConfig) {
        pxpCheckout.createComponent(
            type = ComponentType.PREBUILT_PAYPAL,
            config = prebuiltConfig
        )
    }
    
    pxpCheckout.buildComponentView(
        component = prebuiltComponent,
        modifier = Modifier.fillMaxWidth()
    )
}