Skip to content

Events

Implement callbacks to customise your Paze payment flow for Android.

Overview

The Paze component emits callbacks based on shopper interaction and payment flow state. Use them to inject business logic and UX customisations at critical moments. While the SDK handles checkout, decryption, and authorisation, you retain control over approval gates, error handling, and backend integration.

Callbacks enable you to:

  • Validate business rules before payments proceed.
  • Display custom error, failure, or success messages.
  • Integrate with fraud detection or customer management systems.
  • Control how shoppers experience successful and failed transactions.
  • Handle Paze Custom Tab checkout and decryption flow requirements.

SDK data callbacks

Configure these callbacks on PxpSdkConfig, not on the Paze button component. The Paze button calls onGetShopper when building the Unity transaction request after decryption.

  • onGetShopper (recommended): Called during authorisation to retrieve shopper data for the transaction payload.

onGetShopper

The SDK calls this callback when building the transaction request, after decryption and before Unity authorisation. If onGetShopper is not set, the SDK uses transactionData.shopper when present.

Configuration

val sdkConfig = PxpSdkConfig(
    environment = Environment.TEST,
    session = sessionData,
    transactionData = transactionData,
    clientName = "Your Merchant",
    siteName = "Your Store",
    ownerType = "MerchantGroup",
    ownerId = "MERCHANT-1",
    onGetShopper = {
        Shopper(
            id = "shopper-123",
            firstName = "John",
            lastName = "Doe",
            email = "customer@example.com",
        )
    },
)

Return value

PropertyDescription
id
String?
A unique shopper identifier. Return your customer account ID or a persistent guest session ID.
firstName
String?
The shopper's given name.
lastName
String?
The shopper's family name.
email
String?
The shopper's email address.
phoneNumber
String?
The contact phone number for the transaction shopper profile.
dateOfBirth
String?
The date of birth, when required by your integration or risk screening rules.
houseNumberOrName
String?
The first line of the shopper's address.
street
String?
The street name or remaining address line.
city
String?
The city or locality.
postalCode
String?
The postal or ZIP code.
countryCode
String?
The country code in ISO 3166-1 alpha-2 format (e.g., "US").
state
String?
The state, province, or region.

All properties are optional in the type, but you should always return an id so transactions can be linked to your customer records.

Paze wallet identity (emailAddress / phoneNumber on the component) is separate from onGetShopper. Component identity is forwarded to Paze during create-session when provided. onGetShopper supplies the shopper object sent to Unity during authorisation.

Shipping countries

For shipping constraints on Paze checkout, set acceptedShippingCountries on the component config. See Configuration.

Paze-specific events

Configure these callbacks on PazeButtonComponentConfig before calling createComponent<PazeButtonComponent>(...).

Callback order

For a successful payment, callbacks fire in this order:

  1. onInitonPresentmentResolved after presentment validation succeeds, when the component Content() is composed.
  2. onPazeButtonClicked when the shopper taps the button (after checkout validation, before the Custom Tab opens).
  3. onCheckoutComplete or onCheckoutIncomplete after the Custom Tab returns.
  4. onComplete after the complete API succeeds and the response is decoded.
  5. onPreDecryptiononPostDecryption (if SDK decryption proceeds).
  6. onPreAuthorisation → Unity authorisation (the SDK calls onGetShopper or transactionData.shopper here) → onPostAuthorisation (if registered) or onSubmitError.

onError handles presentment, checkout, complete, and decryption errors. onSubmitError handles authorisation submission failures, including invalid Kount riskScreeningData. Shopper cancellation is surfaced through onCheckoutIncomplete, not onError.

When onPreDecryption returns false, the SDK skips steps 5–6. Use onComplete to receive the securedPayload for backend decryption instead.

SDK initialisation callbacks are configured on PxpSdkConfig. The Paze button calls onGetShopper during authorisation. Paze component callbacks handle checkout, decryption, and authorisation events. Several Paze callbacks are suspend functions and can perform asynchronous work before the SDK continues.

onInit

Called after presentment validation succeeds, immediately before onPresentmentResolved on success.

config.onInit = {
    Log.d("Paze", "Component ready")
}

onPresentmentResolved

Called when presentment resolves.

ParameterDescription
customTabAvailable
Boolean
When presentment succeeds, true when a Custom Tab can launch; false when no compatible browser is installed (the button remains visible). When presentment validation fails, the button is hidden and this callback receives false (see onError).
config.onPresentmentResolved = { customTabAvailable ->
    if (!customTabAvailable) {
        showCustomTabWarning()
    }
}

onPazeButtonClicked

Called when the shopper taps the button, after checkout validation succeeds and before the Custom Tab opens. Checkout validation failures surface through onError, not this callback. Use it for analytics, clearing error messages, or showing a loading state.

