{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","admonition","br","details","required"]},"type":"markdown"},"seo":{"title":"Implementation","description":"Transform your commerce with PXP's unified platform—seamless payments, real-time insights, and global growth in one powerful integration.","lang":"en-UK","siteUrl":"https://developer.pxp.io","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"implementation","__idx":0},"children":["Implementation"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Complete guide to integrating the Paze component into your iOS application."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Paze component provides a fast, secure payment experience using the Paze digital wallet. The component follows a simple three-step lifecycle:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Initialise:"]}," Configure the SDK with your session and transaction data."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Create and display:"]}," Build the Paze button with your configuration and render it in your SwiftUI view."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Handle callbacks:"]}," Respond to payment success, errors, and other events."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The component automatically handles Paze presentment, in-app web checkout, token decryption, and transaction processing."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Backend verification is mandatory. Always verify payments on your backend before fulfilling orders. App callbacks can be manipulated by malicious users."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"before-you-start","__idx":2},"children":["Before you start"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Complete ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/onboarding"},"children":["Paze onboarding"]}," in the Unity Portal before integrating the component. You will need:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Paze enabled at merchant group and site level, with your Paze client ID saved in ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Paze Account Settings"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["PXP API credentials (client ID and authentication token) for session creation on your backend"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["iOS 14.0 or later as your deployment target"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A Paze merchant account linked to the Unity Portal"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set the SDK ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["environment"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".test"]}," for UAT or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".live"]}," for production."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Paze requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USD"]}," currency, a card intent in your transaction data, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantCategoryCode"]}," in the session for payment completion on iOS. We also recommend an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetShopper"]}," callback on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CheckoutConfig"]},". These are covered in the steps below."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If portal or session setup fails, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/troubleshooting#portal-and-session-setup"},"children":["Portal and session setup"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"platform-requirements","__idx":3},"children":["Platform requirements"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Requirement"},"children":["Requirement"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Minimum / notes"},"children":["Minimum / notes"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["iOS"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["14.0+"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Xcode"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["15.0+ (Swift 5.9)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Swift"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["5.9+"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Architectures"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["arm64 (device), arm64 and x86_64 (simulator)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Transaction ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["entryType"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ecom"]}," — required on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TransactionData"]}," for Paze authorisation (not validated at presentment)"]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The iOS Paze component uses ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["static presentment"]}," — the button is shown after SDK validation without calling Paze's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["canCheckout()"]}," eligibility check. Dynamic presentment isn't available on iOS at this time."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-install-the-ios-sdk","__idx":4},"children":["Step 1: Install the iOS SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Add ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PXPCheckoutSDK"]}," to your Xcode project using Swift Package Manager:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In Xcode, go to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["File > Add Package Dependencies"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Enter the package URL: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://github.com/PXP-IO/ios-components-sdk"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Select your app target and add the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["PXPCheckoutSDK"]}," product."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Import the SDK in your Swift files:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import PXPCheckoutSDK\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Paze component is included in the main ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PXPCheckoutSDK"]}," package. You don't need a separate Paze dependency. SPM resolves transitive dependencies (including Kount) through the package manifest."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-register-your-url-callback-scheme","__idx":5},"children":["Step 2: Register your URL callback scheme"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Paze checkout opens in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ASWebAuthenticationSession"]}," and returns to your app via a custom URL scheme:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"{callbackScheme}://paze\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The callback scheme is loaded from the SDK's bundled ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sdk-config.json"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PXP_CALLBACK_SCHEME"]},"). The default is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout"]},", so the default return URL is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout://paze"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Register the scheme in your app's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Info.plist"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"xml","header":{"controls":{"copy":{}}},"source":"<key>CFBundleURLTypes</key>\n<array>\n  <dict>\n    <key>CFBundleURLSchemes</key>\n    <array>\n      <string>pxpcheckout</string>\n    </array>\n  </dict>\n</array>\n","lang":"xml"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use a URL scheme that is unique to your app. If another app registers the same scheme, checkout callbacks may be intercepted."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-create-a-session-on-your-backend","__idx":6},"children":["Step 3: Create a session on your backend"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Paze component requires a session from the PXP Sessions API. This must be done on your backend using HMAC authentication to keep your credentials secure."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"understanding-hmac-authentication","__idx":7},"children":["Understanding HMAC authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Our platform uses HMAC (Hash-based Message Authentication Code) with SHA256 for authentication to ensure secure communication and data integrity. This method involves creating a signature by hashing your request data with a secret key, which must then be included in the HTTP headers of your API request."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-an-hmac-signature","__idx":8},"children":["Create an HMAC signature"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To create the HMAC signature, you need to prepare a string that includes four parts concatenated together:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Timestamp"]},": The current time in ",{"$$mdtype":"Tag","name":"a","attributes":{"target":"_blank","href":"https://en.wikipedia.org/wiki/Unix_time"},"children":["Unix seconds"]}," (UTC) (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1754701373"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Request ID"]},": A unique GUID for this request (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ce244054-b372-42c2-9102-f0d976db69f6"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Request path"]},": The API endpoint path: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["api/v1/sessions"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Request body"]},": The complete JSON request body as a minified string"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Example request body to minify:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"merchant\": \"MERCHANT-1\",\n  \"site\": \"SITE-1\",\n  \"sessionTimeout\": 120,\n  \"merchantTransactionId\": \"txn-123\",\n  \"transactionMethod\": {\n    \"intent\": {\n      \"card\": \"Authorisation\"\n    }\n  },\n  \"amounts\": {\n    \"currencyCode\": \"USD\",\n    \"transactionValue\": 99.99\n  },\n  \"allowTransaction\": true\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When creating the HMAC signature, the request body must be minified (no whitespace or formatting). The formatted JSON above is for readability only. Paze requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currencyCode"]}," to be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USD"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-request-parameters","__idx":9},"children":["Session request parameters"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The session request accepts the following parameters:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchant"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string (≤ 20 characters)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your unique merchant identifier, as assigned by PXP. You can find it in the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://portal.pxp.io","target":"_blank"},"children":["Unity Portal"]},", by going to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant setup > Merchants"]}," and checking the ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Merchant ID"]}," column."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["site"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string (≤ 20 characters)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your unique site identifier, as assigned by PXP. You can find it in the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://portal.pxp.io","target":"_blank"},"children":["Unity Portal"]},", by going to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant setup > Sites"]}," and checking the ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Site ID"]}," column."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantTransactionId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string (≤ 50 characters)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A unique identifier of your choice that represents this transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionTimeout"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["number"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The duration of the session, in minutes."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionMethod"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["object"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Details about the transaction method, including the intent for each payment type."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionMethod.intent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["object"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The transaction intent for each payment method."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionMethod.intent.card"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The intent for Paze transactions. Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorisation"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Purchase"]}," for Paze wallet checkout.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Other session values include:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorisation"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Purchase"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Verification"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["EstimatedAuthorisation"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Payout"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amounts"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["object"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Details about the transaction amount."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amounts.currencyCode"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string (3 characters)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The currency code associated with the transaction, in ISO 4217 format. Paze supports ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USD"]}," only."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amounts.transactionValue"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["number"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The transaction amount. The numbers after the decimal will be zero padded if they are less than the expected ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currencyCode"]}," exponent. For example, USD 1 = USD 1.00."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["allowTransaction"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["boolean"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Whether or not to proceed with the transaction."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"prepare-and-send-your-request","__idx":10},"children":["Prepare and send your request"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The HMAC signature requires combining your timestamp, request ID, request path, and request body. Here's the format:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["String to hash"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{timestamp}{requestId}{requestPath}{requestBody}"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["token value"]}," as the secret key to create an HMAC SHA256 hash of this string. The result will be a hex-encoded signature."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can now put together your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header. It follows this format: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PXP-UST1 {tokenId}:{timestamp}:{signature}"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Lastly, send your request to the Sessions API. You'll need to add a request ID of your choice and include your client ID, which you can find in the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://portal.pxp.io","target":"_blank"},"children":["Unity Portal"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"curl","header":{"controls":{"copy":{}}},"source":"curl -i -X POST \\\n  'https://api-services.dev.pxp.io/api/v1/sessions' \\\n  -H 'Authorization: PXP-UST1 9aac6071-38d0-4545-9d2f-15b936af6d7f:1754701373:1DE2DFC390D7CD746A972140F26846AFA81CF85F5A0BAABA95DBC95301795EA6' \\\n  -H 'X-Request-Id: ce244054-b372-42c2-9102-f0d976db69f6' \\\n  -H 'X-Client-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"merchant\": \"MERCHANT-1\",\n  \"site\": \"SITE-1\",\n  \"sessionTimeout\": 120,\n  \"merchantTransactionId\": \"txn-123\",\n  \"transactionMethod\": {\n    \"intent\": {\n      \"card\": \"Authorisation\"\n    }\n  },\n  \"amounts\": {\n    \"currencyCode\": \"USD\",\n    \"transactionValue\": 99.99\n  },\n  \"allowTransaction\": true\n}'\n","lang":"curl"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-response","__idx":11},"children":["Session response"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If your request is successful, you'll receive a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]}," response containing the session data. When Paze is enabled for your site, the response includes Paze configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"sessionId\": \"c5f0799b-0839-43ce-abc5-5b462a98f250\",\n  \"hmacKey\": \"904bc42395d4af634e2fd48ee8c2c7f52955a1da97a3aa3d82957ff12980a7bb\",\n  \"encryptionKey\": \"20d175a669ad3f8c195c9c283fc86155\",\n  \"sessionExpiry\": \"2025-05-19T13:39:20.3843454Z\",\n  \"allowedFundingTypes\": {\n    \"cardSchemes\": [\"Visa\", \"Mastercard\", \"AmericanExpress\"],\n    \"cards\": [],\n    \"wallets\": {\n      \"paze\": {\n        \"clientId\": \"your-paze-client-id\",\n        \"profileId\": \"optional-profile-id\",\n        \"merchantCategoryCode\": \"5812\"\n      }\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Return the session response to your app together with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantTransactionId"]}," you sent in the session request. Your app must pass the same value to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.merchantTransactionId"]}," when initialising the SDK."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["iOS requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantCategoryCode"]}," in the session for the Paze complete step. If it's missing, the SDK throws ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SDK1202A"]}," when building the complete request."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Card intent on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.intent.card"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".authorisation"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".purchase"]},") controls the Unity authorisation after decryption. The Paze complete API always receives ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionType: \"PURCHASE\""]}," from the SDK — you don't configure this separately. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/how-it-works#transaction-intents"},"children":["Transaction intents"]},"."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Never embed session credentials, API tokens, or HMAC keys in your iOS app binary. Fetch session data from your backend at runtime."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-initialise-the-sdk","__idx":12},"children":["Step 4: Initialise the SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fetch session data from your backend, then initialise ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpCheckout"]}," with your configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import PXPCheckoutSDK\n\n// Session data from your backend\nlet sessionData = SessionData(\n    sessionId: session.sessionId,\n    hmacKey: session.hmacKey,\n    encryptionKey: session.encryptionKey,\n    allowedFundingTypes: AllowedFundingType(\n        wallets: Wallets(\n            paze: Paze(\n                clientId: session.pazeClientId,\n                profileId: session.pazeProfileId,\n                merchantCategoryCode: session.merchantCategoryCode\n            )\n        )\n    )\n)\n\nlet merchantTransactionId = session.merchantTransactionId\n\nlet transactionData = TransactionData(\n    amount: 99.99,\n    currency: \"USD\",\n    entryType: .ecom,\n    intent: TransactionIntentData(card: .authorisation),\n    merchantTransactionId: merchantTransactionId,\n    merchantTransactionDate: { Date() }\n)\n\nlet checkoutConfig = CheckoutConfig(\n    environment: .test,\n    session: sessionData,\n    transactionData: transactionData,\n    merchantShopperId: \"shopper-123\",\n    ownerId: \"MERCHANT-GROUP-1\",\n    clientName: \"Your Merchant\",\n    siteName: \"Your Store\",\n    onGetShopper: { async in\n        TransactionShopper(\n            id: \"shopper-123\",\n            firstName: \"John\",\n            lastName: \"Doe\",\n            email: \"customer@example.com\"\n        )\n    },\n    analyticsEvent: { event in\n        print(\"Analytics: \\(event.eventName)\")\n    }\n)\n\nlet pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantTransactionId"]}," in your session request and in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.merchantTransactionId"]},". If these values differ, reconciliation, callbacks, and transaction lookups won't align."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-create-and-configure-the-paze-button","__idx":13},"children":["Step 5: Create and configure the Paze button"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the Paze button through the SDK factory. Direct instantiation isn't supported."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"let config = PazeButtonComponentConfig()\nconfig.emailAddress = \"customer@example.com\"\nconfig.phoneNumber = \"15551234567\"\nconfig.paymentDescription = \"Order #12345\"\nconfig.billingPreference = .all\nconfig.performAVS = true\nconfig.style = PazeButtonStyleConfig(\n    color: .auto,\n    shape: .rounded,\n    label: .checkoutWith\n)\n\nconfig.onPresentmentResolved = { isVisible in\n    print(\"Paze button visible:\", isVisible)\n}\n\nconfig.onCheckoutComplete = { _ async in\n  // Return true to approve checkout and continue to complete/decrypt/authorise\n  return true\n}\n\nconfig.onPostAuthorisation = { result async in\n    // CRITICAL: Verify transaction outcome on backend before fulfilling order\n    await verifyPaymentOnBackend(systemTransactionId: result.systemTransactionId)\n}\n\nconfig.onSubmitError = { submitError async in\n    if let failed = submitError as? FailedSubmitResult {\n        print(\"Authorisation failed:\", failed.errorReason ?? \"\")\n    }\n}\n\nconfig.onError = { error in\n    print(\"Paze error [\\(error.errorCode)]: \\(error.errorMessage)\")\n}\n\nlet pazeButton = try pxpCheckout.create(.pazeButton, componentConfig: config)\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The factory validates that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["session.allowedFundingTypes.wallets.paze.clientId"]}," is present. Without it, component creation throws ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["UnsupportedFundingTypePazeSdkException"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SDK0118"]},")."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"configuration-options","__idx":14},"children":["Configuration options"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["emailAddress"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional shopper email. Validated at presentment and again at checkout (RFC 5322, max 128 characters). Passed to Paze during session creation when provided."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["phoneNumber"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional US phone: 11 digits starting with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]},", without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["+"]}," (e.g. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["15551234567"]},"). Validated when provided at presentment and checkout."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentDescription"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Statement descriptor forwarded to Paze. Maximum 25 characters. Validated during presentment initialisation."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingPreference"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["PazeBillingPreference?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Billing address collection in the Paze checkout. When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},", defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".all"]}," internally. Set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".all"]}," when using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["performAVS"]},".",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".all"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".zipCountry"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".none"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["confirmLaunch"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", Paze may prompt before launching checkout."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional session ID echoed back by Paze. Falls back to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CheckoutConfig.session.sessionId"]}," when not set."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["acceptedShippingCountries"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[String]?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ISO 3166-1 alpha-2 country codes (e.g. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"US\""]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"CA\""]},"). Each code must be exactly two uppercase letters. Validated at checkout time."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["acceptedPaymentCardNetworks"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[PazeAcceptedPaymentCardNetwork]?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Accepted card networks: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".visa"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".mastercard"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".discover"]},". When all three are selected or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},", no filter is sent."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cobrand"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[PazeCobrandConfig]?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional cobrand entries for partner branding in the Paze wallet. Each entry requires a non-empty ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cobrandName"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["enhancedTransactionData"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["PazeEnhancedTransactionDataConfig?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional checkout metadata forwarded to Paze. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/configuration#enhanced-transaction-data"},"children":["Configuration"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["style.color"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["enum"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Button colour: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".auto"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".pazeBlue"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".white"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".whiteWithOutline"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".midnightBlack"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["style.shape"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["enum"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Button shape: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".rounded"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".rectangle"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".pill"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["style.label"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["enum"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Button label: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".checkoutWith"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".checkout"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".pazeCheckout"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".donateWith"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["style.disableMaxHeight"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", removes the default 48pt height cap."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["performAVS"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", includes billing address from decrypted payload in AVS fields when the SDK submits the transaction. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},". Applies only when the SDK manages decryption and authorisation."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For the full list of component callbacks, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/events"},"children":["Events"]},". For additional configuration examples, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/configuration"},"children":["Configuration"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-6-display-the-component-in-your-app","__idx":15},"children":["Step 6: Display the component in your app"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Embed the Paze button in your SwiftUI view hierarchy using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["buildContent()"]},". The component initialises presentment automatically when the view appears."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"struct CheckoutView: View {\n    @State private var pazeButton: BaseComponent?\n\n    var body: some View {\n        VStack {\n            if let pazeButton {\n                pazeButton.buildContent()\n                    .frame(maxWidth: .infinity)\n            } else {\n                ProgressView(\"Loading Paze...\")\n            }\n        }\n        .onAppear {\n            Task { await loadPazeButton() }\n        }\n    }\n\n    private func loadPazeButton() async {\n        // Initialise pxpCheckout and create component (see steps 4–5)\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The component manages its own visibility and loading state:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The button appears only after presentment validation succeeds (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onInit"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPresentmentResolved(true)"]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A loading indicator overlays the button during checkout, complete, and authorisation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The button is non-interactive while loading."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["When presentment fails, the button is hidden, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPresentmentResolved(false)"]}," is called, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onError"]}," fires."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When the view disappears, internal state (session coordinator, loading flags) is cleaned up automatically. No manual unmount call is required."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-7-handle-callbacks","__idx":16},"children":["Step 7: Handle callbacks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Most Paze callbacks are optional. Configure them on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PazeButtonComponentConfig"]}," to customise checkout approval, decryption, and authorisation handling."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["We recommend implementing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetShopper"]}," on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CheckoutConfig"]}," when calling ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpCheckout.initialize(config:)"]}," (not on the button component). The SDK calls it when building the transaction request after decryption. The Paze button doesn't call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetShippingAddress"]}," during authorisation."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"let checkoutConfig = CheckoutConfig(\n    // ... session and transactionData\n    onGetShopper: { async in\n        TransactionShopper(\n            id: \"shopper-123\",\n            firstName: \"John\",\n            lastName: \"Doe\",\n            email: \"customer@example.com\"\n        )\n    }\n)\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you implement ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCheckoutComplete"]},", return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," to approve checkout and proceed to complete, decryption, and authorisation (default when omitted). Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," to cancel."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPazeButtonClicked"]}," for pre-checkout logic (for example, validating cart state before the Paze web session opens). The Web component's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCustomValidation"]}," callback isn't available on iOS."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a successful payment, callbacks fire in this order:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onInit"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPresentmentResolved(true)"]}," (on view attach)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPazeButtonClicked"]}," (on tap)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCheckoutComplete"]}," → return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," to continue (default when omitted)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onComplete"]}," (complete API response — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["decryptedPayload"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreDecryption"]}," → return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," to continue (default when omitted)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostDecryption"]}," (decrypted token from Unity — skipped when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreDecryption"]}," returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation"]}," → return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".proceed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".cancel"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".transactionInitData(...)"]}," (default ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".proceed"]}," when omitted)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthorisation"]}," when the SDK receives a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantSubmitResult"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onSubmitError"]}," on submission failure"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCheckoutIncomplete"]}," handles shopper cancellation and merchant rejection from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCheckoutComplete"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onError"]}," handles presentment, checkout, complete, and decryption errors."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For all component callbacks and payload types, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/events"},"children":["Events"]},"."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Never trust app callbacks for order fulfilment. Always verify payments on your backend using webhooks or the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/transaction/other/get-transaction-details"},"children":["Get transaction details API"]}," before fulfilling orders."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-8-backend-verification-critical","__idx":17},"children":["Step 8: Backend verification (critical)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["App callbacks can be manipulated by malicious users. You must verify all payments on your backend before fulfilling orders."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the same webhook and API verification patterns described in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/implementation#step-8-backend-verification-critical"},"children":["card implementation guide"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"understanding-the-paze-payment-flow","__idx":18},"children":["Understanding the Paze payment flow"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["On iOS, checkout opens in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ASWebAuthenticationSession"]}," rather than an embedded Paze JavaScript SDK. The SDK calls the PXP create-session API, opens the returned checkout URL, and handles the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout://paze"]}," callback (or your configured scheme) before proceeding to complete, decryption, and authorisation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a full sequence diagram and stage descriptions, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/paze/how-it-works"},"children":["How it works"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"backend-decryption","__idx":19},"children":["Backend decryption"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreDecryption"]},", the SDK skips built-in decryption and authorisation. Your backend must decrypt the secured payload and submit the scheme token transaction."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-configure-the-app","__idx":20},"children":["1. Configure the app"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreDecryption"]}," and forward the secured payload to your backend in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onComplete"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"config.onCheckoutComplete = { _ async in true }\n\nconfig.onPreDecryption = { async in false }\n\nconfig.onComplete = { result async in\n    guard let securedPayload = result.completeDecodedResponse?.securedPayload else { return }\n\n  // Call your backend — never call the PXP decrypt API directly from the app\n    await sendToBackendForDecryption(securedPayload: securedPayload)\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onComplete"]}," callback receives a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PazeCompleteResult"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completeDecodedResponse.securedPayload"]},". Pass this value to your backend."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-decrypt-the-secured-payload","__idx":21},"children":["2. Decrypt the secured payload"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["From your backend, call the PXP decrypt-token endpoint using HMAC authentication. Use the same HMAC pattern as ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#step-3-create-a-session-on-your-backend"},"children":["session creation"]},"."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreDecryption"]}," returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," or is omitted, the iOS SDK decrypts internally using the session-authenticated decrypt API. Use the wallets endpoint below only for manual backend decryption."]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Environment"},"children":["Environment"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Endpoint"},"children":["Endpoint"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Test"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST https://api-services.dev.pxp.io/api/v1/wallets/Paze/decrypt-token"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Live"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST https://api-services.pxp.io/api/v1/wallets/Paze/decrypt-token"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Headers:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Content-Type: application/json"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization: PXP-UST1 <tokenId>:<timestamp>:<hmac>"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Request-Id: <uuid>"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Client-Id: <clientId>"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Request body:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"site\": \"your-site-id\",\n  \"token\": \"eyJhdWQHBmaW...\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["token"]}," value is the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["securedPayload"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onComplete"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-submit-the-scheme-token-transaction","__idx":22},"children":["3. Submit the scheme token transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the decrypted ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData"]}," to submit an authorisation through the PXP ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/transaction"},"children":["Create transaction API"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /api/v1/transactions"]},") from your backend."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"cryptogram-and-eci-handling","__idx":23},"children":["Cryptogram and ECI handling"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Decrypt path"},"children":["Decrypt path"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Where cryptogram / ECI go"},"children":["Where cryptogram / ECI go"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["SDK-managed"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The gateway stores ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schemeTokenCryptogram"]}," and ECI in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["session"]}," before the SDK submits the transaction. You don't pass them in the app transaction request."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Manual backend"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/v1/wallets/Paze/decrypt-token"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Map fields from the decrypt response into your transaction request: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData.schemeTokenCryptogram"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData.card.schemeTokenCryptogram"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData.eci"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["threeDSecureData.electronicCommerceIndicator"]}," when required."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After submission, verify the transaction on your backend before fulfilling the order. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#step-8-backend-verification-critical"},"children":["Backend verification"]},"."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When using manual decryption, you are responsible for securely calling the decrypt API and submitting the transaction from your backend. The SDK doesn't proceed with authorisation."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"complete-example","__idx":24},"children":["Complete example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's a complete SwiftUI example showing Paze integration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import SwiftUI\nimport PXPCheckoutSDK\n\nstruct PazeCheckoutView: View {\n    @State private var pxpCheckout: PxpCheckout?\n    @State private var pazeButton: BaseComponent?\n    @State private var isLoading = true\n    @State private var errorMessage: String?\n\n    var body: some View {\n        VStack(spacing: 16) {\n            if isLoading {\n                ProgressView(\"Connecting...\")\n            } else if let errorMessage {\n                Text(errorMessage).foregroundColor(.red)\n            } else if let pazeButton {\n                pazeButton.buildContent()\n                    .frame(maxWidth: .infinity)\n            }\n        }\n        .padding()\n        .onAppear { Task { await setupPaze() } }\n    }\n\n    private func setupPaze() async {\n        do {\n            let session = try await fetchSessionFromBackend()\n            let checkout = try createPxpCheckout(session: session)\n            let config = buildPazeConfig()\n            let component = try checkout.create(.pazeButton, componentConfig: config)\n\n            await MainActor.run {\n                self.pxpCheckout = checkout\n                self.pazeButton = component\n                self.isLoading = false\n            }\n        } catch {\n            await MainActor.run {\n                self.errorMessage = error.localizedDescription\n                self.isLoading = false\n            }\n        }\n    }\n\n    private func createPxpCheckout(session: BackendSession) throws -> PxpCheckout {\n        let sessionData = SessionData(\n            sessionId: session.sessionId,\n            hmacKey: session.hmacKey,\n            encryptionKey: session.encryptionKey,\n            allowedFundingTypes: AllowedFundingType(\n                wallets: Wallets(\n                    paze: Paze(\n                        clientId: session.pazeClientId,\n                        profileId: session.pazeProfileId,\n                        merchantCategoryCode: session.merchantCategoryCode\n                    )\n                )\n            )\n        )\n\n        let transactionData = TransactionData(\n            amount: session.amount,\n            currency: \"USD\",\n            entryType: .ecom,\n            intent: TransactionIntentData(card: .authorisation),\n            merchantTransactionId: session.merchantTransactionId,\n            merchantTransactionDate: { Date() }\n        )\n\n        let config = CheckoutConfig(\n            environment: .test,\n            session: sessionData,\n            transactionData: transactionData,\n            merchantShopperId: \"shopper-123\",\n            ownerId: session.ownerId,\n            clientName: \"Your Merchant\",\n            siteName: \"Your Store\",\n            onGetShopper: { async in\n                TransactionShopper(\n                    id: \"shopper-123\",\n                    firstName: \"John\",\n                    lastName: \"Doe\",\n                    email: \"customer@example.com\"\n                )\n            }\n        )\n\n        return try PxpCheckout.initialize(config: config)\n    }\n\n    private func buildPazeConfig() -> PazeButtonComponentConfig {\n        let config = PazeButtonComponentConfig()\n        config.emailAddress = \"customer@example.com\"\n        config.style = PazeButtonStyleConfig(color: .auto, shape: .rounded, label: .checkoutWith)\n\n        config.onCheckoutComplete = { _ async in true }\n\n        config.onPostAuthorisation = { result async in\n            await verifyPaymentOnBackend(systemTransactionId: result.systemTransactionId)\n        }\n\n        config.onSubmitError = { submitError async in\n            if let failed = submitError as? FailedSubmitResult {\n                print(\"Authorisation failed:\", failed.errorReason ?? \"\")\n            }\n        }\n\n        config.onError = { error in\n            print(\"Paze error [\\(error.errorCode)]: \\(error.errorMessage)\")\n        }\n\n        return config\n    }\n\n    private func fetchSessionFromBackend() async throws -> BackendSession {\n        // Replace with your backend API call\n        fatalError(\"Implement session fetch\")\n    }\n\n    private func verifyPaymentOnBackend(systemTransactionId: String) async {\n        // Replace with your verification logic\n    }\n}\n","lang":"swift"},"children":[]}]},"headings":[{"value":"Implementation","id":"implementation","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Before you start","id":"before-you-start","depth":2},{"value":"Platform requirements","id":"platform-requirements","depth":3},{"value":"Step 1: Install the iOS SDK","id":"step-1-install-the-ios-sdk","depth":2},{"value":"Step 2: Register your URL callback scheme","id":"step-2-register-your-url-callback-scheme","depth":2},{"value":"Step 3: Create a session on your backend","id":"step-3-create-a-session-on-your-backend","depth":2},{"value":"Understanding HMAC authentication","id":"understanding-hmac-authentication","depth":3},{"value":"Create an HMAC signature","id":"create-an-hmac-signature","depth":3},{"value":"Session request parameters","id":"session-request-parameters","depth":3},{"value":"Prepare and send your request","id":"prepare-and-send-your-request","depth":3},{"value":"Session response","id":"session-response","depth":3},{"value":"Step 4: Initialise the SDK","id":"step-4-initialise-the-sdk","depth":2},{"value":"Step 5: Create and configure the Paze button","id":"step-5-create-and-configure-the-paze-button","depth":2},{"value":"Configuration options","id":"configuration-options","depth":3},{"value":"Step 6: Display the component in your app","id":"step-6-display-the-component-in-your-app","depth":2},{"value":"Step 7: Handle callbacks","id":"step-7-handle-callbacks","depth":2},{"value":"Step 8: Backend verification (critical)","id":"step-8-backend-verification-critical","depth":2},{"value":"Understanding the Paze payment flow","id":"understanding-the-paze-payment-flow","depth":2},{"value":"Backend decryption","id":"backend-decryption","depth":2},{"value":"1. Configure the app","id":"1-configure-the-app","depth":3},{"value":"2. Decrypt the secured payload","id":"2-decrypt-the-secured-payload","depth":3},{"value":"3. Submit the scheme token transaction","id":"3-submit-the-scheme-token-transaction","depth":3},{"value":"Cryptogram and ECI handling","id":"cryptogram-and-eci-handling","depth":4},{"value":"Complete example","id":"complete-example","depth":2}],"frontmatter":{"seo":{"title":"Implementation"}},"lastModified":"2026-06-30T10:00:28.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/ios/paze/implementation","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}