Skip to content

PayPal component

Learn about how to configure the PayPal payment button component.

Basic usage

Minimal configuration

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

val paypalConfig = PayPalComponentConfig(
    renderType = "standalone",
    fundingSources = "paypal",
    shippingPreference = "NoShipping",
    userAction = "PayNow"
)
PropertyDescription
renderType
String
required
The type of button to render. Defaults to standalone.

Possible values:
  • standalone: A single button
  • setOfButtons: Multiple buttons for different funding sources
fundingSources
Any?
required
The payment method(s) to support. The type depends on the renderType: String for standalone (e.g., paypal), List<String> for setOfButtons (e.g., listOf("paypal", "paylater")).

Possible values:
  • paypal: Standard PayPal payments
  • paylater: PayPal Pay Later financing
shippingPreference
String
required
The shipping details to use. Defaults to NoShipping.

Possible values:
  • NoShipping: No shipping address required
  • GetFromFile: Get the shipping address from the PayPal account
  • SetProvidedAddress: Use the provided shipping address
userAction
String
required
The next step in the payment flow. Defaults to PayNow.

Possible values:
  • PayNow: Immediate payment capture
  • Continue: Continue to PayPal for payment

Advanced configuration

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

val paypalConfig = PayPalComponentConfig(
    // Required configuration
    renderType = "standalone",
    fundingSources = "paypal",
    shippingPreference = "NoShipping",
    userAction = "PayNow",
    
    // Payment details
    payeeEmailAddress = "merchant@example.com",
    paymentDescription = "Premium subscription",
    
    // Shipping configuration
    shippingOptions = listOf(
        ShippingOption(
            id = "1",
            label = "Standard Shipping",
            selected = true,
            amounts = ShippingAmounts(
                currencyCode = "USD",
                shipping = 5.99
            )
        )
    ),
    
    // One-click payment configuration
    enableOneClickPayment = true,
    scriptParams = PayPalScriptParams(
        userIdToken = "YOUR_USER_ID_TOKEN"
    ),
    
    // Component linking
    toggleComponent = toggleComponent,
    consentComponent = consentComponent,
    
    // Localisation
    locale = "en-US",
    
    // Query parameters
    queryParams = PayPalQueryParams(
        buyerCountry = "US",
        debug = false,
        integrationDate = "2025-07-01"
    ),
    
    // Layout configuration
    componentLayoutConfig = PayPalComponentLayoutConfig(
        minHeightPercent = 0.1f,
        maxHeightPercent = 0.6f
    )
)
PropertyDescription
payeeEmailAddress
String?
Your email address. Defaults to empty string.
paymentDescription
String?
A description of the payment. Defaults to empty string.
shippingOptions
List<ShippingOption>?
Details about the shipping options. Provide this only when shippingPreference is GetFromFile. Defaults to null.
enableOneClickPayment
Boolean
Whether to enable one-click payment with vaulting. Defaults to true.
scriptParams
PayPalScriptParams?
Optional script parameters including userIdToken for one-click payments. Defaults to null.
scriptParams.userIdToken
String?
Your user ID token. Required for one-click payment functionality. Defaults to null.
toggleComponent
ToggleComponent?
Toggle component for payment method switching. Defaults to null. See Toggle component.
consentComponent
PayPalConsentComponent?
Consent component for vaulting agreement. Defaults to null. See Consent component.
locale
String
The language and region for PayPal interface (e.g., en-US, fr-FR). Defaults to en-US.
queryParams
PayPalQueryParams?
Advanced SDK initialisation parameters. Defaults to null. See Query and script parameters.
queryParams.buyerCountry
String?
The buyer's country code in ISO-3166-1 alpha-2 format. Defaults to null.
queryParams.debug
Boolean
Whether to use debug mode. Defaults to false.
queryParams.integrationDate
String?
The date when your PayPal client ID was created (YYYY-MM-DD). Defaults to null.
componentLayoutConfig
PayPalComponentLayoutConfig
Controls WebView height constraints. Defaults to PayPalComponentLayoutConfig().
componentLayoutConfig.minHeightPercent
Float
Minimum WebView height as screen percentage. Defaults to 0.1f (10%).
componentLayoutConfig.maxHeightPercent
Float
Maximum WebView height as screen percentage. Defaults to 0.6f (60%).

When enableOneClickPayment is true, you must provide a userIdToken in scriptParams. This token is obtained from checking the vault status for your merchant shopper ID.

Styling

Default styling

The PayPal component renders with these default styles:

style = PayPalButtonStyle(
    layout = "vertical",
    color = "gold",
    shape = "rect",
    label = "paypal",
    tagline = false,
    height = 55,
    borderRadius = 4,
    disableMaxWidth = false
)

You can find PayPal's official rules around button styling in their JavaScript SDK reference.

Custom styling

You can override the default appearance by providing custom styles:

