Skip to content

Data validation

Learn about built-in validation and implement additional scenarios for Paze on iOS.

Overview

The Paze component validates configuration, identity data, and transaction parameters before and during the payment flow. Validation runs at multiple stages:

  1. Component creation: Paze must be included in session allowedFundingTypes (SDK0118 if missing).
  2. Presentment: Session clientId, currency, client presentation settings, and optional identity fields.
  3. Checkout: Amount, billing preferences, shipping countries, cobrand configuration, and identity re-validation.
  4. Complete: Transaction type, amount, currency, billing preference, and merchantCategoryCode when the SDK builds the Paze complete request.
  5. 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.

Built-in validation

By default, the Paze component validates that:

  • allowedFundingTypes.wallets.paze.clientId is present in the session.
  • merchantCategoryCode is present in the session when the SDK builds the complete request (on iOS).
  • The transaction currency is USD.
  • clientName is 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 1 followed by 10 digits when provided (at presentment and again at checkout).
  • The transaction amount is greater than 0 at checkout.
  • billingPreference is one of .all, .zipCountry, or .none.
  • acceptedShippingCountries use 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.

Checkout identity

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.

ConfigurationSent to Paze
Email onlyemailAddress
Phone onlyphoneNumber
Email and phoneemailAddress and phoneNumber

The Paze component returns structured error codes for validation failures:

Error codeDescriptionCommon causes
SDK0118Paze is missing in allowed funding types.session.allowedFundingTypes.wallets.paze.clientId is missing or empty at create(.pazeButton) time.
SDK1202Missing session.allowedFundingTypes.wallets.paze.clientId.Paze clientId not in session data at presentment.
SDK1202AMissing session.allowedFundingTypes.wallets.paze.merchantCategoryCode.MCC not included in session for iOS payment completion.
SDK1203clientName exceeds 50 characters.CheckoutConfig.clientName is too long.
SDK1204siteName exceeds 50 characters.CheckoutConfig.siteName is too long.
SDK1205paymentDescription exceeds 25 characters.Statement descriptor on component config is too long.
SDK1209Email address exceeds 128 characters.emailAddress value is too long.
SDK1210Email address format is invalid.emailAddress isn't a valid RFC 5322 address.
SDK1211Phone number exceeds 15 characters.phoneNumber value is too long.
SDK1212Phone number format is invalid.phoneNumber isn't a US E.164 number without +.
SDK1213Currency not supported.Transaction currency isn't USD.
SDK1206Failed to initialize Paze SDK.Generic presentment failure.
SDK1200Failed to load Paze SDK.Session creation failed.
SDK1214Paze checkout failed.Generic checkout failure.
SDK1215Paze checkout did not return checkoutResponse for a COMPLETE result.Missing checkout response.
SDK1216Paze complete did not return completeResponse.Missing complete response code.
SDK1219Paze completeResponse did not contain securedPayload.Secured payload missing after complete.
SDK1231Invalid shipping country codes.acceptedShippingCountries contains non-ISO alpha-2 codes.
SDK1232Cobrand name is required.A cobrand entry is missing cobrandName.
SDK1235Paze 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.

Validation example

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)
    }
}

Merchant validation gates

Callbacks that use await must be marked async on PazeButtonComponentConfig:

CallbackSDK 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)?

Pre-checkout validation

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.

Post-checkout merchant validation

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.")
}

Pre-decryption validation

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)
}

Pre-authorisation validation

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()
        )
    ))
}

Identity validation rules

Email address

RuleRequirement
FormatValid RFC 5322 email address
Maximum length128 characters
TimingOptional. Validated at presentment and again at checkout when provided

Phone number

RuleRequirement
FormatUS number without + prefix: 1 followed by exactly 10 digits (^1\d{10}$)
Valid lengthExactly 11 characters (e.g. 15551234567)
Maximum length15 characters — values longer than 15 throw SDK1211 before format validation
TimingOptional. 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.

Full Paze error reference

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, SDK1200SDK1235 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.

Component creation

Error codeSDK messageWhen it surfaces
SDK0118Paze is missing in allow funding types.create(.pazeButton) when session.allowedFundingTypes.wallets.paze.clientId is missing or empty.

Presentment

