Skip to content

Configuration

Learn about how to configure the Paze button component for iOS.

Basic usage

Minimal configuration

At minimum, the Paze button requires a session with Paze enabled (clientId), USD transaction data on CheckoutConfig, and merchantCategoryCode in session.allowedFundingTypes.wallets.paze for the complete step on iOS. Configure CheckoutConfig, initialise PxpCheckout, then create the component:

let checkoutConfig = CheckoutConfig(
    environment: .test,
    session: sessionData, // allowedFundingTypes.wallets.paze.clientId + merchantCategoryCode
    transactionData: transactionData, // currency must be "USD"
    merchantShopperId: "shopper-123",
    ownerId: "owner-456",
    clientName: "Your Merchant",
    siteName: "Your Store"
)

let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)

let config = PazeButtonComponentConfig()
config.emailAddress = "customer@example.com"

let pazeButton = try pxpCheckout.create(.pazeButton, componentConfig: config)
Property Description
emailAddress
String?
Optional shopper email. Validated at presentment and again at checkout (max 128 characters, RFC 5322 format). Passed to Paze during session creation when provided.
phoneNumber
String?
Optional US phone number: 11 digits starting with 1, without the + prefix (e.g. 15551234567). Max 15 characters. Passed to Paze when provided.

The iOS component uses static presentment where the button is shown after SDK validation. The optional emailAddress and phoneNumber properties are passed to Paze during session creation when provided. merchantCategoryCode is configured on the session, not the button component, but is required for the complete step on iOS.

The SDK opens the Paze web checkout in ASWebAuthenticationSession, and by default decrypts tokens and submits transactions. We also recommend implementing onGetShopper on CheckoutConfig when calling PxpCheckout.initialize(config:) to supply shopper data when the SDK submits the transaction.

Advanced configuration

let config = PazeButtonComponentConfig()
config.emailAddress = "customer@example.com"
config.phoneNumber = "15551234567"
config.paymentDescription = "Order #12345"
config.billingPreference = .all
config.acceptedPaymentCardNetworks = [.visa, .mastercard]
config.cobrand = [PazeCobrandConfig(cobrandName: "Rewards Plus", benefitsOffered: true)]
config.performAVS = true
config.style = PazeButtonStyleConfig(
    color: .pazeBlue,
    shape: .pill,
    label: .checkoutWith
)

config.onInit = { print("Paze initialised") }
config.onPresentmentResolved = { isVisible in print("Button visible:", isVisible) }
config.onCheckoutComplete = { _ async in true }
config.onPreDecryption = { async in true }
config.onPostDecryption = { payload async in print(payload.fundingData.cardNetwork) }
config.onPostAuthorisation = { data async in print(data.systemTransactionId) }

let pazeButton = try pxpCheckout.create(.pazeButton, componentConfig: config)
PropertyDescription
emailAddress
String?
Optional shopper email for Paze checkout. Validated at presentment and again at checkout. Passed to Paze during session creation when provided.
phoneNumber
String?
Optional US phone: 11 digits starting with 1, without +. Max 15 characters. Passed to Paze when provided.
paymentDescription
String?
Statement descriptor forwarded to Paze. Maximum 25 characters. Validated during presentment initialisation.
billingPreference
PazeBillingPreference?
Billing address collection in the Paze checkout. When nil, defaults to .all internally.

Possible values:
  • .all
  • .zipCountry
  • .none
confirmLaunch
Bool?
When true, Paze may prompt before launching checkout.
sessionId
String?
Optional session ID echoed back by Paze. Falls back to CheckoutConfig.session.sessionId when not set.
acceptedShippingCountries
[String]?
The list of accepted shipping countries, in ISO 3166-1 alpha-2 format (e.g. "US", "CA"). Each code must be exactly two uppercase letters. Validated at checkout time.
acceptedPaymentCardNetworks
[PazeAcceptedPaymentCardNetwork]?
The list of accepted card networks. When all three are selected or nil, no filter is sent.