val paypalConfig = PayPalComponentConfig(
    style = PayPalButtonStyle(
        layout = "horizontal",
        color = "blue",
        shape = "pill",
        label = "buynow",
        tagline = true,
        height = 48,
        borderRadius = 8,
        disableMaxHeight = false,
        disableMaxWidth = true
    ),
    message = PayPalMessage(
        amount = 99.99,
        align = "center",
        color = "black",
        position = "bottom"
    )
)
PropertyDescription
style
PayPalButtonStyle?
Styling options for the PayPal button. Defaults to null.
style.layout
String
The layout of the PayPal button. Defaults to vertical.

Possible values:
  • vertical
  • horizontal
style.color
String
The colour of the PayPal button. Defaults to gold.

Possible values:
  • gold
  • blue
  • silver
  • white
  • black
style.shape
String
The shape of the PayPal button. Defaults to rect.

Possible values:
  • rect
  • pill
If borderRadius and shape are both defined, borderRadius takes priority.
style.borderRadius
Int?
The border radius of the PayPal button, in pixels. Defaults to null.
If borderRadius and shape are both defined, borderRadius takes priority.
style.height
Int?
The height of the PayPal button, in pixels. Must be between 25-55px. Defaults to null.
style.disableMaxHeight
Boolean?
Whether to disable the maximum height constraint of the PayPal button. Defaults to null.
style.disableMaxWidth
Boolean
Whether to disable the maximum width constraint of the PayPal button. Defaults to false.
style.label
String
The label text of the PayPal button. Defaults to paypal.

Possible values:
  • paypal
  • checkout
  • buynow
  • pay
  • installment
style.tagline
Boolean
Whether to show the tagline of the PayPal button. Set the layout to horizontal for taglines. Defaults to false.
message
PayPalMessage?
Configuration for the messaging for the most relevant Pay Later offer. If provided, replaces the tagline. Defaults to null.
message.amount
Double
Use this option to show the most relevant offer and price breakdown. Set this to a number greater than 0. Defaults to 0.0.
message.align
String
The alignment of the message, in relation to the button(s). Defaults to center.

Possible values:
  • center
  • left
  • right
message.color
String
The colour of the message. Defaults to black.

Possible values:
  • black
  • white
message.position
String
The position of the message, in relation to the button(s). Defaults to top.

Possible values:
  • top
  • bottom

Event handling

The PayPal component provides event handlers to manage the complete payment flow:

val paypalConfig = PayPalComponentConfig(
    onSuccess = { data: String -> },
    onError = { error: String -> },
    onCancel = { -> },
    onShippingAddressChange = { data: String -> String? },
    onShippingOptionsChange = { data: String -> String? },
    onOrderCreated = { orderData: String -> },
    onSubmitError = { error: String -> },
    onScriptLoaded = { -> },
    onGetConsent = { -> Boolean }
)
CallbackDescription
onSuccess: ((String) -> Unit)?Event handler for when the PayPal payment succeeds with payment approval data. The string parameter contains JSON with order details including orderID, payerID, and paymentID.
onError: ((String) -> Unit)?Event handler for when the PayPal payment encounters an error. The string parameter contains the error message.
onCancel: (() -> Unit)?Event handler for when the user cancels the PayPal payment flow. No parameters.
onShippingAddressChange: ((String) -> String?)?Event handler for when the shipping address changes in the PayPal checkout. Receive address data and return null to accept or reject:ERROR_CODE to reject.
onShippingOptionsChange: ((String) -> String?)?Event handler for when the shipping options change in the PayPal checkout. Receive option data and return null to accept or reject:ERROR_CODE to reject.
onOrderCreated: ((String) -> Unit)?Event handler for when the PayPal order is successfully created. The string parameter contains the order ID.
onSubmitError: ((String) -> Unit)?Event handler for when the order creation or submission fails. The string parameter contains the error details.
onScriptLoaded: (() -> Unit)?Event handler for when the PayPal SDK script loads successfully. Useful for hiding loading indicators.
onGetConsent: (() -> Boolean)?Event handler to get user consent for vaulting PayPal account. Return true if user consents, false otherwise.

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

Methods

The PayPal component provides methods for lifecycle management.

Content()

Renders the PayPal button in Jetpack Compose:

@Composable
fun PaymentScreen() {
    val paypalComponent = remember {
        pxpCheckout.createComponent(
            type = ComponentType.PAYPAL,
            config = paypalConfig
        )
    }
    
    pxpCheckout.buildComponentView(
        component = paypalComponent,
        modifier = Modifier.fillMaxWidth()
    )
}

getValue()

Retrieves the current component state:

val componentValue = paypalComponent.getValue()

Examples

Basic payment button

A straightforward implementation with essential configuration and error handling:

val paypalConfig = PayPalComponentConfig(
    // Required configuration
    renderType = "standalone",
    fundingSources = "paypal",
    shippingPreference = "NoShipping",
    userAction = "PayNow",
    
    // Basic settings
    payeeEmailAddress = "merchant@example.com",
    paymentDescription = "Order payment",
    enableOneClickPayment = false,
    
    // Essential event handlers
    onSuccess = { data ->
        val jsonObject = JSONObject(data)
        val orderID = jsonObject.getString("orderID")
        Log.d("PayPal", "Payment successful: $orderID")
        navigateToSuccessScreen(orderID)
    },
    
    onError = { error ->
        Log.e("PayPal", "Payment failed: $error")
        showErrorMessage("Payment failed. Please try again.")
    },
    
    onCancel = {
        Log.d("PayPal", "Payment cancelled by user")
        showMessage("Payment was cancelled.")
    }
)

