Get actionable, trackable data instantly to drive better decisions and performance.
Analytics events are structured data objects automatically triggered when significant actions or states occur during a Paze payment. Configure a single handler on CheckoutConfig to monitor every stage of the payment journey.
Analytics events allow you to:
- Gain transparency with native transaction tracking in PXP reports.
- Optimise conversion rates and reduce drop-offs, thanks to actionable insights.
- Feed real-time data into your analytics and CRM systems.
Analytics events are delivered through the analyticsEvent callback on CheckoutConfig when you initialise PxpCheckout:
let checkoutConfig = CheckoutConfig(
environment: .test,
session: sessionData,
transactionData: transactionData,
merchantShopperId: "shopper-123",
ownerId: "MERCHANT-GROUP-1",
clientName: "Your Merchant",
siteName: "Your Store",
onGetShopper: { async in
TransactionShopper(id: "shopper-123", email: "customer@example.com")
},
analyticsEvent: { event in
if let clickEvent = event as? PazeButtonClickAnalyticsEvent {
print("Paze button clicked", clickEvent.componentId, clickEvent.merchantTransactionId)
}
if let checkoutComplete = event as? PazeCheckoutCompletedAnalyticsEvent {
print("Paze checkout completed", checkoutComplete.merchantTransactionId)
}
if let authFailed = event as? PazeAuthorisationFailedAnalyticsEvent {
print("Paze authorisation failed", String(describing: authFailed.additionalData))
}
}
)
let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)To handle all Paze-specific events with one branch, cast to PazeAnalyticsEvent:
analyticsEvent: { event in
if let pazeEvent = event as? PazeAnalyticsEvent {
trackPazeEvent(
name: pazeEvent.eventName,
sessionId: pazeEvent.sessionId,
componentId: pazeEvent.componentId,
merchantTransactionId: pazeEvent.merchantTransactionId,
additionalData: pazeEvent.additionalData
)
}
}Button visibility isn't emitted as a dedicated analytics event. Instead, track presentment with onPresentmentResolved on the Paze button component:
config.onPresentmentResolved = { isVisible in
trackMetric("paze_button_visible", properties: ["isVisible": isVisible])
}The following tables list events you can receive during a Paze payment. Paze-specific events extend PazeAnalyticsEvent. Shared lifecycle events use different structures, so check eventName and componentType when filtering.
Events that extend PazeAnalyticsEvent:
| Event name | Swift type | Structure |
|---|---|---|
PazeButtonRendered | PazeButtonRenderedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType |
PazeButtonClicked | PazeButtonClickAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType |
PazePopupLaunched | PazePopupLaunchedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType |
PazeCheckoutCompleted | PazeCheckoutCompletedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType |
PazeCheckoutAbandoned | PazeCheckoutAbandonedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType, additionalData |
PazeDecryptionInitiated | PazeDecryptionInitiatedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType |
PazeDecryptionCompleted | PazeDecryptionCompletedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType |
PazeDecryptionFailed | PazeDecryptionFailedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType, additionalData |
PazeAuthorisationFailed | PazeAuthorisationFailedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType, additionalData |
PazeSdkInitialisationFailed | PazeSdkInitialisationFailedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType, additionalData |
PazeCheckoutFailed | PazeCheckoutFailedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType, additionalData |
PazeCompleteFailed | PazeCompleteFailedAnalyticsEvent | eventName, timestamp, sessionId, componentId, merchantTransactionId, walletType, additionalData |
These events don't extend PazeAnalyticsEvent:
| Event name | Swift type | Structure |
|---|---|---|
PreAuthorisation | PreAuthorisationAnalyticsEvent | eventName, timestamp, sessionId, componentType, transactionId, isRetry |
PostAuthorisation | PostAuthorisationAnalyticsEvent | eventName, timestamp, sessionId, componentType, transactionId, isRetry |
PazeTransactionInitiated | PaymentLifecycleAnalyticsEvent | eventName, timestamp, sessionId, componentType, transactionId |
PazeAuthorisationCancelled | PaymentLifecycleAnalyticsEvent | eventName, timestamp, sessionId, componentType, transactionId |
PazeTokenDecryptionCancelled | PaymentLifecycleAnalyticsEvent | eventName, timestamp, sessionId, componentType, transactionId |
ComponentError | ComponentErrorAnalyticsEvent | eventName, timestamp, sessionId, errorCode, errorMessage, componentId |
PreAuthorisation is emitted only when you configure onPreAuthorisation and the flow proceeds (.proceed or .transactionInitData). Returning .cancel emits PazeAuthorisationCancelled instead. PostAuthorisation is emitted when you configure onPostAuthorisation and the SDK receives a MerchantSubmitResult, immediately before your callback runs. PazeAuthorisationFailed may also fire if the response reports an error state. Paze doesn't emit 3DS or tokenisation events such as PreAuthentication or PreTokenization.
All Paze analytics events extend PazeAnalyticsEvent and include:
| Name | Description |
|---|---|
eventName | The name of the event (for example, PazeButtonClicked). |
timestamp | The date and time when the event occurred. |
sessionId | The session's unique identifier. |
componentId | The Paze button component's unique identifier. |
merchantTransactionId | The merchant transaction identifier from SDK initialisation. |
walletType | Always Paze for Paze-specific events. |
additionalData | Present on all PazeAnalyticsEvent types. Populated on failure and abandonment events with error details, checkout reason, or FailedSubmitResult. Otherwise empty. |
Shared lifecycle events add:
| Name | Description |
|---|---|
componentType | "paze-button" for PreAuthorisation, PostAuthorisation, PazeTransactionInitiated, and cancellation events. |
transactionId | The merchant transaction identifier on lifecycle events. |
isRetry | Whether the lifecycle event is a retry (PreAuthorisation / PostAuthorisation only). |
| Event name | Trigger |
|---|---|
PazeButtonRendered | Presentment validation succeeds and the button becomes visible. |
PazeButtonClicked | Checkout-time validation passes after the shopper taps the button, before the Paze web session opens. |
PazePopupLaunched | The Paze web checkout session opens in ASWebAuthenticationSession. |
PazeCheckoutCompleted | Paze checkout returns COMPLETE and merchant approves at onCheckoutComplete. |
PazeCheckoutAbandoned | Checkout is incomplete, the shopper cancels, or merchant validation rejects checkout. |
PazeDecryptionInitiated | The SDK begins decrypting the secured payload. |
PazeDecryptionCompleted | Decryption succeeds. |
PazeDecryptionFailed | Decryption fails. |
PazeCompleteFailed | The complete API call fails. |
PazeCheckoutFailed | The checkout flow fails with an error. |
PazeAuthorisationFailed | Transaction submission fails. |
PazeSdkInitialisationFailed | Presentment validation fails (button hidden). |
PazeTokenDecryptionCancelled | onPreDecryption returns false. |
PazeAuthorisationCancelled | onPreAuthorisation returns .cancel. |
PazeTransactionInitiated | Authorisation request is sent to the Unity API. |
PreAuthorisation | onPreAuthorisation is configured and the flow proceeds (.proceed or .transactionInitData). Returning .cancel emits PazeAuthorisationCancelled instead. componentType is "paze-button". |
PostAuthorisation | onPostAuthorisation is configured and the SDK receives a MerchantSubmitResult, immediately before your callback runs. componentType is "paze-button". PazeAuthorisationFailed may also fire if the response reports an error state. |
ComponentError | Component validation fails (for example, invalid Kount risk screening data). |
onPazeButtonClicked fires when the shopper taps the button. The PazeButtonClicked analytics event fires only after checkout-time validation succeeds, immediately before the Paze web session opens.
Use merchantTransactionId to correlate analytics events with server-side logs and PXP reports.
import FirebaseAnalytics
analyticsEvent: { event in
if let clickEvent = event as? PazeButtonClickAnalyticsEvent {
Analytics.logEvent("paze_button_click", parameters: [
"component_id": clickEvent.componentId,
"merchant_transaction_id": clickEvent.merchantTransactionId,
"session_id": clickEvent.sessionId
])
}
if let checkoutComplete = event as? PazeCheckoutCompletedAnalyticsEvent {
Analytics.logEvent("paze_checkout_complete", parameters: [
"merchant_transaction_id": checkoutComplete.merchantTransactionId,
"session_id": checkoutComplete.sessionId
])
}
if let authFailed = event as? PazeAuthorisationFailedAnalyticsEvent {
Analytics.logEvent("paze_authorisation_failed", parameters: [
"merchant_transaction_id": authFailed.merchantTransactionId,
"session_id": authFailed.sessionId
])
}
}analyticsEvent: { event in
if let clickEvent = event as? PazeButtonClickAnalyticsEvent {
Analytics.shared().track("Paze button clicked", properties: [
"componentId": clickEvent.componentId,
"merchantTransactionId": clickEvent.merchantTransactionId,
"sessionId": clickEvent.sessionId
])
}
if let checkoutComplete = event as? PazeCheckoutCompletedAnalyticsEvent {
Analytics.shared().track("Paze checkout completed", properties: [
"merchantTransactionId": checkoutComplete.merchantTransactionId,
"sessionId": checkoutComplete.sessionId
])
}
if let decryptionFailed = event as? PazeDecryptionFailedAnalyticsEvent {
Analytics.shared().track("Paze decryption failed", properties: [
"merchantTransactionId": decryptionFailed.merchantTransactionId,
"sessionId": decryptionFailed.sessionId
])
}
}Build a complete picture of your Paze conversion funnel by combining SDK analytics events with onPresentmentResolved:
var funnelStages: [String: Int] = [
"buttonVisible": 0,
"buttonRendered": 0,
"buttonClicked": 0,
"checkoutCompleted": 0,
"decryptionCompleted": 0,
"paymentAuthorised": 0
]
config.onPresentmentResolved = { isVisible in
if isVisible { funnelStages["buttonVisible", default: 0] += 1 }
}
let checkoutConfig = CheckoutConfig(
// ... session and transactionData
analyticsEvent: { event in
switch event {
case is PazeButtonRenderedAnalyticsEvent:
funnelStages["buttonRendered", default: 0] += 1
case is PazeButtonClickAnalyticsEvent:
funnelStages["buttonClicked", default: 0] += 1
case is PazeCheckoutCompletedAnalyticsEvent:
funnelStages["checkoutCompleted", default: 0] += 1
case is PazeDecryptionCompletedAnalyticsEvent:
funnelStages["decryptionCompleted", default: 0] += 1
case let postAuth as PostAuthorisationAnalyticsEvent where postAuth.componentType == "paze-button":
funnelStages["paymentAuthorised", default: 0] += 1
print("Paze conversion funnel:", funnelStages)
default:
break
}
}
)Track operational failures using Paze failure events and shared component errors:
let pazeButton = try pxpCheckout.create(.pazeButton, componentConfig: pazeConfig)
guard let pazeComponentId = (pazeButton as? PazeButtonComponent)?.containerId else {
return
}
analyticsEvent: { event in
if let componentError = event as? ComponentErrorAnalyticsEvent,
componentError.componentId == pazeComponentId {
trackError("paze_component_error", properties: [
"errorCode": componentError.errorCode ?? "",
"errorMessage": componentError.errorMessage,
"sessionId": componentError.sessionId
])
}
switch event {
case is PazeDecryptionFailedAnalyticsEvent,
is PazeAuthorisationFailedAnalyticsEvent,
is PazeSdkInitialisationFailedAnalyticsEvent,
is PazeCheckoutFailedAnalyticsEvent,
is PazeCompleteFailedAnalyticsEvent:
if let pazeEvent = event as? PazeAnalyticsEvent {
trackError("paze_flow_error", properties: [
"eventName": pazeEvent.eventName,
"merchantTransactionId": pazeEvent.merchantTransactionId,
"additionalData": String(describing: pazeEvent.additionalData)
])
}
default:
break
}
}PxpCheckout.create(_:componentConfig:) returns BaseComponent, which doesn't expose containerId. Cast to PazeButtonComponent, or capture componentId from the first PazeAnalyticsEvent in analyticsEvent if you prefer to avoid a cast.
The SDK also emits a generic ComponentLifecycleAnalyticsEvent with eventType: .mount for Paze when presentment validation succeeds (alongside PazeButtonRendered). Paze doesn't emit mount on first view attach if presentment hasn't completed. This is separate from PazeButtonRendered. Types such as PazeAuthorisationInitiatedAnalyticsEvent and PazeAuthorisationCompletedAnalyticsEvent exist in the SDK but aren't emitted by the Paze button component. Use PazeTransactionInitiated and PostAuthorisation instead.