Possible values:
  • .visa
  • .mastercard
  • .discover
cobrand
[PazeCobrandConfig]?
Optional cobrand entries for partner branding in the Paze wallet. Each entry requires cobrandName. See PazeCobrandConfig.
enhancedTransactionData
PazeEnhancedTransactionDataConfig?
Optional checkout metadata forwarded to Paze. See Enhanced transaction data.
style
PazeButtonStyleConfig?
Official Paze button styling. When nil, uses PazeButtonStyleConfig() defaults (auto colour, rounded shape, checkout-with label). See Styling.
performAVS
Bool?
When true, includes billing address from decrypted payload in AVS fields when the SDK submits the transaction. Defaults to false. For manual backend decryption, apply AVS on your transaction request instead.

Your merchant branding (clientName, siteName) is configured on CheckoutConfig when calling PxpCheckout.initialize(config:), not on the button component. clientName maps to Paze's name (max 50 characters) and siteName maps to brandName (max 50 characters).

Enhanced transaction data

enhancedTransactionData is optional metadata forwarded to Paze during checkout and complete. Use it when Paze or your merchant agreement requires additional order context.

config.enhancedTransactionData = PazeEnhancedTransactionDataConfig(
    ecomData: PazeEnhancedTransactionDataConfig.EcomData(
        cartContainsGiftCard: false,
        orderForPickup: false,
        orderQuantity: "2",
        orderHighestCost: "49.99",
        finalShippingAddress: PazeAddressConfig(
            line1: "123 Main St",
            city: "New York",
            state: "NY",
            zip: "10001",
            countryCode: "US"
        )
    ),
    processingNetwork: [.visa, .mastercard]
)
PropertyDescription
ecomData.cartContainsGiftCard
Bool?
Whether the cart contains a gift card.
ecomData.orderForPickup
Bool?
Whether the order is for in-store or curbside pickup.
ecomData.orderQuantity
String?
Order item count as a string.
ecomData.orderHighestCost
String?
Highest line-item cost as a string.
ecomData.finalShippingAddress
PazeAddressConfig?
Optional shipping address. When set, required address fields must be provided. See PazeAddressConfig.
processingNetwork
[PazeAcceptedPaymentCardNetwork]?
Preferred card networks: .visa, .mastercard, or .discover.

PazeAddressConfig

Used for ecomData.finalShippingAddress:

PropertyDescription
name
String?
Recipient or address name.
line1
String
required
Primary address line.
line2
String?
Secondary address line.
city
String
required
City.
state
String
required
State or region.
zip
String
required
Postal or ZIP code.
countryCode
String
required
ISO 3166-1 alpha-2 country code.

Styling

The component renders native Paze button artwork. Use PazeButtonStyleConfig to configure official Paze button attributes. When style isn't set on the component config, the SDK uses PazeButtonStyleConfig() defaults:

config.style = PazeButtonStyleConfig(
    color: .pazeBlue,
    shape: .pill,
    label: .checkoutWith,
    disableMaxHeight: false
)
PropertyDescription
color
enum
Button colour theme.

Possible values:
  • .auto (default — adapts to light/dark mode)
  • .pazeBlue
  • .white
  • .whiteWithOutline
  • .midnightBlack
shape
enum
Button shape.

Possible values:
  • .rounded (default)
  • .rectangle
  • .pill
label
enum
Button label artwork.

Possible values:
  • .checkoutWith
  • .checkout
  • .pazeCheckout
  • .donateWith
disableMaxHeight
Bool?
When true, removes the default 48pt height cap so the button can expand vertically.

Don't override the Paze button with custom styling or overlays that alter its appearance. Use only the supported style values to remain compliant with Paze branding guidelines. See Compliance.

Event handling

