Configure Checkout Drop-in once 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(config:):
import SwiftUI
import PXPCheckoutSDK
let config = CheckoutDropInConfig(
// REQUIRED
environment: .test,
session: sessionData,
transactionData: DropInTransactionData(
amount: Decimal(string: "99.99") ?? 0,
currency: "USD",
entryType: .ecom,
intent: DropInTransactionIntentData(
card: .authorisation,
paypal: .authorisation
),
merchantTransactionId: UUID().uuidString,
merchantTransactionDate: { Date() }
),
merchantShopperId: "shopper-123",
ownerId: "MERCHANT-1",
// OPTIONAL: Fraud detection
kountDisabled: false,
// Recommended: always implement success and error handlers
onSuccess: { result in
// Handle success
},
onError: { paymentMethod, error in
// Handle error
},
// Optional callbacks
onGetShopper: { async in
TransactionShopper(id: "shopper-123")
},
onBeforeSubmit: { paymentMethod in
// Return true to proceed
return true
},
onSubmit: { paymentMethod in
// Payment started
},
analyticsEvent: { event in
// Track analytics
}
)
// Initialise and create Drop-in
let dropIn = try CheckoutDropIn(config: config)
await dropIn.create()
// Render in SwiftUI
dropIn.buildContent()Specifies which Unity environment to connect to:
.test: sandbox environment. Use this for development, testing, and staging..live: live environment. Use this for production deployments.
environment: .test // or .liveSession data is retrieved from your backend and contains payment configuration:
// Backend endpoint
let sessionData = try await 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.sessionExpiry: Optional session expiry timestamp from your backend (respect when creating new sessions).restrictions: Optional session-level card restrictions merged with checkout config.
For session creation details, see our implementation guide.
Identifies who owns this transaction:
merchantShopperId: "shopper-123", // Required — your shopper identifier
ownerId: "MERCHANT-1" // Required — merchant ID from the Unity PortalDrop-in sets ownerType to "MerchantGroup" automatically. You do not pass it in CheckoutDropInConfig.
Defines the payment amount, currency, and intent:
transactionData: DropInTransactionData(
amount: Decimal(string: "99.99") ?? 0,
currency: "USD",
entryType: .ecom,
intent: DropInTransactionIntentData(
card: .authorisation,
paypal: .authorisation
),
merchantTransactionId: UUID().uuidString,
merchantTransactionDate: { Date() }
)The following table describes each DropInTransactionData property:
| Property | Description |
|---|---|
amountDecimal required | The transaction amount shown and submitted by the drop-in. |
currencyString required | The currency code, in ISO 4217 format. |
entryTypeEntryType required | The transaction entry type. |
intentDropInTransactionIntentData required | Card and PayPal intent configuration. |
merchantTransactionIdString required | A merchant-generated transaction ID. Use a UUID or order ID to ensure uniqueness. |
merchantTransactionDate() -> Date required | Closure returning the transaction date. Typically { Date() }. |
cardAcceptorNameString? | Optional card acceptor name shown on card statements. |
recurringRecurringType? | Optional recurring payment configuration for subscriptions. Example:RecurringType(frequencyInDays: 30, frequencyExpiration: "2026-12-31") |
linkIdString? | Optional link ID when linking transactions together. |
Your unique identifier for the transaction:
merchantTransactionId: UUID().uuidString
// Or use your own format
merchantTransactionId: "order-\(orderId)"Drop-in provides unified callbacks for payment success, failure, and processing. onSuccess and onError are optional in the initializer but should always be implemented — without them, completed or failed payments are not handled.
Most other callbacks apply to all enabled payment methods:
CheckoutDropInConfig(
// OPTIONAL: Get shopper information
onGetShopper: { async in
TransactionShopper(id: "shopper-123")
},
// Recommended: called when payment succeeds
onSuccess: { result in
print("Payment successful: \(result.systemTransactionId)")
// CRITICAL: Always verify on backend before fulfilling order
verifyPaymentOnBackend(result)
},
// Recommended: called when payment fails
onError: { paymentMethod, error in
print("Payment failed: \(error.errorCode) - \(error.errorMessage)")
},
// OPTIONAL: Called before payment submission (can cancel)
onBeforeSubmit: { paymentMethod in
print("Payment method: \(paymentMethod.rawValue)")
// Return false to cancel payment
return true
},
// OPTIONAL: Called when payment starts processing
onSubmit: { paymentMethod in
print("Processing payment...")
}
)For detailed callback documentation, see Events.
Track payment flow events:
analyticsEvent: { event in
print("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: [.visa, .mastercard, .amex],
allowedIssuerCountryCodes: ["US", "GB"],
transactionInfo: DropInTransactionInfo(
countryCode: "US",
totalLabel: "Total"
),
riskScreeningData: RiskScreeningData(
performRiskScreening: true,
userIp: "203.0.113.10",
transaction: RiskScreeningTransaction(subtotal: 149.99)
)
),
paypal: DropInPaypalConfig(
fundingSources: [.paypal, .paylater],
shippingPreference: .getFromFile
),
applePay: DropInApplePayConfig(
shippingContactConfiguration: DropInApplePayShippingContactConfiguration(
requireShippingContactFields: [.postalAddress, .name]
)
),
paze: DropInPazeConfig(
emailAddress: "customer@example.com",
phoneNumber: "15551234567"
)
)For detailed payment method configuration, see:
Customise text displayed in the Drop-in interface by implementing the Localisation protocol. Override Drop-in-specific keys to replace default labels, messages, and accessibility strings. Unset properties fall back to the built-in strings for your configured locale.
The following table lists the main Drop-in localisation keys:
| Property | Description |
|---|---|
submitTextString? | Text for the submit or pay button in card and related flows. |
checkoutDropInHeaderTextString? | Header text shown at the top of Drop-in. |
checkoutDropInCardLabelString? | Label for the card payment method row. |
checkoutDropInPaypalLabelString? | Label for the PayPal payment method row. |
checkoutDropInApplePayLabelString? | Label for the Apple Pay payment method row. |
checkoutDropInGooglePayLabelString? | Label for Google Pay (reserved for future use). |
checkoutDropInCardOnFileTitleString? | Title for the saved cards section. |
checkoutDropInNewCardTitleString? | Title for the new card entry section. |
checkoutDropInBillingAddressTitleString? | Title for the billing address section. |
checkoutDropInSecuredByTextString? | “Secured by” branding text shown in Drop-in. |
checkoutDropInPxpBrandingTextString? | PXP branding text shown in Drop-in. |
checkoutDropInLoadingTextString? | Loading message shown while Drop-in initialises or processes payment. |
checkoutDropInNoPaymentMethodsErrorString? | Error message when no payment methods are available. |
checkoutDropInCheckoutPaymentSelectionAccessibilityLabelString? | VoiceOver label for the checkout payment selection region. |
checkoutDropInQuickPaymentMethodsAccessibilityLabelString? | VoiceOver label for the quick payment methods section. |
checkoutDropInPaymentMethodsAccessibilityLabelString? | VoiceOver label for the main payment methods list. |
checkoutDropInA11yPaymentMethodPrefixString? | VoiceOver prefix for payment method rows (accessibility). |
checkoutDropInA11yExpandedStateString? | VoiceOver label when a payment method panel is expanded. |
checkoutDropInA11yCollapsedStateString? | VoiceOver label when a payment method panel is collapsed. |
checkoutDropInA11yExpandedHintString? | VoiceOver hint when a panel is expanded. |
checkoutDropInA11yCollapsedHintString? | VoiceOver hint when a panel is collapsed. |
checkoutDropInA11yErrorPrefixString? | VoiceOver prefix for inline error messages. |
checkoutDropInA11yCheckoutReadyString? | VoiceOver announcement when checkout is ready. |
checkoutDropInA11yPaymentFailedString? | VoiceOver announcement when payment fails. |
checkoutDropInA11yLoadingPaymentMethodString? | VoiceOver announcement while a payment method is loading. |
// Implement a custom localisation type conforming to Localisation protocol
struct MyDropInLocalisation: Localisation {
var submitText: String? { "Pay Now" }
var checkoutDropInHeaderText: String? { "Choose Payment Method" }
var checkoutDropInCardLabel: String? { "Credit or Debit Card" }
var checkoutDropInPaypalLabel: String? { "PayPal" }
var checkoutDropInApplePayLabel: String? { "Apple Pay" }
// ... implement other required protocol properties
}
// Pass to Drop-in config
localisation: MyDropInLocalisation()Localisation is a large protocol shared across checkout components. You must implement all required properties, not only Drop-in keys. Use DefaultLocalisation() as a reference for property names — it returns nil for every override, so you typically implement a custom type that supplies your strings.
When locale is omitted, Drop-in defaults to "en-US". It does not automatically follow the device language.
Set an explicit locale to control built-in SDK strings:
locale: "en-US" // or "es-ES", "el-GR"Drop-in ships built-in string bundles for the following locales:
| Locale | Language |
|---|---|
"en-US" | English (United States). Used when locale is omitted or unrecognised. |
"es-ES" | Spanish (Spain). |
"el-GR" | Greek (Greece). |
Any other locale value falls back to "en-US" strings. Custom Localisation overrides apply on top of the selected bundle.
Pass hyphenated locale values to CheckoutDropInConfig.locale (for example "en-US"). PayPal validation may use underscore format internally (en_US); you do not need to convert values in app code.
Limit accepted card types by owner segment and funding source at checkout. Restrictions apply during card submission after BIN lookup — they filter which cards customers can pay with.
Set restrictions on CheckoutDropInConfig or in session data. When both are present, the SDK merges them as a union (session values first, then config values not already present).
restrictions: Restrictions(
card: Restrictions.Card(
ownerTypes: [.consumer], // Consumer cards only
fundingSources: [.credit, .debit] // Exclude prepaid
)
)The following table describes restriction properties:
| Property | Description |
|---|---|
restrictionsRestrictions? | Optional checkout-level card restrictions on CheckoutDropInConfig. Merged with session.restrictions when both are set. |
restrictions.card.ownerTypes[CardOwnerType]? | Allowed card owner segments. Omit to allow all owner types configured in the merged restriction set. Possible values:
|
restrictions.card.fundingSources[CardFundingSource]? | Allowed funding sources. Omit to allow all funding sources in the merged restriction set. Possible values:
|
methodConfig.global.allowedCardFundingSource is separate from restrictions. It controls Apple Pay merchant capabilities (.credit and .debit only) and does not replace session or checkout card restrictions for manual card entry.
Control Kount device data collection:
kountDisabled: false // Set to true to disable KountDefaults to false (Kount enabled).
To pass transaction risk screening data to the payment flow, use methodConfig.global.riskScreeningData:
methodConfig: DropInMethodConfig(
global: DropInGlobalConfig(
riskScreeningData: RiskScreeningData(
performRiskScreening: true,
userIp: "203.0.113.10",
transaction: RiskScreeningTransaction(subtotal: 149.99)
)
)
)The difference between these two settings:
kountDisabled: controls whether Kount device data is collected during the checkout flow.methodConfig.global.riskScreeningData: provides transaction-level risk data that is sent with card, Apple Pay, and PayPal Drop-in payment requests.
When Kount is enabled, the SDK injects the device session ID at authorisation time — you don't pass it in RiskScreeningData.
Fetch a session from your backend, then initialise Drop-in with required fields and core callbacks:
import SwiftUI
import PXPCheckoutSDK
// Get session from backend
let sessionData = try await fetchSessionFromBackend()
let config = CheckoutDropInConfig(
environment: .test,
session: sessionData,
transactionData: DropInTransactionData(
amount: Decimal(string: "99.99") ?? 0,
currency: "USD",
entryType: .ecom,
intent: DropInTransactionIntentData(
card: .authorisation,
paypal: .authorisation
),
merchantTransactionId: UUID().uuidString,
merchantTransactionDate: { Date() }
),
merchantShopperId: "shopper-123",
ownerId: "MERCHANT-1",
onGetShopper: { async in
TransactionShopper(id: "shopper-123")
},
onSuccess: { result in
Task {
await verifyPaymentOnBackend(result)
}
},
onError: { paymentMethod, error in
print("Payment failed: \(error.errorMessage)")
}
)
let dropIn = try CheckoutDropIn(config: config)
await dropIn.create()Render in SwiftUI with dropIn.buildContent().
Use this pattern when you need validation gates, loading state, analytics, and detailed error handling:
import SwiftUI
import PXPCheckoutSDK
let sessionData = try await fetchSessionFromBackend()
let orderId = "order-12345"
let config = CheckoutDropInConfig(
// REQUIRED
environment: .live,
session: sessionData,
transactionData: DropInTransactionData(
amount: Decimal(string: "149.99") ?? 0,
currency: "USD",
entryType: .ecom,
intent: DropInTransactionIntentData(
card: .authorisation,
paypal: .purchase
),
merchantTransactionId: "order-\(orderId)",
merchantTransactionDate: { Date() }
),
merchantShopperId: "shopper-456",
ownerId: "MERCHANT-1",
locale: "en-US",
kountDisabled: false,
// CALLBACKS
onGetShopper: { async in
TransactionShopper(
id: "shopper-456",
email: "customer@example.com"
)
},
onBeforeSubmit: { paymentMethod in
print("Payment method selected: \(paymentMethod.rawValue)")
// Custom validation — return false to cancel payment
guard await validateOrder(orderId) else {
return false
}
guard await checkInventory(orderId) else {
return false
}
return true
},
onSubmit: { paymentMethod in
print("Payment processing started for: \(paymentMethod.rawValue)")
showLoadingIndicator()
},
onSuccess: { result in
hideLoadingIndicator()
// CRITICAL: Verify on backend before fulfilling
Task {
do {
let verified = try await verifyPaymentOnBackend(
systemTransactionId: result.systemTransactionId,
merchantTransactionId: result.merchantTransactionId ?? "",
orderId: orderId
)
if verified.success {
navigateToOrderConfirmation(orderId: verified.orderId)
} else {
showError("Payment verification failed. Please contact support.")
}
} catch {
showError("Unable to verify payment. Please contact support.")
}
}
},
onError: { paymentMethod, error in
hideLoadingIndicator()
let userMessage: String
switch error.errorCode {
case "SDK1116" where error.errorMessage.localizedCaseInsensitiveContains("declined"):
userMessage = "Card declined. Please try a different card."
case "SDK1116" where error.errorMessage.localizedCaseInsensitiveContains("insufficient"):
userMessage = "Insufficient funds."
case "SDK1114":
userMessage = "Card verification failed."
case "SDK0500":
userMessage = "Connection error. Check your internet connection."
default:
if error.errorMessage.localizedCaseInsensitiveContains("session") ||
error.errorMessage.localizedCaseInsensitiveContains("expired") {
userMessage = "Session expired. Please refresh checkout."
} else {
userMessage = "Payment failed: \(error.errorMessage)"
}
}
showError(userMessage)
},
analyticsEvent: { event in
print("Analytics: \(event.eventName)")
sendToAnalyticsPlatform(event)
}
)
let dropIn = try CheckoutDropIn(config: config)
await dropIn.create()For payment-method-specific settings (methodConfig, restrictions, Apple Pay shipping handlers and similar), see Payment method configuration above and the linked method guides.
Drop-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.
When global or card config values are omitted, the SDK falls back as follows:
| Config value | Fallback behaviour |
|---|---|
methodConfig.global.acceptedCardNetworks | Falls back to session cardSchemes, then cards. If neither is present, no card networks are applied. |
methodConfig.global.allowedCardFundingSource | Falls back to [.credit, .debit] for Apple Pay merchant capabilities. Does not read session restrictions. |
methodConfig.global.allowedIssuerCountryCodes | Falls back to nil — no issuer country filter is applied to Apple Pay supportedCountries. |
methodConfig.global.transactionInfo | Falls back to a basic Apple Pay total using transaction amount and currency (totalLabel defaults to "TOTAL"). |
methodConfig.global.shippingOptions | Falls back to empty list (no shipping options displayed). |
methodConfig.global.couponInfo | Falls back to nil (no coupon information displayed). |
methodConfig.global.onGetConsent | Falls back to omitted — drop-in uses built-in consent UI where configured (card storage checkbox when site storeCardConsent is Ask; PayPal consent when consentComponent is enabled). |
methodConfig.global.onCancel | Falls back to no-op (cancel events are not captured). |
When Apple Pay config values are omitted, the SDK falls back as follows:
| Config value | Fallback behaviour |
|---|---|
methodConfig.applePay.shippingContactConfiguration | Falls back to no required shipping fields. |
methodConfig.applePay.billingContactConfiguration | Falls back to no required billing fields. |
methodConfig.applePay.onShippingContactSelected | Falls back to no shipping contact update (original transaction info used). |
methodConfig.applePay.onShippingMethodSelected | Falls back to no shipping method update (original transaction info used). |
methodConfig.applePay.onPaymentMethodSelected | Falls back to no payment method update (original transaction info used). |
methodConfig.applePay.onCouponCodeChanged | Falls back to no coupon code processing. |
When PayPal config values are omitted, the SDK falls back as follows:
| Config value | Fallback behaviour |
|---|---|
methodConfig.paypal.fundingSources | Falls back to session allowedFundingTypes.wallets.paypal.allowedFundingOptions. If neither merchant config nor session lists options, no PayPal buttons are rendered. |
methodConfig.paypal.shippingPreference | Falls back to .noShipping (no shipping address collected by PayPal). |
methodConfig.paypal.payeeEmailAddress | Falls back to nil (no payee email displayed). |
methodConfig.paypal.paymentDescription | Falls back to nil (PayPal uses its default order description behaviour). |
methodConfig.paypal.consentComponent | Falls back to true (PayPal consent component shown when PayPal is enabled). |
When integrating Checkout Drop-in at scale:
- Session management: cache session data appropriately but respect the
sessionExpirytimestamp. Create new sessions for new checkout attempts. - Error handling: implement comprehensive error handling for all callbacks. Log errors with sufficient context for debugging.
- Backend verification: always verify payment results on your backend before fulfilling orders. Frontend callbacks can be manipulated.
- Analytics: implement
analyticsEventto monitor drop-in performance, conversion rates, and error patterns. - Testing: test with all enabled payment methods in both test and live environments before going to production.
- Cards: configure card-specific settings.
- PayPal: configure PayPal-specific settings.
- Apple Pay: configure Apple Pay-specific settings.
- Events: learn about all available callbacks.
- Error handling: implement robust error handling.