Error codeSDK messageWhen it surfaces
SDK1202Missing session.allowedFundingTypes.wallets.paze.clientId.Presentment validation when clientId is absent from session data.
SDK1203client.name must be 50 characters or fewer.CheckoutConfig.clientName exceeds 50 characters.
SDK1204client.brandName must be 50 characters or fewer.CheckoutConfig.siteName exceeds 50 characters.
SDK1205client.statementDescriptor must be 25 characters or fewer.paymentDescription exceeds 25 characters.
SDK1206Failed to initialize Paze SDK.Generic presentment failure after an unexpected error.
SDK1207Paze canCheckout did not return an eligibility result.Dynamic presentment only. Not used by the iOS button component's static presentment path.
SDK1208Paze dynamic presentment requires both emailAddress and phoneNumber to be provided.Dynamic presentment only. Not used by the iOS button component's static presentment path.
SDK1209emailAddress must be 128 characters or fewer.emailAddress exceeds maximum length.
SDK1210emailAddress must be a valid RFC 5322 email address.emailAddress format is invalid.
SDK1211phoneNumber must be 15 characters or fewer.phoneNumber exceeds maximum length.
SDK1212phoneNumber must be a US E.164 number without '+', for example 15551234567.phoneNumber format is invalid.
SDK1213Paze only supports USD currency. Received: '{currency}'.transactionData.currency is not USD.

Checkout

Error codeSDK messageWhen it surfaces
SDK1200Failed to load Paze SDK.PXP create-session call failed or returned an error before the web checkout opens.
SDK1214Paze 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.
SDK1215Paze checkout did not return checkoutResponse for a COMPLETE result.Checkout returned COMPLETE but the response JWT is missing.
SDK1217Unable to decode Paze checkoutResponse.Defined in the SDK but not emitted by the button component — decode failures surface as SDK1214.
SDK1220Paze wallet account exists but is not accessible.Defined in the SDK but not emitted by the button component in production.
SDK1229transactionValue.transactionAmount must be greater than 0.Transaction amount is zero or negative at checkout validation.
SDK1226billingPreference must be one of: {validBillingPreferences}.Invalid billingPreference at checkout.
SDK1231acceptedShippingCountries contains invalid country codes: {invalidCountryCodes}.acceptedShippingCountries contains non-ISO alpha-2 codes.
SDK1232cobrand.cobrandName is required for each cobrand entry.A cobrand entry has an empty cobrandName.

Complete

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 codeSDK messageWhen it surfaces
SDK1202AMissing session.allowedFundingTypes.wallets.paze.merchantCategoryCode.merchantCategoryCode is missing from session data when building the complete request.
SDK1216Paze complete did not return completeResponse.Complete response code is missing after checkout.
SDK1218Unable to decode Paze completeResponse.Defined in the SDK but not emitted by the button component — decode failures surface as SDK1214.
SDK1219Paze completeResponse did not contain securedPayload.Complete succeeded but no securedPayload was returned.
SDK1221Paze complete() was called before checkout() finished successfully.Defined in the SDK but not emitted by the button component in production.
SDK1222sessionId must be 255 characters or fewer.Session ID exceeds maximum length on the complete request.
SDK1223transactionType must be PURCHASE for Paze complete().Internal validation if complete request transactionType is not PURCHASE.
SDK1224transactionOptions is required when transactionType is PURCHASE.Complete request is missing transactionOptions.
SDK1225transactionValue is required when transactionType is PURCHASE.Complete request is missing transactionValue.
SDK1227transactionOptions.billingPreference must be one of: {validBillingPreferences}.Invalid billing preference on the complete request.
SDK1228transactionOptions.payloadTypeIndicator must be PAYMENT.Complete request payload type is not PAYMENT.
SDK1230transactionValue.transactionCurrencyCode must be a 3-letter ISO currency code.Invalid currency code on the complete request.

Decryption and authorisation

Error codeSDK messageWhen 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.
SDK1235Paze payment transaction failed. {error}Unity transaction submission failed. Typically surfaced through onSubmitError as a FailedSubmitResult with gateway or provider codes, not through onError.
SDK1201Unknown Paze SDK error.Defined in the SDK but not emitted by the button component — unclassified errors normalize to SDK1206 or SDK1214.