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 the analyticsEvent callback on PxpSdkConfig when you build PxpCheckout because events aren't emitted if the handler is omitted.
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 PxpSdkConfig when you build PxpCheckout. Configure the handler and branch on eventName or the Kotlin event type:
val sdkConfig = PxpSdkConfig(
environment = Environment.TEST,
session = sessionData,
transactionData = transactionData,
clientName = "Your merchant name",
siteName = "Your store",
onGetShopper = {
Shopper(id = "shopper-123", email = "customer@example.com")
},
analyticsEvent = { event ->
if (event is PazeButtonClickAnalyticsEvent) {
Log.d("Paze", "Button clicked ${event.componentId} ${event.merchantTransactionId}")
}
if (event is PazeCheckoutCompletedAnalyticsEvent) {
Log.d("Paze", "Checkout completed ${event.merchantTransactionId}")
}
if (event is PazeAuthorisationFailedAnalyticsEvent) {
Log.e("Paze", "Authorisation failed ${event.additionalData}")
}
},
)
val checkout = PxpCheckout.builder()
.withConfig(sdkConfig)
.withContext(context)
.build()Handle every Paze-specific event through a single PazeAnalyticsEvent branch:
analyticsEvent = { event ->
if (event is PazeAnalyticsEvent) {
trackPazeEvent(
name = event.eventName,
sessionId = event.sessionId,
componentId = event.componentId,
merchantTransactionId = event.merchantTransactionId,
additionalData = event.additionalData,
)
}
}Custom Tab availability isn't emitted as a dedicated Paze analytics event. Instead, track it with onPresentmentResolved on the Paze button component:
config.onPresentmentResolved = { customTabAvailable ->
trackMetric("paze_custom_tab_available", mapOf("customTabAvailable" to customTabAvailable))
}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 | Kotlin type | Structure |
|---|---|---|
PazeButtonRendered | PazeButtonRenderedAnalyticsEvent |
|
PazeButtonClicked | PazeButtonClickAnalyticsEvent |
|
PazePopupLaunched | PazePopupLaunchedAnalyticsEvent |
|
PazeCheckoutCompleted | PazeCheckoutCompletedAnalyticsEvent |
|
PazeCheckoutAbandoned | PazeCheckoutAbandonedAnalyticsEvent |
|
PazeDecryptionInitiated | PazeDecryptionInitiatedAnalyticsEvent |
|
PazeDecryptionCompleted | PazeDecryptionCompletedAnalyticsEvent |
|
PazeDecryptionFailed | PazeDecryptionFailedAnalyticsEvent |
|
PazeAuthorisationFailed | PazeAuthorisationFailedAnalyticsEvent |
|
PazeSdkInitialisationFailed | PazeSdkInitialisationFailedAnalyticsEvent |
|
PazeCheckoutFailed | PazeCheckoutFailedAnalyticsEvent |
|
PazeCompleteFailed | PazeCompleteFailedAnalyticsEvent |
|
These events don't extend PazeAnalyticsEvent:
| Event name | Kotlin type | Structure |
|---|---|---|
PreAuthorisation | PreAuthorisationAnalyticsEvent |
|
PostAuthorisation | PostAuthorisationAnalyticsEvent |
|
PazeTransactionInitiated | PaymentLifecycleAnalyticsEvent |
|
PazeAuthorisationCancelled | PaymentLifecycleAnalyticsEvent |
|
PazeTokenDecryptionCancelled | PazeDecryptionCancelledAnalyticsEvent |
|
ComponentLifecycleEvent | ComponentLifecycleAnalyticsEvent |
|
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. Invalid Kount riskScreeningData throws a ValidationException surfaced through onSubmitError without a PazeAuthorisationFailed event.
All Paze analytics events extend PazeAnalyticsEvent and include:
| Name | Description |
|---|---|
eventName | The name of the event (for example, PazeButtonClicked). |
timestamp | Milliseconds since epoch 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 events with PazeErrorAnalyticsData (errorCode, errorMessage) or on abandonment events with PazeReasonAnalyticsData (reason); otherwise null. |
Shared lifecycle events add:
| Name | Description |
|---|---|
componentType | Paze for PreAuthorisation and PostAuthorisation; PazeButton for PazeTransactionInitiated and PazeAuthorisationCancelled. |
transactionId | The merchant transaction identifier on lifecycle events. |
isRetry | Whether the lifecycle event is a retry (PreAuthorisation / PostAuthorisation only). |
The following table describes when each analytics event fires during a Paze payment:
| Event name | Trigger |
|---|---|
PazeButtonRendered | Presentment validation succeeds and the button becomes visible, when the component Content() is composed. |
PazeButtonClicked | After checkout validation passes: onPazeButtonClicked runs, then this event fires, then the SDK calls create-session and opens the Custom Tab. |
PazePopupLaunched | Create-session succeeds and the Paze checkout Custom Tab opens. |
PazeCheckoutCompleted | Paze checkout returns COMPLETE and the merchant approves at onCheckoutComplete. |
PazeCheckoutAbandoned | Checkout is incomplete, the shopper cancels, the Custom Tab closes without a redirect, or merchant validation rejects checkout. |
PazeDecryptionInitiated | After onComplete, when the SDK enters the decryption flow — immediately before onPreDecryption. Also fires when onPreDecryption returns false (followed by PazeTokenDecryptionCancelled). |
PazeDecryptionCompleted | SDK decryption succeeds. Not emitted when onPreDecryption returns false. |
PazeDecryptionFailed | SDK decryption fails (onError with SDK1233). |
PazeCompleteFailed | The complete API call fails (onError also fires). |
PazeCheckoutFailed | Checkout validation fails when the shopper taps the button, or the create-session API call fails. Not emitted for Custom Tab launch failures (onError only). |
PazeAuthorisationFailed | Transaction submission fails or the Unity response reports an error state. |
PazeSdkInitialisationFailed | Presentment validation fails (button hidden). |
PazeTokenDecryptionCancelled | onPreDecryption returns false (merchant-managed decryption). Authorisation analytics events do not follow. |
PazeAuthorisationCancelled | onPreAuthorisation is configured and 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. |
PostAuthorisation | onPostAuthorisation is configured and the SDK receives a MerchantSubmitResult, immediately before your callback runs. componentType is Paze. PazeAuthorisationFailed may also fire if the response reports an error state. Not emitted on the merchant-managed decryption path. |
ComponentLifecycleEvent | The component mounts after presentment succeeds (Mount, when Content() is composed — emitted once, before PazeButtonRendered), or unmounts when removed from the UI (Unmount). |
onPazeButtonClicked runs when the shopper taps the button, after checkout validation. The PazeButtonClicked analytics event fires immediately afterwards, before the Custom Tab opens.
One-line descriptions of each Paze-related analytics event:
| Event name | Description |
|---|---|
PazeButtonRendered | Button became visible after presentment validation. |
PazeButtonClicked | Shopper tapped the native Paze button. |
PazePopupLaunched | Paze checkout Custom Tab opened. |
PazeCheckoutCompleted | Checkout returned COMPLETE and the merchant approved at onCheckoutComplete. |
PazeCheckoutAbandoned | Checkout incomplete, shopper cancelled, Custom Tab closed without redirect, or merchant rejected at onCheckoutComplete. |
PazeDecryptionInitiated | SDK entered the decryption flow (before onPreDecryption). |
PazeDecryptionCompleted | SDK decrypt succeeded; not emitted on the merchant-managed path. |
PazeDecryptionFailed | Decrypt request failed (onError with SDK1233). |
PazeTokenDecryptionCancelled | Merchant returned false from onPreDecryption. |
PazeCompleteFailed | Paze complete API call failed (onError also fires). |
PazeCheckoutFailed | Checkout validation failed on tap, or create-session failed; not emitted for Custom Tab launch failures. |
PazeAuthorisationFailed | Transaction submission failed or Unity returned an error state. |
PazeSdkInitialisationFailed | Presentment validation failed (button hidden). |
PazeTransactionInitiated | Authorisation request sent to the Unity API. |
PazeAuthorisationCancelled | onPreAuthorisation configured and returned Cancel. |
PreAuthorisation | Shared lifecycle event when configured onPreAuthorisation proceeds (Proceed or TransactionInitData). |
PostAuthorisation | Shared lifecycle event when onPostAuthorisation is configured and Unity returns MerchantSubmitResult, before your callback runs. |
ComponentLifecycleEvent | Component mounted or unmounted (Mount / Unmount). |
PazeAuthorisationInitiatedAnalyticsEvent and PazeAuthorisationCompletedAnalyticsEvent exist in the SDK but aren't emitted by the Paze button component. Use PazeTransactionInitiated and PostAuthorisation instead.
Use merchantTransactionId to correlate analytics events with server-side logs and PXP reports.
Forward Paze analytics events to Firebase by type:
analyticsEvent = { event ->
when (event) {
is PazeButtonClickAnalyticsEvent -> {
Firebase.analytics.logEvent("paze_button_click") {
param("component_id", event.componentId)
param("merchant_transaction_id", event.merchantTransactionId)
param("session_id", event.sessionId)
}
}
is PazeCheckoutCompletedAnalyticsEvent -> {
Firebase.analytics.logEvent("paze_checkout_complete") {
param("merchant_transaction_id", event.merchantTransactionId)
param("session_id", event.sessionId)
}
}
is PazeAuthorisationFailedAnalyticsEvent -> {
Firebase.analytics.logEvent("paze_authorisation_failed") {
param("merchant_transaction_id", event.merchantTransactionId)
param("session_id", event.sessionId)
}
}
}
}Build a complete picture of your Paze conversion funnel by combining SDK analytics events with onPresentmentResolved:
val funnelStages = mutableMapOf(
"customTabAvailable" to 0,
"buttonRendered" to 0,
"buttonClicked" to 0,
"checkoutCompleted" to 0,
"decryptionCompleted" to 0,
"paymentAuthorised" to 0,
)
config.onPresentmentResolved = { customTabAvailable ->
if (customTabAvailable) {
funnelStages["customTabAvailable"] = funnelStages.getValue("customTabAvailable") + 1
}
}
val sdkConfig = PxpSdkConfig(
// ... session and transactionData
analyticsEvent = { event ->
when (event) {
is PazeButtonRenderedAnalyticsEvent ->
funnelStages["buttonRendered"] = funnelStages.getValue("buttonRendered") + 1
is PazeButtonClickAnalyticsEvent ->
funnelStages["buttonClicked"] = funnelStages.getValue("buttonClicked") + 1
is PazeCheckoutCompletedAnalyticsEvent ->
funnelStages["checkoutCompleted"] = funnelStages.getValue("checkoutCompleted") + 1
is PazeDecryptionCompletedAnalyticsEvent ->
funnelStages["decryptionCompleted"] = funnelStages.getValue("decryptionCompleted") + 1
is PostAuthorisationAnalyticsEvent ->
if (event.componentType == "Paze") {
// Only emitted when onPostAuthorisation is registered on the component config
funnelStages["paymentAuthorised"] = funnelStages.getValue("paymentAuthorised") + 1
Log.d("Paze", "Conversion funnel: $funnelStages")
}
else -> Unit
}
},
)Track operational failures using Paze failure events:
Route Paze failure analytics events to your error tracking service:
analyticsEvent = { event ->
when (event) {
is PazeDecryptionFailedAnalyticsEvent,
is PazeAuthorisationFailedAnalyticsEvent,
is PazeSdkInitialisationFailedAnalyticsEvent,
is PazeCheckoutFailedAnalyticsEvent,
is PazeCompleteFailedAnalyticsEvent,
-> {
if (event is PazeAnalyticsEvent) {
trackError("paze_flow_error", mapOf(
"eventName" to event.eventName,
"merchantTransactionId" to event.merchantTransactionId,
"additionalData" to event.additionalData.toString(),
))
}
}
else -> Unit
}
}The SDK also emits ComponentLifecycleEvent with eventType: Mount when presentment succeeds. This is separate from PazeButtonRendered. Custom Tab launch failures surface through onError only — there's no dedicated analytics event. Types such as PazeAuthorisationInitiatedAnalyticsEvent and PazeAuthorisationCompletedAnalyticsEvent exist in the SDK but aren't emitted by the Paze button component; use PazeTransactionInitiated and PostAuthorisation instead.