Learn about built-in validation and implement additional scenarios for Paze on Android.
The Paze component validates configuration, identity data, and transaction parameters before and during the payment flow. Validation runs at multiple stages:
- Presentment: Session
clientId, currency, client presentation settings, and optional identity fields when the componentContent()is composed. - Checkout: Identity re-validation, amount check, optional
sessionIdlength, and create-session request building. - Complete:
merchantCategoryCodeand complete-request fields when the SDK calls Paze complete. - Merchant callbacks: Optional approval gates via
onCheckoutComplete,onPreDecryption, andonPreAuthorisation.
If validation fails, the SDK surfaces a BaseSdkException with a structured error code in the SDK12XX range. Most validation, checkout, and decrypt failures route to onError. Authorisation submission failures route to onSubmitError.
Missing clientId is detected at presentment as SDK1202.
The SDK validates session configuration, presentation settings, and optional identity fields before checkout proceeds. By default, the Paze component checks that:
allowedFundingTypes.wallets.paze.clientIdis present in the session.merchantCategoryCodeis present in the session when the SDK builds the complete request.- The transaction currency is
USD. - When set,
clientNameis 50 characters or fewer. - When set,
siteName(brand name) is 50 characters or fewer. - When set,
paymentDescription(statement descriptor) is 25 characters or fewer at presentment. - Email addresses are valid RFC 5322-style format and 128 characters or fewer when provided (at presentment and again at checkout).
- Phone numbers match
1followed by 10 digits when provided (at presentment and again at checkout). - The transaction amount is greater than 0 at checkout.
sessionIdis 255 characters or fewer when set on the component config.
The button uses static presentment: it appears after presentment validation succeeds when Content() is composed. Optional emailAddress and phoneNumber are validated when provided and forwarded to the Paze create-session request. Both fields are optional but recommended when you have verified shopper identity.
acceptedPaymentCardNetworks, cobrand, and acceptedShippingCountries are forwarded to create-session when set. For card networks, omitting the property, passing an empty list, or selecting all three supported networks (VISA, MASTERCARD, DISCOVER) sends no network filter to Paze.
Set transactionData.entryType to EntryType.Ecom when initialising the SDK. Paze expects an e-commerce entry type on the authorisation request. The standalone Paze button component does not validate entryType at presentment — it is included on the transaction request after decryption. Checkout drop-in validates EntryType.Ecom separately (SDK1124).
Component identity (emailAddress / phoneNumber) is passed to Paze during session creation when provided. Each field is validated independently when set. Identity is separate from onGetShopper, which supplies shopper data for Unity authorisation after decryption.
When you set one or both identity fields, the SDK sends them to Paze as follows:
| Configuration | Sent to Paze |
|---|---|
| Email only | emailAddress |
| Phone only | phoneNumber |
| Email and phone | emailAddress and phoneNumber |
The Paze component returns structured error codes when built-in validation or flow checks fail:
| Error code | Description | Common causes |
|---|---|---|
SDK1202 | Missing session.allowedFundingTypes.wallets.paze.clientId. | Paze clientId not in session data at presentment. |
SDK1202A | Missing session.allowedFundingTypes.wallets.paze.merchantCategoryCode. | MCC not included in session when the SDK builds the complete request. |
SDK1203 | clientName exceeds 50 characters. | clientName on SDK initialisation is too long when set. |
SDK1204 | siteName exceeds 50 characters. | siteName on SDK initialisation is too long when set. |
SDK1205 | paymentDescription exceeds 25 characters. | Statement descriptor on component config is too long when set. |
SDK1209 | Email address exceeds 128 characters. | emailAddress value is too long. |
SDK1210 | Email address format is invalid. | emailAddress is not a valid RFC 5322-style email address. |
SDK1211 | Phone number exceeds 15 characters. | phoneNumber value is too long. |
SDK1212 | Phone number format is invalid. | phoneNumber is not a US E.164 number without +. |
SDK1213 | Currency not supported. | Transaction currency is not USD. |
SDK1206 | Failed to initialize Paze SDK. | Create-session failure or missing checkout URL. |
SDK1200 | Failed to load Paze SDK. | Custom Tab launch failed. |
SDK1214 | Paze checkout failed. | Generic checkout or wallet flow failure. |
SDK1215 | Paze checkout did not return checkoutResponse for a COMPLETE result. | Missing checkout response. |
SDK1216 | Paze complete did not return completeResponse. | Missing complete response code. |
SDK1219 | Paze completeResponse did not contain securedPayload. | Secured payload missing after complete. |
SDK1222 | sessionId exceeds 255 characters. | Component sessionId is too long at checkout. |
SDK1229 | Transaction amount invalid. | Transaction amount is 0 or negative at checkout. |
SDK1231 | Invalid shipping country codes. | acceptedShippingCountries contains codes that are not valid ISO 3166-1 alpha-2 values. |
SDK1232 | Cobrand name required. | A cobrand entry has an empty cobrandName. |
SDK1233 | Failed to decrypt Paze token. | Decrypt API error or invalid secured payload. Surfaced through onError. |
SDK1235 | Paze transaction failed. | Authorisation request failed. Surfaced through onSubmitError, not onError. |
Create-session and complete API provider errors may return provider-specific codes through PazeProviderException, not only the SDK12XX values listed above. Map unknown codes using error.message and your backend logs. Codes such as SDK1231 and SDK1232 are defined in the SDK but are typically returned by the create-session API rather than thrown locally by the component.
Use onError to map SDK validation and flow errors to user-facing messages:
config.onError = { error ->
when (error.errorCode) {
"SDK1210" -> showError("Please enter a valid email address.")
"SDK1212" -> showError("Please enter a valid US phone number (e.g. 15551234567).")
"SDK1213" -> showError("Paze is only available for USD transactions.")
"SDK1202", "SDK1202A" -> showError("Paze is not configured for this session.")
"SDK1231" -> showError("Invalid shipping country configuration.")
"SDK1232" -> showError("Cobrand configuration is incomplete.")
"SDK1233" -> showError("Payment token could not be processed. Please try again.")
"SDK1200", "SDK1214" -> showError("Paze checkout failed. Please try again.")
else -> showError(error.message ?: "Payment could not be completed.")
}
}Beyond built-in SDK checks, you can add merchant-side approval gates at key points in the flow.
Validate cart state, terms acceptance, and inventory before checkout by disabling the Paze button in your UI until pre-requisites are met. onPazeButtonClicked has no return value and can't cancel the flow; the SDK opens the Custom Tab as soon as the callback completes. Use onPazeButtonClicked only for non-blocking side effects such as analytics or clearing error messages.
To hard-block checkout after the shopper returns from Paze, return false from onCheckoutComplete.
Use onCheckoutComplete to inspect checkout data and approve or reject before the SDK calls complete. Return false to treat the checkout as incomplete.
The following example approves checkout only after server-side validation succeeds:
config.onCheckoutComplete = { result ->
val decoded = result.checkoutDecodedResponse ?: return@onCheckoutComplete false
return@onCheckoutComplete validateCheckoutOnBackend(
sessionId = decoded.sessionId,
cardLastFour = decoded.maskedCard.panLastFour,
)
}
config.onCheckoutIncomplete = { _ ->
showMessage("Payment was not completed. Please try again.")
}Use onPreDecryption to control whether the SDK decrypts the secured payload. Return false to handle decryption on your backend. When omitted, the SDK defaults to decrypting.
Return false from onPreDecryption and send the secured payload to your backend in onComplete:
config.onPreDecryption = { false }
config.onComplete = { result ->
val securedPayload = result.completeDecodedResponse?.securedPayload ?: return@onComplete
sendToBackendForDecryption(securedPayload)
}Use onPreAuthorisation to provide risk screening data or abort the transaction before submission. When you return TransactionInitData(...) with riskScreeningData, the SDK validates the Kount payload before submitting the transaction. Invalid risk screening data throws a ValidationException surfaced through onSubmitError.
The following example cancels authorisation when a fraud check fails, or passes Kount risk screening data when it passes:
config.onPreAuthorisation = {
if (fraudCheckFailed()) {
PazePreAuthorisationResult.Cancel
} else {
PazePreAuthorisationResult.TransactionInitData(
PazeTransactionInitData(
riskScreeningData = RiskScreeningData(
performRiskScreening = true,
userIp = getUserIpAddress(),
),
),
)
}
}The SDK applies the following rules to optional emailAddress and phoneNumber fields on the component config.
Email validation runs at presentment and again at checkout when the field is set:
| Rule | Requirement |
|---|---|
| Format | Valid RFC 5322-style email address (format check uses trimmed value) |
| Maximum length | 128 characters (checked before trimming) |
| Timing | Optional; validated at presentment and again at checkout when provided |
Phone validation runs at presentment and again at checkout when the field is set:
| Rule | Requirement |
|---|---|
| Format | US number without + prefix: 1 followed by exactly 10 digits (^1\d{10}$) |
| Valid length | Exactly 11 characters (e.g., 15551234567) |
| Maximum length | 15 characters. Values longer than 15 throw SDK1211 before format validation |
| Timing | Optional; validated at presentment and again at checkout when provided |
Phone numbers must not include the + prefix or formatting characters. Use 15551234567, not +1 (555) 123-4567.