config.onInit = { }
config.onPresentmentResolved = { isVisible in }
config.onPazeButtonClicked = { async in }
config.onCheckoutComplete = { _ async in true }
config.onCheckoutIncomplete = { _ async in }
config.onComplete = { result async in }
config.onPreDecryption = { async in true }
config.onPostDecryption = { decryptedPayload async in }
config.onPreAuthorisation = { async in .proceed }
config.onPostAuthorisation = { data async in }
config.onSubmitError = { submitError async in }
config.onError = { error in }
CallbackDescription
onInit
() -> Void
Called after presentment validation succeeds for this component.
onPresentmentResolved
(Bool) -> Void
Called when presentment resolves. true when the button is shown, false when validation failed (see onError).
onPazeButtonClicked
() async -> Void
Called when the button is tapped, before checkout starts. Use for pre-checkout logic.
onCheckoutComplete
(PazeCheckoutResult) async -> Bool
Called when checkout returns COMPLETE. Return true to proceed to complete, or false to cancel. Defaults to true when omitted.
onCheckoutIncomplete
(PazeCheckoutResult) async -> Void
Called when checkout ends without completion, the shopper cancels, or you return false from onCheckoutComplete.
onComplete
(PazeCompleteResult) async -> Void
Called when the complete API succeeds and the response is decoded, before decryption and authorisation. Use result.completeDecodedResponse?.securedPayload for manual decryption workflows.
onPreDecryption
() async -> Bool
Called after onComplete, before SDK decryption. Return true to allow SDK decryption, or false for manual decryption. Defaults to true when omitted.
onPostDecryption
(PazeDecryptTokenResponseSuccess) async -> Void
Called after the SDK decrypts the secured payload.
onPreAuthorisation
() async -> PazePreAuthorisationResult
Called before transaction submission. Return .proceed, .cancel, or .transactionInitData(...). Defaults to .proceed when omitted.
onPostAuthorisation
(MerchantSubmitResult) async -> Void
Called when the SDK receives a MerchantSubmitResult, immediately before your callback runs. Verify the transaction outcome on your backend — the response may report an error state while still returning transaction identifiers.
onSubmitError
(BaseSubmitResult) async -> Void
Called when authorisation submission fails and the SDK receives a FailedSubmitResult.
onError
(BaseSdkException) -> Void
Called on presentment, checkout, complete, or decryption errors. Shopper cancellation is surfaced through onCheckoutIncomplete, not onError.

For detailed callback payloads and event data structures, see Events.

Decryption flow

By default, the SDK decrypts the secured payload after complete. The callback order is onCompleteonPreDecryptiononPostDecryptiononPreAuthorisationonPostAuthorisation:

config.onCheckoutComplete = { _ async in true }

config.onPreDecryption = { async in true }

config.onPostDecryption = { decryptedPayload async in
    print("Card network:", decryptedPayload.fundingData.cardNetwork)
}

config.onPostAuthorisation = { data async in
    print("Transaction ID:", data.systemTransactionId)
    await verifyPaymentOnBackend(systemTransactionId: data.systemTransactionId)
}

Manual decryption flow

Return false from onPreDecryption to handle decryption on your backend:

config.onCheckoutComplete = { _ async in true }

config.onPreDecryption = { async in false }

config.onComplete = { result async in
    guard let securedPayload = result.completeDecodedResponse?.securedPayload else { return }
    await sendToBackendForDecryption(securedPayload: securedPayload)
}

When using manual decryption, you are responsible for calling the PXP decrypt-token endpoint and submitting the transaction from your backend. See Backend decryption for the full API reference.

Fraud detection integration

Address verification (AVS)

Set performAVS to true to include billing address from the decrypted payload in the transaction request when the SDK submits the transaction:

config.billingPreference = .all
config.performAVS = true

If you enable performAVS, set billingPreference to .all so the Paze checkout returns a billing address for AVS. This applies only when the SDK manages decryption and authorisation. If you return false from onPreDecryption, add addressVerification to your backend transaction request using the billing address from the decrypt response.

Kount risk screening

Pass risk screening data through onPreAuthorisation. Disable Kount device fingerprinting with kountDisabled: true on CheckoutConfig when calling PxpCheckout.initialize(config:):

