{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","admonition","br","details","required","tabs","tab"]},"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 Android 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 Compose."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Handle callbacks:"]}," Respond to payment success, errors, and checkout redirects."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The component automatically handles Paze presentment, Custom Tab 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/android/paze/onboarding"},"children":["Paze onboarding"]}," in the Unity Portal before integrating the component. If you have not installed the SDK yet, start with ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/install"},"children":["Install the Android SDK"]},". 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":["Android API 24 or later with Jetpack Compose"]},{"$$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":["Environment.TEST"]}," for UAT or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Environment.LIVE"]}," for production."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Paze requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USD"]}," currency and a card intent in your transaction data. Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.entryType"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["EntryType.Ecom"]}," for Paze authorisation requests. We also recommend an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetShopper"]}," callback on SDK initialisation. 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/android/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":{"data-label":"Requirement"},"children":["Requirement"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Minimum / notes"},"children":["Minimum / notes"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Android API"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["24+"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["UI framework"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Jetpack Compose"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Transaction ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["entryType"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["EntryType.Ecom"]}," (recommended for Paze authorisation; not validated at presentment on the standalone button)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Browser"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Chrome or another Custom Tabs-compatible browser for checkout"]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The button uses static presentment after SDK validation. Optional ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["emailAddress"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["phoneNumber"]}," are validated when provided. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/how-it-works#presentment"},"children":["How it works"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-install-the-android-sdk","__idx":4},"children":["Step 1: Install the Android SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Install the PXP Android Components SDK from Maven Central and configure Gradle. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/install"},"children":["Install the Android SDK"]}," for repositories, Compose setup, dependency version, permissions, and verification steps."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Paze component is included in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["io.pxp:android-components-sdk"]},". You don't need a separate Paze dependency."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Import the SDK in your Kotlin files:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import com.pxp.PxpCheckout\nimport com.pxp.checkout.components.paze.PazeButtonComponent\nimport com.pxp.checkout.components.paze.PazeButtonComponentConfig\nimport com.pxp.checkout.models.AllowedFundingTypes\nimport com.pxp.checkout.models.PazeWalletConfig\nimport com.pxp.checkout.models.SessionConfig\nimport com.pxp.checkout.models.WalletsConfig\nimport com.pxp.checkout.types.ComponentType\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Paze component is part of the main SDK package. You don't need a separate Paze dependency."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-handle-checkout-redirects","__idx":5},"children":["Step 2: Handle checkout redirects"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Paze checkout opens in a Chrome Custom Tab and returns to your app via a deep link. The SDK merges ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PazeSdkRedirectActivity"]}," for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout://callback"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout://paze"]},". You don't need your own intent filter for these default schemes."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When checkout completes, the SDK forwards the callback to your host Activity. Implement ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onNewIntent"]}," and deliver the result to your Paze component:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class CheckoutActivity : ComponentActivity() {\n\n    private lateinit var pazeButton: PazeButtonComponent\n\n    override fun onNewIntent(intent: Intent) {\n        super.onNewIntent(intent)\n        setIntent(intent)\n        intent.deliverPazeCheckoutResult(pazeButton)\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import com.pxp.checkout.components.paze.payment.deliverPazeCheckoutResult\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK registers your host Activity automatically via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PazeRedirectRegistry"]}," when checkout launches from an Activity context. Ensure your checkout screen uses an Activity context (not only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Application"]}," context) when creating ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpCheckout"]},". The component also checks for pending redirect results when the host Activity resumes."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onNewIntent"]}," doesn't call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["deliverPazeCheckoutResult"]},", checkout may complete in the Custom Tab but your app won't process the payment."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a custom callback scheme, register it through ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PazeRedirectRegistry"]}," and add a matching intent filter in your host app. See the SDK's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PazeRedirectActivity"]}," for custom scheme integration."]},{"$$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":{"width":"40%","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":"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."]}]},{"$$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":[{"$$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 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":["Your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header follows this format: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PXP-UST1 {tokenId}:{timestamp}:{signature}"]},"."]},{"$$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":["Include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantCategoryCode"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["allowedFundingTypes.wallets.paze"]}," in your session response. The SDK checks it when calling Paze complete after checkout; if missing, it throws ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SDK1202A"]},"."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When mapping the session response to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SessionConfig"]},", include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["locale"]}," as required by the SDK type."]}]},{"$$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 Android app binary. Fetch session data from your backend at runtime."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"fetch-session-data-from-your-app","__idx":12},"children":["Fetch session data from your app"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Call your backend session endpoint from a coroutine and deserialise the response into the types your SDK initialisation expects:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"suspend fun fetchSessionFromBackend(): SessionResponse = withContext(Dispatchers.IO) {\n    val connection = URL(\"https://your-backend/api/sessions\")\n        .openConnection() as HttpURLConnection\n    connection.requestMethod = \"POST\"\n    connection.connect()\n    // Deserialise connection.inputStream into SessionResponse\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your backend endpoint wraps the PXP Sessions API. The request format and HMAC signing described above apply on the server, not in the Android app."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-initialise-the-sdk","__idx":13},"children":["Step 4: Initialise the SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fetch session data from your backend, then build ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpCheckout"]}," with your configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val sessionData = SessionConfig(\n    sessionId = session.sessionId,\n    hmacKey = session.hmacKey,\n    data = session.data,\n    encryptionKey = session.encryptionKey,\n    locale = \"en-US\",\n    allowedFundingTypes = AllowedFundingTypes(\n        wallets = WalletsConfig(\n            paze = PazeWalletConfig(\n                clientId = session.pazeClientId,\n                profileId = session.pazeProfileId,\n                merchantCategoryCode = session.merchantCategoryCode,\n            ),\n        ),\n    ),\n)\n\nval transactionData = TransactionData(\n    amount = 99.99,\n    currency = \"USD\",\n    merchant = \"MERCHANT-1\",\n    intent = TransactionIntentData(card = CardIntentType.Authorisation),\n    merchantTransactionId = session.merchantTransactionId,\n    merchantTransactionDate = {\n        LocalDateTime.now(ZoneOffset.UTC)\n            .format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'\"))\n    },\n    entryType = EntryType.Ecom,\n)\n\nval sdkConfig = PxpSdkConfig(\n    environment = Environment.TEST,\n    session = sessionData,\n    transactionData = transactionData,\n    clientName = \"Your Merchant\",\n    siteName = \"Your Store\",\n    ownerType = \"MerchantGroup\",\n    ownerId = \"MERCHANT-1\",\n    onGetShopper = {\n        Shopper(\n            id = \"shopper-123\",\n            firstName = \"John\",\n            lastName = \"Doe\",\n            email = \"customer@example.com\",\n        )\n    },\n    analyticsEvent = { event -> Log.d(\"PazeAnalytics\", event.eventName) },\n)\n\nval checkout = PxpCheckout.builder()\n    .withConfig(sdkConfig)\n    .withContext(context)\n    .build()\n","lang":"kotlin"},"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 will not align."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-create-and-configure-the-paze-button","__idx":14},"children":["Step 5: Create and configure the Paze button"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the Paze button through the SDK factory:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val config = PazeButtonComponentConfig().apply {\n    emailAddress = \"customer@example.com\"\n    phoneNumber = \"15551234567\"\n    paymentDescription = \"Order #12345\"\n    billingPreference = PazeBillingPreference.ALL\n    performAVS = true\n    style = PazeButtonStyleConfig(\n        color = PazeButtonColor.AUTO,\n        shape = PazeButtonShape.DEFAULT,\n        label = PazeButtonLabel.CHECKOUT_WITH,\n    )\n\n    onPresentmentResolved = { customTabAvailable ->\n        Log.d(\"Paze\", \"Custom Tab available: $customTabAvailable\")\n    }\n    onPazeButtonClicked = {\n        clearCheckoutErrors()\n    }\n    onCheckoutComplete = { result ->\n        // Return false to reject checkout after the Custom Tab returns\n        true\n    }\n    onCheckoutIncomplete = { result ->\n        Log.d(\"Paze\", \"Checkout incomplete: ${result.reason}\")\n    }\n    onComplete = { result ->\n        Log.d(\"Paze\", \"Payload ID: ${result.completeDecodedResponse?.payloadId}\")\n    }\n    onPreDecryption = { true }\n    onPostDecryption = { decryptedPayload ->\n        val maskedToken = decryptedPayload.fundingData.networkToken.take(6) + \"...\"\n        Log.d(\"Paze\", \"Decrypted token prefix: $maskedToken\")\n    }\n    onPreAuthorisation = { PazePreAuthorisationResult.Proceed }\n    onPostAuthorisation = { result ->\n        verifyPaymentOnBackend(systemTransactionId = result.systemTransactionId)\n    }\n    onSubmitError = { result ->\n        val failed = result as? FailedSubmitResult\n        Log.e(\"Paze\", \"Submit error: ${failed?.errorReason}\")\n    }\n    onError = { error ->\n        Log.e(\"Paze\", \"Error [${error.errorCode}]: ${error.message}\")\n    }\n}\n\nval pazeButton = checkout.createComponent<PazeButtonComponent>(\n    ComponentType.PAZE_BUTTON,\n    config,\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Missing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clientId"]}," is detected at presentment and throws ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SDK1202"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For the full list of component properties and callbacks, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/configuration"},"children":["Configuration"]}," and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/events"},"children":["Events"]},"."]},{"$$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":["Render the Paze button in your Compose hierarchy:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"@Composable\nfun CheckoutScreen(pazeButton: PazeButtonComponent) {\n    Column(modifier = Modifier.padding(16.dp)) {\n        pazeButton.Content(modifier = Modifier.fillMaxWidth())\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Presentment runs automatically when you render ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Content()"]}," in Compose with a valid ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context"]},". The button is shown only when presentment validation succeeds; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPresentmentResolved"]}," indicates Custom Tab availability when the button is visible."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During create-session, complete, and authorisation, the SDK shows a loading indicator on the button and ignores taps while loading is active. After the Custom Tab opens, the button is interactive again until the redirect returns."]},{"$$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":["PxpSdkConfig"]}," (not on the button component). The SDK calls it when building the transaction request after decryption."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPazeButtonClicked"]}," for non-blocking side effects before the Custom Tab opens (for example analytics or clearing error messages). Disable the button in your UI to block checkout before the tab opens, or return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCheckoutComplete"]}," to block the flow after checkout returns."]},{"$$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":["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"]}," (after presentment validation, when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Content()"]}," is displayed)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPazeButtonClicked"]}," (on tap, after checkout validation succeeds)"]},{"$$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":"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"]}," (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"]}," → ",{"$$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"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantSubmitResult"]}," (verify on your backend), or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onSubmitError"]}," on hard 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/android/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/android/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 Android, checkout opens in a Chrome Custom Tab. The SDK calls the PXP create-session API, opens the returned checkout URL, and handles the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout://callback"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pxpcheckout://paze"]}," redirect before calling the PXP complete API, 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/android/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":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreDecryption"]}," controls whether the SDK decrypts the secured payload or your backend does:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["SDK-managed (recommended):"]}," Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," or omit the callback. The SDK calls the PXP decrypt API, invokes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostDecryption"]},", then continues through ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation"]}," → transaction submission → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthorisation"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant-managed:"]}," Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},". The SDK skips decrypt and authorisation. Read ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["result.completeDecodedResponse?.securedPayload"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onComplete"]}," and POST it to your backend, which calls the PXP decrypt endpoint and submits the scheme token transaction."]}]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"SDK-managed decrypt (recommended)","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"config.onPreDecryption = { true }\nconfig.onPostDecryption = { decryptedPayload ->\n    val masked = decryptedPayload.fundingData.networkToken.take(6) + \"...\"\n    Log.d(\"Paze\", \"Decrypted token prefix: $masked\")\n}\n","lang":"kotlin"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Merchant-managed decrypt","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"config.onPreDecryption = { false }\nconfig.onComplete = { result ->\n    val securedPayload = result.completeDecodedResponse?.securedPayload ?: return@onComplete\n    sendToBackendForDecryption(securedPayload)\n}\n","lang":"kotlin"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"backend-decrypt-and-transaction-apis","__idx":20},"children":["Backend decrypt and transaction APIs"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For merchant-managed decryption, configure the app as shown above, then call these endpoints from your backend:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["From your backend, call the PXP decrypt-token endpoint using HMAC authentication."]},{"$$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 Android SDK decrypts internally via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /api/v1/paze/decrypt-token"]}," using session authentication. Use the wallets endpoint below only for manual backend decryption with HMAC (PXP-UST1)."]}]},{"$$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":["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":"submit-the-scheme-token-transaction","__idx":21},"children":["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":"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":{"width":"20%","data-label":"Decrypt path"},"children":["Decrypt path "]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Transaction payload"},"children":["Transaction payload"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["SDK-managed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The Android SDK submits ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schemeTokenNumber"]},", expiry, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["walletType: \"Paze\""]}," via session-authenticated ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processTransaction"]},". Cryptogram handling is managed by the gateway, not included explicitly in the SDK client request."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Manual backend"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Map ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["networkToken"]},", expiry, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["walletType: \"Paze\""]},", and any cryptogram or ECI fields from the decrypt response into your HMAC transaction request."]}]}]}]}]},{"$$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":"Heading","attributes":{"level":2,"id":"complete-example","__idx":22},"children":["Complete example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class PazeCheckoutActivity : ComponentActivity() {\n\n    private var checkout: PxpCheckout? = null\n    private var pazeButton: PazeButtonComponent? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContent {\n            var isLoading by remember { mutableStateOf(true) }\n            var errorMessage by remember { mutableStateOf<String?>(null) }\n\n            LaunchedEffect(Unit) {\n                try {\n                    val session = fetchSessionFromBackend()\n                    val pxpCheckout = createPxpCheckout(session)\n                    val component = pxpCheckout.createComponent<PazeButtonComponent>(\n                        ComponentType.PAZE_BUTTON,\n                        buildPazeConfig(),\n                    )\n                    checkout = pxpCheckout\n                    pazeButton = component\n                    isLoading = false\n                } catch (e: Exception) {\n                    errorMessage = e.message\n                    isLoading = false\n                }\n            }\n\n            when {\n                isLoading -> CircularProgressIndicator()\n                errorMessage != null -> Text(errorMessage!!, color = Color.Red)\n                pazeButton != null -> pazeButton!!.Content(Modifier.fillMaxWidth())\n            }\n        }\n    }\n\n    override fun onNewIntent(intent: Intent) {\n        super.onNewIntent(intent)\n        setIntent(intent)\n        pazeButton?.let { intent.deliverPazeCheckoutResult(it) }\n    }\n\n    private fun buildPazeConfig() = PazeButtonComponentConfig().apply {\n        emailAddress = \"customer@example.com\"\n        onCheckoutComplete = { _ -> true }\n        onPostAuthorisation = { result ->\n            verifyPaymentOnBackend(result.systemTransactionId)\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"whats-next","__idx":23},"children":["What's next?"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/configuration"},"children":["Configuration"]},":"]}," Explore advanced Paze button options and styling."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/events"},"children":["Events"]},":"]}," Reference all callbacks and payload types."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/testing"},"children":["Testing"]},":"]}," Test your integration in the UAT environment."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paze/troubleshooting"},"children":["Troubleshooting"]},":"]}," Diagnose common integration issues."]}]}]},"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 Android SDK","id":"step-1-install-the-android-sdk","depth":2},{"value":"Step 2: Handle checkout redirects","id":"step-2-handle-checkout-redirects","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":"Fetch session data from your app","id":"fetch-session-data-from-your-app","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":"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":"Backend decrypt and transaction APIs","id":"backend-decrypt-and-transaction-apis","depth":3},{"value":"Submit the scheme token transaction","id":"submit-the-scheme-token-transaction","depth":3},{"value":"Complete example","id":"complete-example","depth":2},{"value":"What's next?","id":"whats-next","depth":2}],"frontmatter":{"seo":{"title":"Implementation"}},"lastModified":"2026-07-01T15:11:56.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/android/paze/implementation","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}