Configure Checkout Drop-in with unified settings for all payment methods, callbacks, and transaction data.
Checkout Drop-in uses a single, unified configuration at initialisation. Instead of configuring individual payment components, you configure Drop-in once and it automatically handles all payment methods.
All configuration happens at initialisation via CheckoutDropIn.initialize():
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.Modifier
import com.pxp.checkout.checkoutdropin.CheckoutDropIn
import com.pxp.checkout.checkoutdropin.types.CheckoutDropInConfig
import com.pxp.checkout.models.DropInTransactionData
import com.pxp.checkout.models.DropInTransactionIntentData
import com.pxp.checkout.models.*
import com.pxp.checkout.checkoutdropin.types.*
val checkoutDropIn = CheckoutDropIn.initialize(
context = context,
config = CheckoutDropInConfig(
// REQUIRED
environment = Environment.TEST,
session = sessionData,
ownerType = "MerchantGroup",
ownerId = "MERCHANT-1",
transactionData = DropInTransactionData(
amount = 99.99,
currency = "USD",
entryType = EntryType.Ecom,
intent = DropInTransactionIntentData(
card = IntentType.Authorisation,
paypalDropInIntent = DropInPayPalIntentType.Authorisation
),
merchant = "MERCHANT-1",
merchantTransactionId = UUID.randomUUID().toString(),
merchantTransactionDate = { Instant.now().toString() }
),
// OPTIONAL: Fraud detection
kountDisabled = false, // Set to true to disable Kount fraud detection
// REQUIRED: Callbacks
onSuccess = { result -> /* ... */ },
onError = { error -> /* ... */ },
// OPTIONAL: Callbacks
onGetShopper = { Shopper(id = "shopper-123") },
onBeforeSubmit = { paymentMethod -> /* return true to proceed */ },
onSubmit = { paymentMethod -> /* ... */ },
analyticsEvent = { event -> /* ... */ }
)
)
// Create the component from a coroutine
val component = checkoutDropIn.create()
// Render in Compose UI
component.Content(modifier = Modifier.fillMaxWidth())Specifies which Unity environment to connect to:
environment = Environment.TEST // or Environment.LIVE| Value | Description |
|---|---|
Environment.TEST | Sandbox environment. Use this for development, testing, and staging. |
Environment.LIVE | Live environment. Use this for production deployments. |
Session data is retrieved from your backend and contains payment configuration:
// Backend endpoint
val sessionData = fetchSessionFromBackend()
// Pass to Drop-in
session = sessionDataSession data includes:
sessionId: Unique session identifier.hmacKey: HMAC authentication key.encryptionKey: Encryption key.allowedFundingTypes: Which payment methods are enabled.- Session timeout and merchant identification.
For session creation details, see our implementation guide.
Identifies who owns this transaction:
ownerType = "MerchantGroup",
ownerId = "MERCHANT-1"Defines the payment amount, currency, and intent:
transactionData = DropInTransactionData(
amount = 99.99,
currency = "USD",
entryType = EntryType.Ecom,
intent = DropInTransactionIntentData(
card = IntentType.Authorisation,
paypalDropInIntent = DropInPayPalIntentType.Authorisation
),
merchant = "MERCHANT-1",
merchantTransactionId = UUID.randomUUID().toString(),
merchantTransactionDate = { Instant.now().toString() }
)| Property | Description |
|---|---|
amountDouble required | Transaction amount shown and submitted by the Drop-in. |
currencyString required | Currency code, for example "USD". Must be a valid ISO 4217 currency code. |
entryTypeEntryType? | Transaction entry type. Usually EntryType.Ecom for e-commerce transactions. |
intentDropInTransactionIntentData required | Card and PayPal intent configuration. See supported transaction intents for details. |
merchantString required | Merchant name or identifier used for the transaction. |
merchantTransactionIdString required | Merchant-generated transaction ID. Use a UUID or order ID to ensure uniqueness. |
merchantTransactionDate() -> String required | Function returning the transaction date/time string in ISO 8601 format. |
shopperShopper? | Optional shopper data attached to the transaction. |
recurringRecurringData? | Optional recurring payment configuration for subscriptions. |
cardAcceptorNameString? | Optional card acceptor name shown on card statements. |
Your unique identifier for the transaction:
merchantTransactionId = UUID.randomUUID().toString()
// Or use your own format
merchantTransactionId = "order-${orderId}"Drop-in provides unified callbacks that work for all payment methods:
CheckoutDropInConfig(
// OPTIONAL: Get shopper information
onGetShopper = {
Shopper(id = "shopper-123")
},
// REQUIRED: Called when payment succeeds
onSuccess = { result ->
Log.d("CheckoutDropIn", "Payment successful: ${result.systemTransactionId}")
// CRITICAL: Always verify on backend before fulfilling order
verifyPaymentOnBackend(result)
},
// REQUIRED: Called when payment fails
onError = { error ->
Log.e("CheckoutDropIn", "Payment failed: ${error.code} - ${error.message}")
},
// OPTIONAL: Called before payment submission (can cancel)
onBeforeSubmit = { paymentMethod ->
Log.d("CheckoutDropIn", "Payment method: $paymentMethod")
// Return false to cancel payment
true
},
// OPTIONAL: Called when payment starts processing
onSubmit = { paymentMethod ->
Log.d("CheckoutDropIn", "Processing payment...")
}
)For detailed callback documentation, see Events.
Track payment flow events:
analyticsEvent = { event ->
Log.d("Analytics", "Event: ${event.eventName}")
// Send to your analytics platform
sendToFirebaseAnalytics(event)
}For detailed analytics documentation, see Analytics.
Configure payment-method-specific settings:
methodConfig = DropInMethodConfig(
global = DropInGlobalConfig(
acceptedCardNetworks = listOf(
CardNetworks.VISA,
CardNetworks.MASTERCARD
),
allowedIssuerCountryCodes = listOf("US", "GB")
),
paypal = DropInPaypalConfig(
shippingPreference = ShippingPreference.GET_FROM_FILE
),
googlePay = DropInGooglePayConfig(
collectCvc = CollectCvcMode.DEFAULT,
billingAddressRequired = true
),
card = DropInCardConfig() // Currently empty marker
)Learn more about payment method configuration
Global settings apply to all payment methods:
| Property | Description |
|---|---|
acceptedCardNetworksList<CardNetworks>? | Limits accepted card networks for card and wallet payments. Supported values include VISA, MASTERCARD, AMERICAN_EXPRESS, UNION_PAY, DINERS, JCB, and DISCOVER. |
allowedCardFundingSourceList<CardFundingSource>? | Limits accepted funding sources. Supported values are CREDIT, DEBIT, and PREPAID. |
allowedIssuerCountryCodesList<String>? | Allows only cards issued in the listed ISO country codes. |
transactionInfoTransactionInfo? | Payment display information such as country code, merchant display name, total label, total status, and line items. |
shippingOptionsList<ShippingOption>? | Shipping options displayed for supported wallet flows. |
couponInfoCouponInfo? | Optional coupon code and description. |
riskScreeningDataRiskScreeningData? | Kount risk screening data for fraud checks. |
onGetConsent(PaymentMethod) -> Boolean | Called before tokenisation/consent-sensitive actions. Return true to continue. |
onCancel(PaymentMethod, Any?) -> Unit | Called when the buyer cancels a supported payment flow. |
PayPal-specific settings:
| Property | Description |
|---|---|
fundingSourcesList<PaypalFundingSources>? | Optional PayPal funding sources, such as PAYPAL or PAYLATER. |
shippingOptionString? | Optional selected shipping option value. |
enableOneClickPaymentBoolean? | Enables PayPal one-click payment behaviour when supported. |
localeString? | PayPal locale override. |
payeeEmailAddressString? | Payee email address for the PayPal transaction. |
paymentDescriptionString? | Description shown for the PayPal payment. |
useBuiltInChangePreferredPaymentMethodBoolean? | Uses the built-in preferred payment method change behaviour when supported. |
consentComponentBoolean? | Enables PayPal consent component behaviour when supported. |
shippingPreferenceShippingPreference? | Shipping handling for PayPal. Values are NO_SHIPPING, GET_FROM_FILE, and SET_PROVIDED_ADDRESS. |
buyerCountryString? | Buyer country override. |
onShippingAddressChange(String) -> String? | Called when the PayPal shipping address changes. Return null to accept or a reject response string to reject. |
onShippingOptionsChange(String) -> String? | Called when the PayPal shipping option changes. Return null to accept or a reject response string to reject. |
Google Pay-specific settings:
| Property | Description |
|---|---|
collectCvcCollectCvcMode? | Controls CVC collection for Google Pay. Values are ALWAYS, NEVER, and DEFAULT. |
billingAddressRequiredBoolean? | Requests a billing address from Google Pay. |
billingAddressParametersBillingAddressParameters? | Billing address options. Currently supports phoneNumberRequired. |
shippingAddressRequiredBoolean? | Requests a full shipping address from Google Pay. |
shippingAddressParametersShippingAddressParameters? | Shipping address options, including allowedCountryCodes and phoneNumberRequired. |
blockedIssuerCountryCodesList<String>? | Blocks cards issued in the listed ISO country codes. Don't combine with allowedIssuerCountryCodes. |
Card-specific settings (currently empty):
card = DropInCardConfig() // Empty marker - inherits from globalDrop-in method configuration values are optional overrides. When you omit an optional value, the SDK derives the effective component configuration from the checkout session, Unity site configuration, or SDK defaults.
| Config value | Fallback behaviour |
|---|---|
methodConfig.global.acceptedCardNetworks | Falls back to the card service configuration in the Unity Portal. If not configured in the portal, defaults to an empty list. |
methodConfig.global.transactionInfo.countryCode | Falls back to siteConfig.merchantConfiguration.countryCode. |
methodConfig.global.transactionInfo.totalLabel | Falls back to "TOTAL". |
methodConfig.global.transactionInfo.totalStatus | Falls back to DropInTotalStatus.FINAL. |
methodConfig.global.transactionInfo.lineItems | Falls back to one generated subtotal display item using transactionData.amount. |
| Config value | Fallback behaviour |
|---|---|
methodConfig.googlePay.collectCvc | Falls back to CollectCvcMode.DEFAULT. |
methodConfig.googlePay.billingAddressRequired | Falls back to false. |
methodConfig.googlePay.billingAddressParameters.phoneNumberRequired | Falls back to false. |
methodConfig.googlePay.shippingAddressRequired | Falls back to false. |
methodConfig.googlePay.shippingAddressParameters.phoneNumberRequired | Falls back to false. |
methodConfig.global.shippingOptions | If omitted, Google Pay sets shippingOptionRequired = false and doesn't pass shipping option parameters. |
| Config value | Fallback behaviour |
|---|---|
methodConfig.paypal.fundingSources | Falls back to session.allowedFundingTypes.wallets.paypal.allowedFundingOptions. |
methodConfig.paypal.shippingPreference | Falls back to PayPal NoShipping. |
methodConfig.paypal.enableOneClickPayment | Falls back to true. |
methodConfig.paypal.locale | Falls back to "en-US". |
methodConfig.paypal.consentComponent | Falls back to true. |
methodConfig.paypal.useBuiltInChangePreferredPaymentMethod | The built-in change preferred payment method toggle is only created when this value is explicitly true. |
methodConfig.global.shippingOptions.amount | For PayPal shipping options, non-numeric amounts fall back to 0.0. |
Checkout Drop-in supports UI scaling from 50% to 175%. This value can be adjusted in the Unity portal to match the merchant checkout design and available screen space.
During Android mobile testing, the best visual results were observed with scale values between 60% and 115%. This range is the recommended choice for mobile resolutions because it keeps the Drop-in readable while reducing the risk of clipped content, crowded payment method sections, or excessive scrolling.
| Scale | Recommended use |
|---|---|
| 60% - 80% | Compact layouts, smaller checkout containers, or screens with additional merchant content above/below the Drop-in. |
| 80% - 100% | Default mobile checkout layouts. This is the safest range for most integrations. |
| 100% - 115% | Larger mobile screens or merchant flows that need stronger visual emphasis. |
| Above 115% | Supported by configuration, but should be tested carefully on target devices before release. |
| Device | Display | Resolution | Android version / API level |
|---|---|---|---|
| Google Pixel 8 | 6.2-inch OLED, 20:9 aspect ratio | 1080 x 2400 px, approximately 428 ppi | Android 14 / API 34 |
| Google Pixel 8a | 6.1-inch OLED, 20:9 aspect ratio | 1080 x 2400 px, approximately 430 ppi | Android 14 / API 36.1 |
Merchants can still use the full 50% to 175% portal range, but values outside 60% to 115% should be reviewed on the merchant's own supported devices and checkout content before going live.
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.Modifier
import com.pxp.checkout.checkoutdropin.CheckoutDropIn
import com.pxp.checkout.checkoutdropin.types.CheckoutDropInConfig
import com.pxp.checkout.models.DropInTransactionData
import com.pxp.checkout.models.DropInTransactionIntentData
import com.pxp.checkout.models.*
import com.pxp.checkout.checkoutdropin.types.*
import java.time.Instant
import java.util.UUID
// Get session from backend
val sessionData = fetchSessionFromBackend()
// Initialise with minimal config
val checkoutDropIn = CheckoutDropIn.initialize(
context = context,
config = CheckoutDropInConfig(
environment = Environment.TEST,
session = sessionData,
ownerType = "MerchantGroup",
ownerId = "MERCHANT-1",
transactionData = DropInTransactionData(
amount = 99.99,
currency = "USD",
entryType = EntryType.Ecom,
intent = DropInTransactionIntentData(
card = IntentType.Authorisation,
paypalDropInIntent = DropInPayPalIntentType.Authorisation
),
merchant = "MERCHANT-1",
merchantTransactionId = UUID.randomUUID().toString(),
merchantTransactionDate = { Instant.now().toString() }
),
kountDisabled = false, // OPTIONAL: Set to true to disable Kount fraud detection
onGetShopper = {
Shopper(id = "shopper-123")
},
onSuccess = { result ->
verifyPaymentOnBackend(result)
},
onError = { error ->
showError(error.message ?: "Payment failed")
}
)
)
// Create and render
val component = checkoutDropIn.create()
component.Content(modifier = Modifier.fillMaxWidth())import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.Modifier
import com.pxp.checkout.checkoutdropin.CheckoutDropIn
import com.pxp.checkout.checkoutdropin.types.*
import com.pxp.checkout.models.*
import java.time.Instant
import java.util.UUID
// Get session from backend
val sessionData = fetchSessionFromBackend()
// Initialise with all callbacks
val checkoutDropIn = CheckoutDropIn.initialize(
context = context,
config = CheckoutDropInConfig(
// REQUIRED
environment = Environment.LIVE,
session = sessionData,
ownerType = "MerchantGroup",
ownerId = "MERCHANT-1",
transactionData = DropInTransactionData(
amount = 149.99,
currency = "USD",
entryType = EntryType.Ecom,
intent = DropInTransactionIntentData(
card = IntentType.Authorisation,
paypalDropInIntent = DropInPayPalIntentType.Purchase
),
merchant = "MERCHANT-1",
merchantTransactionId = "order-${orderId}",
merchantTransactionDate = { Instant.now().toString() }
),
// OPTIONAL: Fraud detection
kountDisabled = false, // Set to true to disable Kount fraud detection
// CALLBACKS
onGetShopper = {
Shopper(id = "shopper-123")
},
onBeforeSubmit = { paymentMethod ->
Log.d("CheckoutDropIn", "Payment method selected: $paymentMethod")
// Custom validation
val isValid = validateOrder(orderId)
if (!isValid) {
showToast("Order validation failed")
return@CheckoutDropInConfig false // Cancel payment
}
// Check inventory
val inStock = checkInventory(orderId)
if (!inStock) {
showToast("Item is out of stock")
return@CheckoutDropInConfig false // Cancel payment
}
true // Proceed with payment
},
onSubmit = { paymentMethod ->
Log.d("CheckoutDropIn", "Payment processing started for: $paymentMethod")
// Show loading spinner
showLoadingSpinner(true)
},
onSuccess = { result ->
Log.d("CheckoutDropIn", "Payment successful: ${result.systemTransactionId}")
showLoadingSpinner(false)
// CRITICAL: Verify on backend before fulfilling
lifecycleScope.launch {
try {
val verified = verifyPaymentOnBackend(
systemTransactionId = result.systemTransactionId,
merchantTransactionId = result.merchantTransactionId,
orderId = orderId
)
if (verified.success) {
navigateToOrderConfirmation(verified.orderId)
} else {
showToast("Payment verification failed. Please contact support.")
}
} catch (e: Exception) {
Log.e("CheckoutDropIn", "Verification failed", e)
showToast("Unable to verify payment. Please contact support.")
}
}
},
onError = { error ->
Log.e("CheckoutDropIn", "Payment error: ${error.code}")
showLoadingSpinner(false)
// Show user-friendly error message
val userMessage = when {
error.code == "SDK1114" -> "Card verification failed"
error.code == "SDK1116" -> "Card payment failed"
error.message?.contains("declined", ignoreCase = true) == true ->
"Card declined. Please try a different card."
error.message?.contains("insufficient funds", ignoreCase = true) == true ->
"Insufficient funds."
error.message?.contains("expired", ignoreCase = true) == true ->
"This card has expired."
error.message?.contains("cvv", ignoreCase = true) == true ->
"Invalid security code."
else -> error.message ?: "Payment failed. Please try again."
}
showError(userMessage)
},
analyticsEvent = { event ->
// Send to Firebase Analytics
firebaseAnalytics.logEvent(event.eventName, bundleOf(
"event_category" to "checkout",
"event_label" to event.toString()
))
// Send to backend
sendAnalyticsToBackend(event)
},
// Method-specific configuration
methodConfig = DropInMethodConfig(
global = DropInGlobalConfig(
acceptedCardNetworks = listOf(
CardNetworks.VISA,
CardNetworks.MASTERCARD,
CardNetworks.AMERICAN_EXPRESS
),
allowedCardFundingSource = listOf(
CardFundingSource.CREDIT,
CardFundingSource.DEBIT
),
allowedIssuerCountryCodes = listOf("US", "GB", "CA"),
transactionInfo = TransactionInfo(
countryCode = "US",
merchantDisplayName = "Demo Store",
totalLabel = "Total Amount",
totalStatus = DropInTotalStatus.FINAL,
lineItems = listOf(
TransactionLineItem(label = "Products", amount = "5.00"),
TransactionLineItem(label = "Shipping", amount = "2.00")
)
),
onGetConsent = { paymentMethod ->
// Show consent for cards and PayPal
paymentMethod == PaymentMethod.CARD ||
paymentMethod == PaymentMethod.PAYPAL
},
onCancel = { paymentMethod, data ->
Log.d("CheckoutDropIn", "Payment cancelled: $paymentMethod")
showLoadingSpinner(false)
// Track cancellation
trackEvent("payment_cancelled", mapOf(
"payment_method" to paymentMethod.toString()
))
}
),
paypal = DropInPaypalConfig(
shippingPreference = ShippingPreference.GET_FROM_FILE
),
googlePay = DropInGooglePayConfig(
collectCvc = CollectCvcMode.DEFAULT,
shippingAddressRequired = true,
shippingAddressParameters = ShippingAddressParameters(
allowedCountryCodes = listOf("US", "GB"),
phoneNumberRequired = true
),
billingAddressRequired = true,
billingAddressParameters = BillingAddressParameters(
phoneNumberRequired = true
)
),
card = DropInCardConfig()
)
)
)
// Create and render
val component = checkoutDropIn.create()
component.Content(modifier = Modifier.fillMaxWidth())