Enterprise payment with full features

A comprehensive implementation with one-click payments, custom styling, and complete event handling:

val paypalConfig = PayPalComponentConfig(
    // Required configuration
    renderType = "standalone",
    fundingSources = "paypal",
    shippingPreference = "NoShipping",
    userAction = "PayNow",
    
    // Payment details
    payeeEmailAddress = "enterprise@example.com",
    paymentDescription = "Enterprise subscription",
    
    // One-click payment configuration
    enableOneClickPayment = true,
    scriptParams = PayPalScriptParams(
        userIdToken = getUserIdToken(),
        clientToken = getClientToken(),
        pageType = "checkout"
    ),
    
    // Component linking
    toggleComponent = toggleComponent,
    consentComponent = consentComponent,
    
    // Localisation
    locale = "en-US",
    
    // Custom styling
    style = PayPalButtonStyle(
        layout = "horizontal",
        color = "blue",
        shape = "pill",
        label = "buynow",
        height = 48,
        borderRadius = 8
    ),
    
    // Query parameters
    queryParams = PayPalQueryParams(
        buyerCountry = if (BuildConfig.DEBUG) "US" else null,
        debug = BuildConfig.DEBUG,
        integrationDate = "2025-07-01"
    ),
    
    // Layout configuration
    componentLayoutConfig = PayPalComponentLayoutConfig(
        minHeightPercent = 0.1f,
        maxHeightPercent = 0.8f
    ),
    
    // Complete event handling
    onScriptLoaded = {
        Log.d("PayPal", "SDK loaded successfully")
        hideLoadingIndicator()
    },
    
    onOrderCreated = { orderId ->
        Log.d("PayPal", "Order created: $orderId")
        trackAnalyticsEvent("paypal_order_created", mapOf("orderId" to orderId))
    },
    
    onGetConsent = {
        val consentGiven = consentComponent?.getValue() as? Boolean ?: false
        Log.d("PayPal", "Consent status: $consentGiven")
        consentGiven
    },
    
    onSuccess = { data ->
        hideLoadingIndicator()
        
        val jsonObject = JSONObject(data)
        val orderID = jsonObject.getString("orderID")
        val payerID = jsonObject.getString("payerID")
        
        // Check if user consented to save account
        val consentGiven = consentComponent?.getValue() as? Boolean ?: false
        if (consentGiven) {
            Log.d("PayPal", "User consented to save PayPal account")
            saveVaultingPreference(payerID)
        }
        
        trackAnalyticsEvent("paypal_payment_success", mapOf(
            "orderId" to orderID,
            "vaulted" to consentGiven
        ))
        
        showPaymentSuccessMessage()
        setTimeout({
            navigateToSuccessScreen(orderID)
        }, 2000)
    },
    
    onError = { error ->
        hideLoadingIndicator()
        
        val errorMessage = when {
            error.contains("SDK") -> "Failed to load PayPal. Please check your connection."
            error.contains("transaction") -> "Payment processing error. Please try again."
            else -> "Payment error occurred: $error"
        }
        
        Log.e("PayPal", "Payment error: $error")
        trackAnalyticsEvent("paypal_payment_error", mapOf("error" to error))
        showErrorDialog(errorMessage)
    },
    
    onCancel = {
        Log.d("PayPal", "Payment cancelled by user")
        trackAnalyticsEvent("paypal_payment_cancelled")
        showMessage("Payment was cancelled.")
    },
    
    onSubmitError = { error ->
        Log.e("PayPal", "Submit error: $error")
        showErrorDialog("Unable to process payment: $error")
    },
    
    onShippingAddressChange = { data ->
        val jsonObject = JSONObject(data)
        val address = jsonObject.optJSONObject("shippingAddress")
        val countryCode = address?.optString("countryCode", "")
        
        // Validate address
        if (countryCode != "US") {
            Log.w("PayPal", "Non-US address rejected")
            "reject:COUNTRY_ERROR"
        } else {
            null // Accept the address
        }
    }
)

Multiple funding sources

Implementation with Pay Later support:

val paypalConfig = PayPalComponentConfig(
    // Use setOfButtons for multiple funding sources
    renderType = "setOfButtons",
    fundingSources = listOf("paypal", "paylater"),
    shippingPreference = "NoShipping",
    userAction = "PayNow",
    
    // Payment details
    payeeEmailAddress = "merchant@example.com",
    paymentDescription = "Product purchase",
    
    // Custom styling for multiple buttons
    style = PayPalButtonStyle(
        layout = "vertical",
        color = "gold",
        shape = "rect",
        height = 45
    ),
    
    // Pay Later message
    message = PayPalMessage(
        amount = 199.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("PayPal", "Payment via $paymentSource: $orderID")
        navigateToSuccessScreen(orderID)
    }
)