onPazeButtonClicked is a component callback. The PazeButtonClicked analytics event is separate — it fires after onPazeButtonClicked completes and immediately before the Custom Tab opens. See Analytics.

config.onPazeButtonClicked = {
    clearErrorMessages()
}

The SDK opens the Custom Tab after this callback completes. There is no return value — you cannot cancel checkout from this callback. Disable the button in your UI until prerequisites are met. To block after the shopper returns from Paze, return false from onCheckoutComplete.

onCheckoutComplete

Called when checkout returns COMPLETE, before the SDK calls the complete API.

Return true to approve and continue (default when omitted). Return false to reject; the SDK calls onCheckoutIncomplete.

ParameterDescription
result
PazeCheckoutResult
The checkout result data.
result.result
PazeCheckoutResultType
The checkout outcome from Paze. In this callback, the value is always COMPLETE, meaning the shopper finished checkout in the Custom Tab and Paze returned review data. INCOMPLETE is delivered through onCheckoutIncomplete instead.
result.checkoutDecodedResponse
PazeCheckoutReviewData?
Decoded session and masked card data when complete.
result.checkoutDecodedResponse?.maskedCard?.panLastFour
String
The last four digits of the selected card.
result.checkoutDecodedResponse?.maskedCard?.paymentCardBrand
String
The card brand returned by Paze (for example, VISA).
result.reason
String?
An optional reason from Paze.
config.onCheckoutComplete = { result ->
    val decoded = result.checkoutDecodedResponse ?: return@onCheckoutComplete false
    validateCheckoutOnBackend(
        sessionId = decoded.sessionId,
        cardLastFour = decoded.maskedCard.panLastFour,
    )
}

onCheckoutIncomplete

Called when checkout ends without completion, the shopper cancels, the Custom Tab closes without a redirect, or you return false from onCheckoutComplete. When you reject in onCheckoutComplete, the reason is set from the SDK's localised merchant-validation message.

config.onCheckoutIncomplete = { result ->
    if (result.reason?.contains("cancel", ignoreCase = true) == true) {
        return@onCheckoutIncomplete
    }
    showError("Checkout was not completed. Please try again.")
}

onComplete

Called when the complete API succeeds and the response is decoded. Runs before onPreDecryption.

Use result.completeDecodedResponse?.securedPayload for manual decryption when onPreDecryption returns false.

config.onComplete = { result ->
    Log.d("Paze", "Payload ID: ${result.completeDecodedResponse?.payloadId}")
}

onPreDecryption

Called after onComplete, before the SDK decrypts the secured payload.

Return true to allow SDK decryption (default when omitted). Return false to handle decryption on your backend — the SDK skips decrypt and authorisation; use onComplete to forward the securedPayload.

SDK-managed (recommended):

config.onPreDecryption = { true }
config.onPostDecryption = { decryptedPayload ->
    val masked = decryptedPayload.fundingData.networkToken.take(6) + "..."
    Log.d("Paze", "Decrypted token prefix: $masked")
}

Merchant-managed:

config.onPreDecryption = { false }
config.onComplete = { result ->
    val securedPayload = result.completeDecodedResponse?.securedPayload ?: return@onComplete
    sendToBackendForDecryption(securedPayload)
}

See Backend decryption for PXP API endpoints.

onPostDecryption

Called after Unity successfully decrypts the network token. Skipped when onPreDecryption returns false.

ParameterDescription
decryptedPayload.shopper
PazeDecryptTokenShopper
Customer name, email, and phone from the decrypt response.
decryptedPayload.billingAddress
PazeDecryptTokenBillingAddress?
Billing address when returned by Paze.
decryptedPayload.fundingData
PazeDecryptTokenFundingData
Network token, expiry, card network, and related fields.
config.onPostDecryption = { decrypted ->
    Log.d("Paze", "Card network: ${decrypted.fundingData.cardNetwork}")
    val maskedToken = decrypted.fundingData.networkToken.take(6) + "..."
    Log.d("Paze", "Token prefix: $maskedToken")
}

onPreAuthorisation

Called before the transaction is submitted to Unity.

Return valueBehaviour
ProceedContinue without extra data (default when omitted).
CancelAbort authorisation silently. The SDK does not call onSubmitError.
TransactionInitData(...)Continue with risk screening or other init data.
config.onPreAuthorisation = {
    if (!validateOrderDetails()) {
        PazePreAuthorisationResult.Cancel
    } else {
        PazePreAuthorisationResult.TransactionInitData(
            PazeTransactionInitData(
                riskScreeningData = buildRiskScreeningData(),
            ),
        )
    }
}

onPostAuthorisation

Called when the SDK receives a MerchantSubmitResult. Only invoked when this callback is registered on the config. Verify the transaction outcome on your backend — the Unity response may report an error state while still returning transaction identifiers. Hard submission failures route to onSubmitError, not this callback.

