Skip to content

Analytics

Get actionable, trackable data to support decisions and performance on iOS.

Overview

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.

Consume an event

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.

Supported events

Each row is the string in event.eventName. Every event also includes eventName, sessionId, and timestamp from BaseAnalyticsEvent.

Event nameStructure
DeviceTypedeviceType
CustomerClickelementId
CardBrandTypecardBrand
CardDeletionelementId, cardStatus, cardBrand
ChangePreselectedCardClickcomponentId
ComponentAbandonmentcomponentType
ComponentErrorerrorCode, errorMessage, componentId
ComponentInteractioninteractionType, componentId, componentType
ComponentLifecycleEventeventType, componentId
CVVFillTimestartTimeStamp, endTimeStamp, duration
EditCardClickeditedFields, elementId
ErrorMessageShownmessageContent, elementId, componentType
OneclickPaymentCompletionTimestartTimeStamp, endTimeStamp, duration
OneclickPaymentConfirmed
PaymentAbandonmentcomponentType
PayButtonClickcardBrand, cardType, componentId
PreInitiateAuthenticationcomponentType, transactionId, isRetry
PostInitiateAuthenticationcomponentType, transactionId, isRetry
PreAuthenticationcomponentType, transactionId, isRetry
PostAuthenticationcomponentType, transactionId, isRetry
PreTokenizationcomponentType, transactionId
PostTokenizationcomponentType, transactionId
PreAuthorisationcomponentType, transactionId, isRetry
PostAuthorisationcomponentType, transactionId, isRetry
SecurityCheckcheckType

Property names match the Swift types (for example TokenListFillCVVTimerAnalyticsEvent uses startTimeStamp / endTimeStamp).

Event data

NameDescription
cardBrandCard brand (for example scheme name).
cardStatusCard state (for example expired).
cardTypeFunding or token classification as reported by the SDK.
checkTypeSecurity or callback identifier for SecurityCheck.
componentIdComponent instance identifier.
componentTypeLogical type (for example NewCard, ClickOnce).
durationElapsed time in milliseconds where timing events apply.
editedFieldsFields edited in token list flows.
elementIdUI element identifier.
endTimeStampInterval end (Unix-style stamp where used).
errorCodeMachine-readable error code when present.
errorMessageHuman-readable error text.
eventNameEvent discriminator string.
eventTypeLifecycle subtype (mount, unmount, etc.).
interactionTypefocus, blur, paste, change, onSubmit, …
isRetryWhether the step is part of a retry path (retryable lifecycle events).
messageContentText shown to the shopper (trim before logging externally).
sessionIdCheckout session ID.
startTimeStampInterval start (Unix-style stamp where used).
timestampWhen the event was created.
transactionIdTransaction identifier when allocated.

JSON and forwarding

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.

Practices and privacy

  • 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 messageContent and errorMessage before they leave the device.