Learn about how to configure the PayPal payment button component.
At minimum, the PayPal component requires the following configuration to function:
val paypalConfig = PayPalComponentConfig(
renderType = "standalone",
fundingSources = "paypal",
shippingPreference = "NoShipping",
userAction = "PayNow"
)| Property | Description |
|---|---|
renderTypeString required | The type of button to render. Defaults to standalone.Possible values:
|
fundingSourcesAny? 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:
|
shippingPreferenceString required | The shipping details to use. Defaults to NoShipping.Possible values:
|
userActionString required | The next step in the payment flow. Defaults to PayNow.Possible values:
|
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
)
)| Property | Description |
|---|---|
payeeEmailAddressString? | Your email address. Defaults to empty string. |
paymentDescriptionString? | A description of the payment. Defaults to empty string. |
shippingOptionsList<ShippingOption>? | Details about the shipping options. Provide this only when shippingPreference is GetFromFile. Defaults to null. |
enableOneClickPaymentBoolean | Whether to enable one-click payment with vaulting. Defaults to true. |
scriptParamsPayPalScriptParams? | Optional script parameters including userIdToken for one-click payments. Defaults to null. |
scriptParams.userIdTokenString? | Your user ID token. Required for one-click payment functionality. Defaults to null. |
toggleComponentToggleComponent? | Toggle component for payment method switching. Defaults to null. See Toggle component. |
consentComponentPayPalConsentComponent? | Consent component for vaulting agreement. Defaults to null. See Consent component. |
localeString | The language and region for PayPal interface (e.g., en-US, fr-FR). Defaults to en-US. |
queryParamsPayPalQueryParams? | Advanced SDK initialisation parameters. Defaults to null. See Query and script parameters. |
queryParams.buyerCountryString? | The buyer's country code in ISO-3166-1 alpha-2 format. Defaults to null. |
queryParams.debugBoolean | Whether to use debug mode. Defaults to false. |
queryParams.integrationDateString? | The date when your PayPal client ID was created (YYYY-MM-DD). Defaults to null. |
componentLayoutConfigPayPalComponentLayoutConfig | Controls WebView height constraints. Defaults to PayPalComponentLayoutConfig(). |
componentLayoutConfig.minHeightPercentFloat | Minimum WebView height as screen percentage. Defaults to 0.1f (10%). |
componentLayoutConfig.maxHeightPercentFloat | 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.
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.
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"
)
)| Property | Description |
|---|---|
stylePayPalButtonStyle? | Styling options for the PayPal button. Defaults to null. |
style.layoutString | The layout of the PayPal button. Defaults to vertical.Possible values:
|
style.colorString | The colour of the PayPal button. Defaults to gold.Possible values:
|
style.shapeString | The shape of the PayPal button. Defaults to rect.Possible values:
If borderRadius and shape are both defined, borderRadius takes priority. |
style.borderRadiusInt? | The border radius of the PayPal button, in pixels. Defaults to null.If borderRadius and shape are both defined, borderRadius takes priority. |
style.heightInt? | The height of the PayPal button, in pixels. Must be between 25-55px. Defaults to null. |
style.disableMaxHeightBoolean? | Whether to disable the maximum height constraint of the PayPal button. Defaults to null. |
style.disableMaxWidthBoolean | Whether to disable the maximum width constraint of the PayPal button. Defaults to false. |
style.labelString | The label text of the PayPal button. Defaults to paypal.Possible values:
|
style.taglineBoolean | Whether to show the tagline of the PayPal button. Set the layout to horizontal for taglines. Defaults to false. |
messagePayPalMessage? | Configuration for the messaging for the most relevant Pay Later offer. If provided, replaces the tagline. Defaults to null. |
message.amountDouble | 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.alignString | The alignment of the message, in relation to the button(s). Defaults to center.Possible values:
|
message.colorString | The colour of the message. Defaults to black.Possible values:
|
message.positionString | The position of the message, in relation to the button(s). Defaults to top.Possible values:
|
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 }
)| Callback | Description |
|---|---|
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.
The PayPal component provides methods for lifecycle management.
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()
)
}Retrieves the current component state:
val componentValue = paypalComponent.getValue()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.")
}
)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
}
}
)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)
}
)