let checkoutConfig = CheckoutConfig(
    environment: .test,
    session: sessionData,
    transactionData: transactionData,
    merchantShopperId: "shopper-123",
    ownerId: "owner-456",
    kountDisabled: false, // Set to true to disable Kount
    onGetShopper: { async in
        TransactionShopper(id: "shopper-123", email: "customer@example.com")
    }
)

let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)

config.onPreAuthorisation = { async in
    return .transactionInitData(PazeTransactionInitData(
        riskScreeningData: RiskScreeningData(
            performRiskScreening: true,
            userIp: "192.168.1.100",
            account: RiskScreeningAccount(
                id: "shopper-123",
                creationDateTime: ISO8601DateFormatter().date(from: "2024-01-15T10:30:00Z")
            )
        )
    ))
}

Displaying the component

Render the Paze button in your SwiftUI view hierarchy with buildContent():

if let pazeButton {
    pazeButton.buildContent()
        .frame(maxWidth: .infinity)
}

Presentment initialises automatically when the component view appears. When the view disappears, internal state is cleaned up — no manual unmount call is required.

Examples

Basic checkout button

let config = PazeButtonComponentConfig()
config.emailAddress = "customer@example.com"

config.onCheckoutComplete = { _ async in true }

config.onPostAuthorisation = { data async in
    await verifyPaymentOnBackend(systemTransactionId: data.systemTransactionId)
    navigateToOrderConfirmation()
}

config.onError = { error in
    print("Paze error:", error.errorCode, error.errorMessage)
    showError("Payment error. Please try again.")
}

let pazeButton = try pxpCheckout.create(.pazeButton, componentConfig: config)

Donation flow

config.style = PazeButtonStyleConfig(
    color: .midnightBlack,
    shape: .rounded,
    label: .donateWith
)
config.paymentDescription = "Charity donation"

Enterprise payment with fraud detection

let config = PazeButtonComponentConfig()
config.emailAddress = "customer@example.com"
config.phoneNumber = "15551234567"
config.billingPreference = .all
config.acceptedPaymentCardNetworks = [.visa, .mastercard]
config.performAVS = true
config.style = PazeButtonStyleConfig(color: .pazeBlue, shape: .pill, label: .checkoutWith)

config.onCheckoutComplete = { result async in
    return await validateOrderOnBackend(result: result)
}

config.onPreAuthorisation = { async in
    return .transactionInitData(PazeTransactionInitData(
        riskScreeningData: buildRiskScreeningData()
    ))
}

config.onPostAuthorisation = { data async in
    await verifyPaymentOnBackend(systemTransactionId: data.systemTransactionId)
    navigateToSuccess(merchantTransactionId: data.merchantTransactionId)
}

config.onSubmitError = { submitError async in
    if let failed = submitError as? FailedSubmitResult {
        showError("Payment failed: \(failed.errorReason ?? "")")
    }
}

Configuration types

PazeButtonComponentConfig

PazeButtonComponentConfig extends BaseComponentConfig and exposes the properties and callbacks listed above. Configure properties and callbacks on a single instance before passing it to create(.pazeButton, componentConfig:).

PazeButtonStyleConfig

struct PazeButtonStyleConfig {
    var color: PazeButtonColor       // .auto, .pazeBlue, .white, .whiteWithOutline, .midnightBlack
    var shape: PazeButtonShape       // .rounded, .rectangle, .pill
    var disableMaxHeight: Bool?
    var label: PazeButtonLabel       // .checkoutWith, .checkout, .pazeCheckout, .donateWith
}

PazeCobrandConfig

Each cobrand entry in cobrand uses:

PropertyDescription
cobrandName
String
required
Cobrand program name. Must be non-empty.
benefitsOffered
Bool?
Whether cobrand benefits are offered for this program.
struct PazeCobrandConfig {
    var cobrandName: String
    var benefitsOffered: Bool?
}