Learn about how to configure the Paze button component for iOS.
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 |
|---|---|
emailAddressString? | Optional shopper email. Validated at presentment and again at checkout (max 128 characters, RFC 5322 format). Passed to Paze during session creation when provided. |
phoneNumberString? | 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.
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)| Property | Description |
|---|---|
emailAddressString? | Optional shopper email for Paze checkout. Validated at presentment and again at checkout. Passed to Paze during session creation when provided. |
phoneNumberString? | Optional US phone: 11 digits starting with 1, without +. Max 15 characters. Passed to Paze when provided. |
paymentDescriptionString? | Statement descriptor forwarded to Paze. Maximum 25 characters. Validated during presentment initialisation. |
billingPreferencePazeBillingPreference? | Billing address collection in the Paze checkout. When nil, defaults to .all internally.Possible values:
|
confirmLaunchBool? | When true, Paze may prompt before launching checkout. |
sessionIdString? | 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:
|
cobrand[PazeCobrandConfig]? | Optional cobrand entries for partner branding in the Paze wallet. Each entry requires cobrandName. See PazeCobrandConfig. |
enhancedTransactionDataPazeEnhancedTransactionDataConfig? | Optional checkout metadata forwarded to Paze. See Enhanced transaction data. |
stylePazeButtonStyleConfig? | Official Paze button styling. When nil, uses PazeButtonStyleConfig() defaults (auto colour, rounded shape, checkout-with label). See Styling. |
performAVSBool? | 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).
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]
)| Property | Description |
|---|---|
ecomData.cartContainsGiftCardBool? | Whether the cart contains a gift card. |
ecomData.orderForPickupBool? | Whether the order is for in-store or curbside pickup. |
ecomData.orderQuantityString? | Order item count as a string. |
ecomData.orderHighestCostString? | Highest line-item cost as a string. |
ecomData.finalShippingAddressPazeAddressConfig? | Optional shipping address. When set, required address fields must be provided. See PazeAddressConfig. |
processingNetwork[PazeAcceptedPaymentCardNetwork]? | Preferred card networks: .visa, .mastercard, or .discover. |
Used for ecomData.finalShippingAddress:
| Property | Description |
|---|---|
nameString? | Recipient or address name. |
line1String required | Primary address line. |
line2String? | Secondary address line. |
cityString required | City. |
stateString required | State or region. |
zipString required | Postal or ZIP code. |
countryCodeString required | ISO 3166-1 alpha-2 country code. |
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
)| Property | Description |
|---|---|
colorenum | Button colour theme. Possible values:
|
shapeenum | Button shape. Possible values:
|
labelenum | Button label artwork. Possible values:
|
disableMaxHeightBool? | 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.
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 }| Callback | Description |
|---|---|
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.
By default, the SDK decrypts the secured payload after complete. The callback order is onComplete → onPreDecryption → onPostDecryption → onPreAuthorisation → onPostAuthorisation:
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)
}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.
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 = trueIf 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.
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")
)
)
))
}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.
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)config.style = PazeButtonStyleConfig(
color: .midnightBlack,
shape: .rounded,
label: .donateWith
)
config.paymentDescription = "Charity donation"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 ?? "")")
}
}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:).
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
}Each cobrand entry in cobrand uses:
| Property | Description |
|---|---|
cobrandNameString required | Cobrand program name. Must be non-empty. |
benefitsOfferedBool? | Whether cobrand benefits are offered for this program. |
struct PazeCobrandConfig {
var cobrandName: String
var benefitsOffered: Bool?
}