ParameterDescription
result.merchantTransactionId
String
Your transaction identifier.
result.systemTransactionId
String
The system transaction identifier generated by PXP.
config.onPostAuthorisation = { result ->
    verifyPaymentOnBackend(systemTransactionId = result.systemTransactionId)
}

onSubmitError

Called when authorisation submission fails, including invalid Kount riskScreeningData (ValidationException). Cast to FailedSubmitResult for error details.

config.onSubmitError = { result ->
    val failed = result as? FailedSubmitResult
    showError(failed?.errorReason ?: "Payment failed")
}

onError

Called on presentment, checkout, complete, or decryption errors. Shopper cancellation is surfaced through onCheckoutIncomplete, not onError.

config.onError = { error ->
    when (error.errorCode) {
        "SDK1202", "SDK1202A" -> showError("Paze is not configured for this session.")
        "SDK1210", "SDK1212" -> showError("Please check your contact details and try again.")
        "SDK1213" -> showError("Paze is only available for USD transactions.")
        "SDK1233" -> showError("Token decryption failed. Please try again.")
        "SDK1200", "SDK1214" -> showError("Paze checkout failed. Please try again.")
        else -> showError(error.message ?: "Payment could not be completed.")
    }
}

Event data structures

Shopper

Returned by onGetShopper:

data class Shopper(
    val id: String? = null,
    val firstName: String? = null,
    val lastName: String? = null,
    val email: String? = null,
    val phoneNumber: String? = null,
    val dateOfBirth: String? = null,
    // address fields...
)

PazeCheckoutResult

Passed to onCheckoutComplete and onCheckoutIncomplete:

data class PazeCheckoutResult(
    val result: PazeCheckoutResultType,
    val reason: String?,
    val checkoutDecodedResponse: PazeCheckoutReviewData?,
)

data class PazeCheckoutReviewData(
    val sessionId: String?,
    val maskedCard: PazeMaskedCard,
)

PazeMaskedCard

Included on checkoutDecodedResponse when checkout completes:

data class PazeMaskedCard(
    val digitalCardId: String?,
    val panLastFour: String,
    val paymentAccountReference: String?,
    val panExpirationMonth: String?,
    val panExpirationYear: String?,
    val paymentCardDescriptor: String,
    val paymentCardType: String,
    val paymentCardBrand: String,
    val paymentCardNetwork: String,
    val digitalCardData: PazeDigitalCardData,
    val billingAddress: PazeCheckoutAddress?,
)

PazeCompleteResult

Passed to onComplete:

data class PazeCompleteResult(
    val completeDecodedResponse: PazeCompleteDecoded?,
    val decryptedPayload: PazeDecryptTokenResponseSuccess?,
)

At onComplete, decryptedPayload is always null. Decrypted token data is passed to onPostDecryption when SDK decryption proceeds.

data class PazeCompleteDecoded(
    val payloadId: String?,
    val sessionId: String?,
    val securedPayload: String?,
)

PazeDecryptTokenResponseSuccess

Passed to onPostDecryption:

data class PazeDecryptTokenResponseSuccess(
    val shopper: PazeDecryptTokenShopper,
    val billingAddress: PazeDecryptTokenBillingAddress?,
    val fundingData: PazeDecryptTokenFundingData,
)

data class PazeDecryptTokenShopper(
    val firstName: String?,
    val lastName: String?,
    val fullName: String,
    val emailAddress: String,
    val phoneCountryCode: String?,
    val phoneNumber: String?,
    val countryCode: String?,
    val languageCode: String?,
)

data class PazeDecryptTokenBillingAddress(
    val addressLine1: String,
    val city: String,
    val state: String,
    val countryCode: String,
    val postalCode: String,
)

data class PazeDecryptTokenFundingData(
    val networkToken: String,
    val expirationMonth: String,
    val expirationYear: String,
    val accountReference: String?,
    val cardNetwork: String,
    val tokenUsageType: String?,
    val dynamicDataExpiration: String?,
)

MerchantSubmitResult

Passed to onPostAuthorisation when the SDK receives the Unity authorisation response. Verify the outcome on your backend; hard failures route to onSubmitError.

data class MerchantSubmitResult(
    val merchantTransactionId: String,
    val systemTransactionId: String,
) : SubmitResult()

FailedSubmitResult

Typical type received in onSubmitError:

data class FailedSubmitResult(
    val errorCode: String?,
    val errorReason: String?,
    val correlationId: String?,
    val httpStatusCode: Int?,
    val details: List<String>?,
)

BaseSdkException

Passed to onError:

open class BaseSdkException(
    message: String,
    cause: Throwable? = null,
    val errorCode: String,
)