{"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 card components into your application."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Card components provide flexible, secure payment forms for collecting card details. Every 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 & mount"]},": Build the component with your configuration and render it to your page."]},{"$$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":["Components automatically handle card tokenisation, validation, 3D Secure authentication, 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. Frontend 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":["Components for Web is already available to all Unity customers. No additional activation required."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-install-the-web-sdk-library","__idx":3},"children":["Step 1: Install the Web SDK library"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Install the latest version of the Web SDK from the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://www.npmjs.com/package/@pxpio/web-components-sdk","target":"_blank"},"children":["npm public registry"]},". You'll need to have Node.js 22.x or higher."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"npm i @pxpio/web-components-sdk\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Card components are part of the main SDK package. Import ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpCheckout"]}," directly from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@pxpio/web-components-sdk"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-get-your-api-credentials","__idx":4},"children":["Step 2: Get your API credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In order to initialise Components for Web, you'll need to send authenticated requests to the PXP API."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To get your credentials:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://portal.pxp.io","target":"_blank"},"children":["Unity Portal"]},", go to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant setup > Merchant groups"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Select a merchant group."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inbound calls"]}," tab."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Copy the ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Client ID"]}," in the top-right corner."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["New token"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Choose a number of days before token expiry. For example, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["30"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Save"]}," to confirm. Your token is now created."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Copy the token ID and token value. Make sure to keep these confidential to protect the integrity of your authentication process."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["As best practice, we recommend regularly generating and implementing new tokens."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-create-a-session-on-your-backend","__idx":5},"children":["Step 3: Create a session on your backend"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Components for Web 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":6},"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":7},"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 milliseconds"]}," (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\": \"0ce72cfd-014d-4256-a006-a56601b2ffc4\",\n  \"transactionMethod\": {\n    \"intent\": {\n      \"card\": \"Authorisation\"\n    }\n  },\n  \"amounts\": {\n    \"currencyCode\": \"USD\",\n    \"transactionValue\": 25.00\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."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-request-parameters","__idx":8},"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":"td","attributes":{},"children":["The intent for card, Apple Pay, Google Pay, or Paze transactions.",{"$$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":["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. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/supported-currencies"},"children":["Supported payment currencies"]},"."]}]},{"$$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, GBP 1.1 = GBP 1.10, USD 1 = USD 1.00, or BHD 1.3 = 1.300. The transaction will be rejected if numbers after the decimal are greater than the expected ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currencyCode"]}," exponent (e.g., GBP 1.234), or if a decimal is supplied when the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currencyCode"]}," of the exponent does not require it (e.g., JPY 1.0)."]}]},{"$$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":9},"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":["For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"1754701373ce244054-b372-42c2-9102-f0d976db69f6api/v1/sessions{\"merchant\":\"MERCHANT-1\",\"site\":\"SITE-1\",\"sessionTimeout\":120,\"merchantTransactionId\":\"0ce72cfd-014d-4256-a006-a56601b2ffc4\",\"transactionMethod\":{\"intent\":{\"card\":\"Authorisation\"}},\"amounts\":{\"currencyCode\":\"USD\",\"transactionValue\":25.00},\"allowTransaction\":true}\n"},"children":[]},{"$$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 like:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"1DE2DFC390D7CD746A972140F26846AFA81CF85F5A0BAABA95DBC95301795EA6\n"},"children":[]},{"$$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}"]},". For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"PXP-UST1 9aac6071-38d0-4545-9d2f-15b936af6d7f:1754701373:1DE2DFC390D7CD746A972140F26846AFA81CF85F5A0BAABA95DBC95301795EA6\n"},"children":[]},{"$$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":"p","attributes":{},"children":["Here's a full example of what your request might look like:"]},{"$$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\": \"0ce72cfd-014d-4256-a006-a56601b2ffc4\",\n  \"transactionMethod\": {\n    \"intent\": {\n      \"card\": \"Authorisation\"\n    }\n  },\n  \"amounts\": {\n    \"currencyCode\": \"USD\",\n    \"transactionValue\": 25.00\n  },\n  \"allowTransaction\": true\n}'\n","lang":"curl"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-response","__idx":10},"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:"]},{"$$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\": [\n      \"Visa\",\n      \"Diners\",\n      \"Mastercard\",\n      \"AmericanExpress\"\n    ],\n    \"cards\": []\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-initialise-the-sdk-on-your-frontend","__idx":11},"children":["Step 4: Initialise the SDK on your frontend"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Import ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpCheckout"]}," from the SDK and initialise with your configuration."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"import { PxpCheckout, IntentType } from '@pxpio/web-components-sdk';\n\n// Get session data from your backend\nconst sessionData = await fetch('/api/sessions', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' }\n}).then(response => response.json());\n\n// Initialise the SDK\nconst pxpSdk = PxpCheckout.initialize({\n  environment: 'test',\n  session: sessionData,\n  ownerId: 'MERCHANT-1',\n  ownerType: 'MerchantGroup',\n  transactionData: {\n    currency: 'USD',\n    amount: 25,\n    entryType: 'Ecom',\n    intent: {\n      card: IntentType.Authorisation\n    },\n    merchantTransactionId: crypto.randomUUID(),\n    merchantTransactionDate: () => new Date().toISOString()\n  },\n  kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection\n  onGetShopper: () => Promise.resolve({ \n    id: 'shopper-123',\n    email: 'customer@example.com',\n    firstName: 'John',\n    lastName: 'Doe'\n  })\n});\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"configuration-parameters","__idx":12},"children":["Configuration parameters"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["initialize()"]}," method accepts the following configuration 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":["environment"]},{"$$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 environment type.",{"$$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":["test"]},": For development and testing."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["production"]},": For live transactions."]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["session"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["SessionData"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Details about the checkout session returned from the Unity Sessions API. Includes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hmacKey"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["allowedFundingTypes"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerId"]},{"$$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 or merchant group 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"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerType"]},{"$$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":["Always set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'MerchantGroup'"]}," for Components for Web."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData"]},{"$$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."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.currency"]},{"$$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. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/supported-currencies"},"children":["Supported payment currencies"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.amount"]},{"$$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. Must match the currency's expected decimal places."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.entryType"]},{"$$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 entry type.",{"$$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":["Ecom"]},": E-commerce transactions."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Moto"]},": Mail order/telephone order transactions."]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.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 intents for each payment method. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/web/card/how-it-works#supported-transaction-intents"},"children":["supported transaction intents"]}," for details."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.intent.card"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The intent for card, Google Pay, Apple Pay, or Paze transactions.",{"$$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":["Authorisation"]}]},{"$$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":["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":["Payout"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.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 for this transaction. Use a UUID or order ID."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.merchantTransactionDate"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["function"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A function that returns the current date and time in ISO 8601 format."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetShopper"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["function"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Function to retrieve shopper information. Required for card tokenisation and Card-on-File functionality. Returns a Promise with shopper object containing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["email"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["firstName"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lastName"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetShippingAddress"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["function"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Function to retrieve shipping address information. Returns a Promise with address object."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kountDisabled"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["boolean"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Whether to disable the Kount fraud detection service. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," (fraud detection enabled)."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-create-and-configure-a-component","__idx":13},"children":["Step 5: Create and configure a component"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the SDK's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["create()"]}," method to build a component with your desired configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"const newCard = pxpSdk.create('new-card', {\n  fields: {\n    cardNumber: {\n      required: true,\n      placeholder: '1234 5678 9012 3456'\n    },\n    expiryDate: {\n      required: true,\n      placeholder: 'MM/YY'\n    },\n    cvc: {\n      required: true,\n      placeholder: '123'\n    },\n    holderName: {\n      required: true,\n      placeholder: 'John Doe'\n    }\n  },\n  submit: {\n    submitText: 'Pay $25.00',\n    styles: {\n      backgroundColor: '#4CAF50',\n      color: 'white',\n      padding: '15px',\n      borderRadius: '6px',\n      fontSize: '16px',\n      fontWeight: 'bold',\n      width: '100%'\n    },\n    onPostAuthorisation: async (data) => {\n      // CRITICAL: Verify on backend before fulfilling order\n      await verifyPaymentOnBackend(data);\n    }\n  }\n});\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["new-card"]}," component shown above is just one of many available components. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/web/card/pre-built-components"},"children":["Pre-built components"]}," and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/web/card/standalone-components"},"children":["Standalone components"]}," for a full list of available options."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-6-mount-the-component-to-your-page","__idx":14},"children":["Step 6: Mount the component to your page"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Add a container element to your page where the component will be rendered:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<div id=\"new-card-container\"></div>\n","lang":"html"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then call the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mount()"]}," method to render the component:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"newCard.mount('new-card-container');\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["At this point, the component will:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Render all configured input fields."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Apply validation rules automatically."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Handle card brand detection."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Display the submit button."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Process payments when submitted."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-7-handle-callbacks","__idx":15},"children":["Step 7: Handle callbacks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Card components use callbacks to notify you of important events during the payment lifecycle."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"ongetshopper-callback","__idx":16},"children":["onGetShopper callback"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Returns shopper information for card tokenisation and Card-on-File functionality."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"onGetShopper: () => Promise.resolve({ \n  id: 'shopper-123',\n  email: 'customer@example.com',\n  firstName: 'John',\n  lastName: 'Doe',\n  phoneNumber: '+1-555-0123'\n})\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpostauthorisation-callback","__idx":17},"children":["onPostAuthorisation callback"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fires when payment succeeds. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["CRITICAL: Always verify on your backend before fulfilling orders."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"onPostAuthorisation: async (data) => {\n  // Verify payment on backend\n  const verified = await fetch('/api/verify-payment', {\n    method: 'POST',\n    body: JSON.stringify({\n      systemTransactionId: data.systemTransactionId,\n      merchantTransactionId: data.merchantTransactionId\n    })\n  }).then(r => r.json());\n  \n  if (verified.success) {\n    globalThis.location.href = `/success?orderId=${verified.orderId}`;\n  }\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onsubmiterror-callback","__idx":18},"children":["onSubmitError callback"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Handles payment failures and displays error messages to the user."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"onSubmitError: (error) => {\n  console.error('Payment failed:', error);\n  alert('Payment failed. Please check your card details and try again.');\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3d-secure-callbacks-required-if-using-3ds","__idx":19},"children":["3D Secure callbacks (required if using 3DS)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you want to use 3DS authentication, implement these callbacks. If you want to skip 3DS, omit these callbacks."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your backend must set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authentication = true"]}," via the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://developer.pxp.io/apis/session/other/modify-session"},"children":["Modify session API"]}," if you include these callbacks, or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," if you omit them. Mismatched decisions will cause error ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAD4005: Authentication decision is required but not provided"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"onPreInitiateAuthentication: () => {\n  return {\n    providerId: 'pxpfinancial',\n    timeout: 12\n  };\n},\nonPostInitiateAuthentication: (data) => {\n  console.log('3DS authentication initiated:', data);\n},\nonPreAuthentication: async () => {\n  return {\n    merchantCountryNumericCode: '100',\n    merchantLegalName: 'YourMerchantName',\n    challengeWindowSize: 1,\n    requestorChallengeIndicator: '02'\n  };\n},\nonPostAuthentication: (data) => {\n  console.log('3DS authentication completed:', data);\n  // Optional: Retrieve authentication details from backend\n  // and update session decision if needed\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpreauthorisation-callback","__idx":20},"children":["onPreAuthorisation callback"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Provides additional transaction data before authorisation. Most merchants return an empty object to proceed."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"onPreAuthorisation: (data) => {\n  return {}; // Return empty object to proceed\n  // Or optionally include AVS/risk screening data\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Never trust frontend callbacks for order fulfillment. Always verify payments on your backend using webhooks or the Query Transaction API before fulfilling orders."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Want to add validation before payment or handle field-level events? See the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/web/card/events"},"children":["Events guide"]}," for all available callbacks."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-8-backend-verification-critical","__idx":21},"children":["Step 8: Backend verification (CRITICAL)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Frontend callbacks can be manipulated by malicious users. You must verify all payments on your backend before fulfilling orders."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"primary-method-webhooks","__idx":22},"children":["Primary method: Webhooks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Unity sends real-time webhook notifications to your backend when transactions complete:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"// Your webhook endpoint (configured in the Unity Portal)\napp.post('/webhooks/pxp', async (req, res) => {\n  const events = req.body;\n  \n  // Verify webhook authenticity using HMAC\n  if (!verifyWebhookSignature(req)) {\n    return res.status(401).json({ error: 'Unauthorised' });\n  }\n  \n  for (const event of events) {\n    if (event.eventCategory === 'Transaction') {\n      const txn = event.eventData;\n      \n      // Verify transaction details\n      if (txn.state === 'Authorised' || txn.state === 'Captured') {\n        // Check idempotency (prevent duplicate processing)\n        if (!await hasProcessedTransaction(txn.systemTransactionId)) {\n          // Verify amount and merchant transaction ID\n          const transactionAmount = txn.amounts?.transactionValue || txn.amount;\n          if (transactionAmount === expectedAmount &&\n              txn.merchantTransactionId === expectedMerchantTxnId) {\n            // Payment verified - fulfill order\n            await fulfillOrder(txn.merchantTransactionId);\n            await markTransactionProcessed(txn.systemTransactionId);\n          }\n        }\n      }\n    }\n  }\n  \n  // Always return success response\n  res.json({ state: 'Success' });\n});\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"optional-fallback-query-the-transactions-api","__idx":23},"children":["Optional fallback: Query the Transactions API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you need instant feedback before the webhook arrives, you can query PXP's Transactions API:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"// Your verification endpoint\napp.post('/api/verify-payment', async (req, res) => {\n  const { systemTransactionId, amount, merchantTransactionId } = req.body;\n  \n  // Check if webhook already processed this\n  const existingTxn = await getTransactionFromDB(systemTransactionId);\n  if (existingTxn) {\n    return res.json({ success: true, orderId: existingTxn.orderId });\n  }\n  \n  // Query PXP API as fallback (requires HMAC authentication)\n  const response = await fetch(\n    `https://api-services.dev.pxp.io/api/v1/transactions?systemTransactionId=${systemTransactionId}&fundingType=Card`,\n    {\n      headers: {\n        'X-Client-Id': process.env.PXP_CLIENT_ID,\n        'X-Request-Id': crypto.randomUUID(),\n        'Authorization': createAuthHeader('/api/v1/transactions', '', process.env.PXP_TOKEN_ID, process.env.PXP_TOKEN_VALUE),\n        'Content-Type': 'application/json'\n      }\n    }\n  );\n  \n  const transaction = await response.json();\n  \n  // Verify transaction details\n  const transactionAmount = transaction.amounts?.transactionValue || transaction.amount;\n  if (transaction.state === 'Authorised' &&\n      Math.abs(transactionAmount - amount) < 0.01 &&\n      transaction.merchantTransactionId === merchantTransactionId) {\n    // Payment verified - fulfill order\n    const order = await fulfillOrder(merchantTransactionId);\n    return res.json({ success: true, orderId: order.id });\n  }\n  \n  res.json({ success: false, error: 'Payment verification failed' });\n});\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"error-handling","__idx":24},"children":["Error handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All errors return a consistent structure with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ErrorCode"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["message"]}," properties. Common scenarios include card declined, insufficient funds, expired card, CVV failure, and 3DS authentication failure. Display the error message to users and allow them to retry or use a different payment method."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"complete-example","__idx":25},"children":["Complete example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's a complete example showing the new-card component integration in a React component:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"import { useEffect, useState } from 'react';\nimport { PxpCheckout, IntentType } from '@pxpio/web-components-sdk';\n\nexport default function CheckoutPage() {\n  const [isLoading, setIsLoading] = useState(false);\n  const [error, setError] = useState(null);\n\n  useEffect(() => {\n    initializeCheckout();\n  }, []);\n\n  async function initializeCheckout() {\n    try {\n      // 1. Get session from backend\n      const sessionData = await fetch('/api/sessions', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({\n          merchant: \"MERCHANT-1\",\n          site: \"SITE-1\",\n          sessionTimeout: 120,\n          merchantTransactionId: crypto.randomUUID(),\n          transactionMethod: {\n            intent: {\n              card: \"Authorisation\"\n            }\n          },\n          amounts: {\n            currencyCode: \"USD\",\n            transactionValue: 25\n          },\n          allowTransaction: true\n        })\n      }).then(r => r.json());\n\n      // 2. Initialise SDK\n      const pxpSdk = PxpCheckout.initialize({\n        environment: 'production',\n        session: sessionData,\n        ownerId: 'MERCHANT-1',\n        ownerType: 'MerchantGroup',\n        transactionData: {\n          currency: 'USD',\n          amount: 25,\n          entryType: 'Ecom',\n          intent: {\n            card: IntentType.Authorisation\n          },\n          merchantTransactionId: crypto.randomUUID(),\n          merchantTransactionDate: () => new Date().toISOString()\n        },\n        kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection\n        onGetShopper: () => Promise.resolve({ \n          id: 'shopper-123',\n          email: 'customer@example.com',\n          firstName: 'John',\n          lastName: 'Doe'\n        })\n      });\n\n      // 3. Create component\n      const newCard = pxpSdk.create('new-card', {\n        fields: {\n          cardNumber: {\n            required: true,\n            placeholder: '1234 5678 9012 3456',\n            onCardBrandDetected: (event) => {\n              console.log('Card brand detected:', event.detail.cardBrand.brand);\n            }\n          },\n          expiryDate: {\n            required: true,\n            placeholder: 'MM/YY'\n          },\n          cvc: {\n            required: true,\n            placeholder: '123'\n          },\n          holderName: {\n            required: true,\n            placeholder: 'John Doe'\n          }\n        },\n        submit: {\n          submitText: 'Pay $25.00',\n          styles: {\n            backgroundColor: '#4CAF50',\n            border: 'none',\n            padding: '15px',\n            borderRadius: '6px',\n            color: 'white',\n            fontSize: '16px',\n            fontWeight: 'bold',\n            cursor: 'pointer',\n            width: '100%'\n          },\n          onPostAuthorisation: async (data) => {\n            console.log('Payment successful:', data.systemTransactionId);\n            \n            // Verify on backend\n            try {\n              const verified = await fetch('/api/verify-payment', {\n                method: 'POST',\n                headers: { 'Content-Type': 'application/json' },\n                body: JSON.stringify({\n                  systemTransactionId: data.systemTransactionId,\n                  merchantTransactionId: data.merchantTransactionId\n                })\n              }).then(r => r.json());\n              \n              if (verified.success) {\n                globalThis.location.href = `/success?orderId=${verified.orderId}`;\n              } else {\n                setError('Payment verification failed. Please contact support.');\n                setIsLoading(false);\n              }\n            } catch (err) {\n              setError('Failed to verify payment. Please contact support.');\n              setIsLoading(false);\n            }\n          },\n          onSubmitError: (error) => {\n            console.error('Payment failed:', error);\n            setError('Payment failed. Please check your card details and try again.');\n            setIsLoading(false);\n          },\n          // 3DS callbacks (only include if backend set authentication = true)\n          onPreInitiateAuthentication: () => {\n            return {\n              providerId: 'pxpfinancial',\n              timeout: 12\n            };\n          },\n          onPostInitiateAuthentication: (data) => {\n            console.log('3DS authentication initiated:', data);\n          },\n          onPreAuthentication: async () => {\n            return {\n              merchantCountryNumericCode: '100',\n              merchantLegalName: 'TestMerchant_10',\n              challengeWindowSize: 1,\n              requestorChallengeIndicator: '02'\n            };\n          },\n          onPostAuthentication: (data) => {\n            console.log('3DS authentication completed:', data);\n          },\n          onPreAuthorisation: (data) => {\n            setIsLoading(true);\n            setError(null);\n            return {};\n          }\n        }\n      });\n\n      // 4. Mount component\n      newCard.mount('new-card-container');\n      \n    } catch (err) {\n      console.error('Failed to initialise checkout:', err);\n      setError('Failed to load payment form. Please refresh the page.');\n    }\n  }\n\n  return (\n    <div className=\"checkout-page\">\n      <h1>Complete Your Purchase</h1>\n      \n      <div className=\"order-summary\">\n        <h2>Order Summary</h2>\n        <p>Product: Premium Subscription</p>\n        <p>Amount: $25.00 USD</p>\n      </div>\n      \n      {error && (\n        <div className=\"error-message\" role=\"alert\">\n          {error}\n        </div>\n      )}\n      \n      {isLoading && (\n        <div className=\"loading-overlay\">\n          Processing payment...\n        </div>\n      )}\n      \n      <div id=\"new-card-container\"></div>\n      \n      <p className=\"security-notice\">\n        Your payment information is securely processed by PXP. \n        We never store your full card details.\n      </p>\n    </div>\n  );\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"whats-next","__idx":26},"children":["What's next?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Now that you've integrated card components, here are some recommended next steps:"]},{"$$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/web/card/about-customisation"},"children":["Customisation"]}]},": Learn how to customise the appearance and behavior of components."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/web/card/events"},"children":["Events"]}]},": Explore all available callbacks and event handling."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/web/card/3ds"},"children":["3D Secure"]}]},": Enable 3DS for enhanced security and liability shift."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/get-started/about-webhooks"},"children":["Configure webhooks"]}]},": Set up server-side webhook handling for reliable payment verification."]}]}]},"headings":[{"value":"Implementation","id":"implementation","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Before you start","id":"before-you-start","depth":2},{"value":"Step 1: Install the Web SDK library","id":"step-1-install-the-web-sdk-library","depth":2},{"value":"Step 2: Get your API credentials","id":"step-2-get-your-api-credentials","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 on your frontend","id":"step-4-initialise-the-sdk-on-your-frontend","depth":2},{"value":"Configuration parameters","id":"configuration-parameters","depth":3},{"value":"Step 5: Create and configure a component","id":"step-5-create-and-configure-a-component","depth":2},{"value":"Step 6: Mount the component to your page","id":"step-6-mount-the-component-to-your-page","depth":2},{"value":"Step 7: Handle callbacks","id":"step-7-handle-callbacks","depth":2},{"value":"onGetShopper callback","id":"ongetshopper-callback","depth":3},{"value":"onPostAuthorisation callback","id":"onpostauthorisation-callback","depth":3},{"value":"onSubmitError callback","id":"onsubmiterror-callback","depth":3},{"value":"3D Secure callbacks (required if using 3DS)","id":"3d-secure-callbacks-required-if-using-3ds","depth":3},{"value":"onPreAuthorisation callback","id":"onpreauthorisation-callback","depth":3},{"value":"Step 8: Backend verification (CRITICAL)","id":"step-8-backend-verification-critical","depth":2},{"value":"Primary method: Webhooks","id":"primary-method-webhooks","depth":3},{"value":"Optional fallback: Query the Transactions API","id":"optional-fallback-query-the-transactions-api","depth":3},{"value":"Error handling","id":"error-handling","depth":2},{"value":"Complete example","id":"complete-example","depth":2},{"value":"What's next?","id":"whats-next","depth":2}],"frontmatter":{"seo":{"title":"Implementation"}},"lastModified":"2026-05-19T09:47:25.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/web/card/implementation","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}