Learn about built-in validation and implement additional scenarios for Paze on iOS.
The Paze component validates configuration, identity data, and transaction parameters before and during the payment flow. Validation runs at multiple stages:
- Component creation: Paze must be included in session
allowedFundingTypes(SDK0118if missing). - Presentment: Session
clientId, currency, client presentation settings, and optional identity fields. - Checkout: Amount, billing preferences, shipping countries, cobrand configuration, and identity re-validation.
- Complete: Transaction type, amount, currency, billing preference, and
merchantCategoryCodewhen the SDK builds the Paze complete request. - Merchant callbacks: Optional approval gates after checkout, before decryption, and before authorisation.
If validation fails, the SDK surfaces a BaseSdkException with a structured error code in the SDK12XX range (or SDK0118 at component creation). Authorisation submission failures are surfaced through onSubmitError instead of onError.
By default, the Paze component validates that:
allowedFundingTypes.wallets.paze.clientIdis present in the session.merchantCategoryCodeis present in the session when the SDK builds the complete request (on iOS).- The transaction currency is
USD. clientNameis 50 characters or fewer.siteName(brand name) is 50 characters or fewer.paymentDescription(statement descriptor) is 25 characters or fewer.- Email addresses are valid RFC 5322 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.
billingPreferenceis one of.all,.zipCountry, or.none.acceptedShippingCountriesuse valid ISO 3166-1 alpha-2 codes (exactly two uppercase letters).- Each cobrand entry has a non-empty
cobrandName.
Set transactionData.entryType to .ecom when initialising the SDK. Paze expects an e-commerce entry type on the authorisation request, but the button component doesn't validate entryType at presentment.
The iOS component uses static presentment, so it doesn't call Paze's canCheckout(). Optional emailAddress and phoneNumber are validated when provided, but not required for the button to appear.
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.
| Configuration | Sent to Paze |
|---|---|
| Email only | emailAddress |
| Phone only | phoneNumber |
| Email and phone | emailAddress and phoneNumber |
The Paze component returns structured error codes for validation failures:
| Error code | Description | Common causes |
|---|---|---|
SDK0118 | Paze is missing in allowed funding types. | session.allowedFundingTypes.wallets.paze.clientId is missing or empty at create(.pazeButton) time. |
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 for iOS payment completion. |
SDK1203 | clientName exceeds 50 characters. | CheckoutConfig.clientName is too long. |
SDK1204 | siteName exceeds 50 characters. | CheckoutConfig.siteName is too long. |
SDK1205 | paymentDescription exceeds 25 characters. | Statement descriptor on component config is too long. |
SDK1209 | Email address exceeds 128 characters. | emailAddress value is too long. |
SDK1210 | Email address format is invalid. | emailAddress isn't a valid RFC 5322 address. |
SDK1211 | Phone number exceeds 15 characters. | phoneNumber value is too long. |
SDK1212 | Phone number format is invalid. | phoneNumber isn't a US E.164 number without +. |
SDK1213 | Currency not supported. | Transaction currency isn't USD. |
SDK1206 | Failed to initialize Paze SDK. | Generic presentment failure. |
SDK1200 | Failed to load Paze SDK. | Session creation failed. |
SDK1214 | Paze checkout failed. | Generic checkout 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. |
SDK1231 | Invalid shipping country codes. | acceptedShippingCountries contains non-ISO alpha-2 codes. |
SDK1232 | Cobrand name is required. | A cobrand entry is missing cobrandName. |
SDK1235 | Paze transaction failed. | Authorisation request failed. onSubmitError typically receives a FailedSubmitResult with gateway or provider error codes (for example, DECLINED), not SDK1235. |
For the complete list of Paze error codes, including complete-step validation and decode failures, see Full Paze error reference.
config.onError = { error in
switch error.errorCode {
case "SDK0118":
showError("Paze isn't enabled for this session.")
case "SDK1210":
showError("Please enter a valid email address.")
case "SDK1212":
showError("Please enter a valid US phone number (e.g. 15551234567).")
case "SDK1213":
showError("Paze is only available for USD transactions.")
case "SDK1202":
showError("Paze client ID is missing from the session.")
case "SDK1202A":
showError("Paze merchant category code is missing from the session.")
case "SDK1214", "SDK1200":
showError("Paze checkout failed. Please try again.")
default:
showError(error.errorMessage)
}
}Callbacks that use await must be marked async on PazeButtonComponentConfig:
| Callback | SDK signature |
|---|---|
onPazeButtonClicked | (() async -> Void)? |
onCheckoutComplete | ((PazeCheckoutResult) async -> Bool)? |
onCheckoutIncomplete | ((PazeCheckoutResult) async -> Void)? |
onComplete | ((PazeCompleteResult) async -> Void)? |
onPreDecryption | (() async -> Bool)? |
onPreAuthorisation | (() async -> PazePreAuthorisationResult)? |
onSubmitError | ((BaseSubmitResult) async -> Void)? |
onError | ((BaseSdkException) -> Void)? |
The iOS component doesn't provide onCustomValidation. Validate cart state, terms acceptance, and inventory in your UI before enabling the Paze button, or run non-blocking checks in onPazeButtonClicked before the Paze web session opens.
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.
config.onCheckoutComplete = { result async in
guard let decoded = result.checkoutDecodedResponse else { return false }
let isValid = await validateCheckoutOnBackend(
sessionId: decoded.sessionId,
cardLastFour: decoded.maskedCard?.panLastFour,
cardBrand: decoded.maskedCard?.paymentCardBrand
)
return isValid
}
config.onCheckoutIncomplete = { result async in
showMessage("Payment was not completed. Please try again.")
}onComplete fires first with securedPayload in completeDecodedResponse. onPreDecryption runs next — return false to skip SDK decryption and handle the payload on your backend.
Use onPreDecryption to control whether the SDK decrypts the secured payload. When omitted, the SDK defaults to decrypting.
config.onPreDecryption = { async in false }
config.onComplete = { result async in
guard let securedPayload = result.completeDecodedResponse?.securedPayload else { return }
await sendToBackendForDecryption(securedPayload: 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.
config.onPreAuthorisation = { async in
if fraudCheckFailed() {
return .cancel
}
return .transactionInitData(PazeTransactionInitData(
riskScreeningData: RiskScreeningData(
performRiskScreening: true,
userIp: await getUserIpAddress()
)
))
}| Rule | Requirement |
|---|---|
| Format | Valid RFC 5322 email address |
| Maximum length | 128 characters |
| Timing | Optional. Validated at presentment and again at checkout when provided |
| 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.
The table in Built-in validation lists the errors you are most likely to encounter during integration. This section lists every Paze-related error code defined in the iOS SDK (SDK0118 at component creation, SDK1200–SDK1235 during the payment flow).
The tables below list every Paze-related error code defined in the iOS SDK. For the standalone Paze button component, some codes are defined but not emitted — decode and provider failures often surface as SDK1214 or PazeProviderException instead. Authorisation failures are typically surfaced through onSubmitError as FailedSubmitResult, not onError.
SDK1207 and SDK1208 apply to dynamic presentment flows. The iOS button component uses static presentment and doesn't call Paze canCheckout(), so these codes aren't emitted.
| Error code | SDK message | When it surfaces |
|---|---|---|
SDK0118 | Paze is missing in allow funding types. | create(.pazeButton) when session.allowedFundingTypes.wallets.paze.clientId is missing or empty. |
| Error code | SDK message | When it surfaces |
|---|---|---|
SDK1202 | Missing session.allowedFundingTypes.wallets.paze.clientId. | Presentment validation when clientId is absent from session data. |
SDK1203 | client.name must be 50 characters or fewer. | CheckoutConfig.clientName exceeds 50 characters. |
SDK1204 | client.brandName must be 50 characters or fewer. | CheckoutConfig.siteName exceeds 50 characters. |
SDK1205 | client.statementDescriptor must be 25 characters or fewer. | paymentDescription exceeds 25 characters. |
SDK1206 | Failed to initialize Paze SDK. | Generic presentment failure after an unexpected error. |
SDK1207 | Paze canCheckout did not return an eligibility result. | Dynamic presentment only. Not used by the iOS button component's static presentment path. |
SDK1208 | Paze dynamic presentment requires both emailAddress and phoneNumber to be provided. | Dynamic presentment only. Not used by the iOS button component's static presentment path. |
SDK1209 | emailAddress must be 128 characters or fewer. | emailAddress exceeds maximum length. |
SDK1210 | emailAddress must be a valid RFC 5322 email address. | emailAddress format is invalid. |
SDK1211 | phoneNumber must be 15 characters or fewer. | phoneNumber exceeds maximum length. |
SDK1212 | phoneNumber must be a US E.164 number without '+', for example 15551234567. | phoneNumber format is invalid. |
SDK1213 | Paze only supports USD currency. Received: '{currency}'. | transactionData.currency is not USD. |
| Error code | SDK message | When it surfaces |
|---|---|---|
SDK1200 | Failed to load Paze SDK. | PXP create-session call failed or returned an error before the web checkout opens. |
SDK1214 | Paze checkout failed. | Generic checkout failure (web session, callback parsing, or provider error). Decode failures (SDK1217) and provider errors often surface here or as PazeProviderException rather than as separate onError codes. |
SDK1215 | Paze checkout did not return checkoutResponse for a COMPLETE result. | Checkout returned COMPLETE but the response JWT is missing. |
SDK1217 | Unable to decode Paze checkoutResponse. | Defined in the SDK but not emitted by the button component — decode failures surface as SDK1214. |
SDK1220 | Paze wallet account exists but is not accessible. | Defined in the SDK but not emitted by the button component in production. |
SDK1229 | transactionValue.transactionAmount must be greater than 0. | Transaction amount is zero or negative at checkout validation. |
SDK1226 | billingPreference must be one of: {validBillingPreferences}. | Invalid billingPreference at checkout. |
SDK1231 | acceptedShippingCountries contains invalid country codes: {invalidCountryCodes}. | acceptedShippingCountries contains non-ISO alpha-2 codes. |
SDK1232 | cobrand.cobrandName is required for each cobrand entry. | A cobrand entry has an empty cobrandName. |
The SDK always sends transactionType: "PURCHASE" when calling the Paze complete API, regardless of the card intent (.authorisation or .purchase) configured on CheckoutConfig. Card intent applies to the Unity authorisation request after decryption, not to the Paze complete step. See Transaction intents.
| Error code | SDK message | When it surfaces |
|---|---|---|
SDK1202A | Missing session.allowedFundingTypes.wallets.paze.merchantCategoryCode. | merchantCategoryCode is missing from session data when building the complete request. |
SDK1216 | Paze complete did not return completeResponse. | Complete response code is missing after checkout. |
SDK1218 | Unable to decode Paze completeResponse. | Defined in the SDK but not emitted by the button component — decode failures surface as SDK1214. |
SDK1219 | Paze completeResponse did not contain securedPayload. | Complete succeeded but no securedPayload was returned. |
SDK1221 | Paze complete() was called before checkout() finished successfully. | Defined in the SDK but not emitted by the button component in production. |
SDK1222 | sessionId must be 255 characters or fewer. | Session ID exceeds maximum length on the complete request. |
SDK1223 | transactionType must be PURCHASE for Paze complete(). | Internal validation if complete request transactionType is not PURCHASE. |
SDK1224 | transactionOptions is required when transactionType is PURCHASE. | Complete request is missing transactionOptions. |
SDK1225 | transactionValue is required when transactionType is PURCHASE. | Complete request is missing transactionValue. |
SDK1227 | transactionOptions.billingPreference must be one of: {validBillingPreferences}. | Invalid billing preference on the complete request. |
SDK1228 | transactionOptions.payloadTypeIndicator must be PAYMENT. | Complete request payload type is not PAYMENT. |
SDK1230 | transactionValue.transactionCurrencyCode must be a 3-letter ISO currency code. | Invalid currency code on the complete request. |
| Error code | SDK message | When it surfaces |
|---|---|---|
SDK1233 | {error} | Defined in the SDK but not emitted by the button component — decryption failures surface as SDK1214 or SDK1219. Also tracked as the PazeDecryptionFailed analytics event when decryption fails internally. |
SDK1234 | {error} | Defined in the SDK but not emitted by the button component — provider errors surface as SDK1214 or PazeProviderException. |
SDK1235 | Paze payment transaction failed. {error} | Unity transaction submission failed. Typically surfaced through onSubmitError as a FailedSubmitResult with gateway or provider codes, not through onError. |
SDK1201 | Unknown Paze SDK error. | Defined in the SDK but not emitted by the button component — unclassified errors normalize to SDK1206 or SDK1214. |