Get actionable, trackable data to support decisions and performance on iOS.
The SDK emits structured analytics events when important actions or states occur (lifecycle, interactions, tokenisation, 3DS, authorisation, errors, and more). You handle them in one place: CheckoutConfig.analyticsEvent.
Analytics help you:
- See the full journey from field interaction through tokenisation, 3DS (when enabled), and authorisation.
- Optimise conversion by correlating abandonment, validation-style signals, and errors with funnel steps.
- Feed data into your analytics or CRM tools (subject to privacy and consent).
This is checkout-level telemetry. Component config callbacks (onChange, onSubmitError, etc.) are separate — see Events. Validation-related signals appear as ComponentErrorAnalyticsEvent or ComponentInteractionAnalyticsEvent.
Pass a closure when you build CheckoutConfig. The SDK calls it from checkout and component code (including submitAsync()). Keep the closure fast; move network I/O or heavy work to Task.detached or your own queue so you don't block the main thread.
import PXPCheckoutSDK
let checkoutConfig = CheckoutConfig(
environment: .test,
session: sessionData,
transactionData: transactionData,
merchantShopperId: "shopper-id",
ownerType: "MerchantGroup",
ownerId: "your-owner-id",
analyticsEvent: { event in
switch event {
case let e as ComponentErrorAnalyticsEvent:
print(e.errorCode ?? "", e.errorMessage)
case let e as ComponentInteractionAnalyticsEvent:
print(e.componentType, e.interactionType)
case let e as PaymentLifecycleAnalyticsEvent:
print(e.eventName, e.transactionId)
case let e as RetryablePaymentLifecycleAnalyticsEvent:
print(e.eventName, e.isRetry)
default:
print(event.eventName)
}
Task.detached(priority: .utility) {
await forwardToYourPipeline(event)
}
}
)
let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)Use switch / as? on concrete subclasses so you can read typed properties. Tokenisation milestones (PreTokenizationAnalyticsEvent, PostTokenizationAnalyticsEvent) extend PaymentLifecycleAnalyticsEvent (componentType, transactionId). 3DS and authorisation milestones extend RetryablePaymentLifecycleAnalyticsEvent (componentType, transactionId, isRetry). Those two bases are sibling subclasses of BaseAnalyticsEvent, not parent and child.
Apple Pay and PayPal define additional event types in PXPCheckoutSDK; the table focuses on card-related names.
Each row is the string in event.eventName. Every event also includes eventName, sessionId, and timestamp from BaseAnalyticsEvent.
| Event name | Structure |
|---|---|
DeviceType | deviceType |
CustomerClick | elementId |
CardBrandType | cardBrand |
CardDeletion | elementId, cardStatus, cardBrand |
ChangePreselectedCardClick | componentId |
ComponentAbandonment | componentType |
ComponentError | errorCode, errorMessage, componentId |
ComponentInteraction | interactionType, componentId, componentType |
ComponentLifecycleEvent | eventType, componentId |
CVVFillTime | startTimeStamp, endTimeStamp, duration |
EditCardClick | editedFields, elementId |
ErrorMessageShown | messageContent, elementId, componentType |
OneclickPaymentCompletionTime | startTimeStamp, endTimeStamp, duration |
OneclickPaymentConfirmed | — |
PaymentAbandonment | componentType |
PayButtonClick | cardBrand, cardType, componentId |
PreInitiateAuthentication | componentType, transactionId, isRetry |
PostInitiateAuthentication | componentType, transactionId, isRetry |
PreAuthentication | componentType, transactionId, isRetry |
PostAuthentication | componentType, transactionId, isRetry |
PreTokenization | componentType, transactionId |
PostTokenization | componentType, transactionId |
PreAuthorisation | componentType, transactionId, isRetry |
PostAuthorisation | componentType, transactionId, isRetry |
SecurityCheck | checkType |
Property names match the Swift types (for example TokenListFillCVVTimerAnalyticsEvent uses startTimeStamp / endTimeStamp).
| Name | Description |
|---|---|
cardBrand | Card brand (for example scheme name). |
cardStatus | Card state (for example expired). |
cardType | Funding or token classification as reported by the SDK. |
checkType | Security or callback identifier for SecurityCheck. |
componentId | Component instance identifier. |
componentType | Logical type (for example NewCard, ClickOnce). |
duration | Elapsed time in milliseconds where timing events apply. |
editedFields | Fields edited in token list flows. |
elementId | UI element identifier. |
endTimeStamp | Interval end (Unix-style stamp where used). |
errorCode | Machine-readable error code when present. |
errorMessage | Human-readable error text. |
eventName | Event discriminator string. |
eventType | Lifecycle subtype (mount, unmount, etc.). |
interactionType | focus, blur, paste, change, onSubmit, … |
isRetry | Whether the step is part of a retry path (retryable lifecycle events). |
messageContent | Text shown to the shopper (trim before logging externally). |
sessionId | Checkout session ID. |
startTimeStamp | Interval start (Unix-style stamp where used). |
timestamp | When the event was created. |
transactionId | Transaction identifier when allocated. |
BaseAnalyticsEvent subclasses conform to Encodable. Use JSONEncoder with dateEncodingStrategy = .iso8601 and encode the runtime subclass if you need full payloads for an API.
func encodeEvent(_ event: BaseAnalyticsEvent) -> Data? {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
// Cast to each concrete type you persist — encoding as BaseAnalyticsEvent
// does not include subclass-specific keys.
switch event {
case let e as ComponentErrorAnalyticsEvent: return try? encoder.encode(e)
case let e as PaymentLifecycleAnalyticsEvent: return try? encoder.encode(e)
case let e as RetryablePaymentLifecycleAnalyticsEvent: return try? encoder.encode(e)
default: return nil
}
}For Firebase Analytics, names and parameter lengths are limited — see Firebase event limits. Truncate errorMessage / messageContent (for example to 100 characters) and normalise eventName to allowed characters before Analytics.logEvent.
- Filter noisy events in production if you only care about errors and payment milestones.
- Never let a logging failure break checkout — wrap third-party SDK calls and swallow or degrade gracefully.
- Obtain consent where required; avoid exporting data that could identify users when combined with other sources.
- Don't log PAN/CVC; review
messageContentanderrorMessagebefore they leave the device.