{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","admonition","endpoint","br","details","required","code-group"]},"type":"markdown"},"seo":{"title":"Recurring payments","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":"recurring-payments","__idx":0},"children":["Recurring payments"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set up recurring payments using card components."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Card components support two types of recurring payments:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant-initiated transactions (MITs):"]}," For subscription-based payments where the customer signs up and pays initially, and you then automatically charge them at a specified interval using your own scheduling system."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Card-on-file transactions with shopper consent:"]}," For storing payment methods with customer consent for future use, allowing faster checkout for returning customers."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["PXP doesn't provide an automatic payment scheduler. You must implement your own scheduling system to initiate subsequent recurring charges via the Transactions API."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"merchant-initiated-recurring-payments","__idx":2},"children":["Merchant-initiated recurring payments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Merchant-initiated recurring payments require two steps: an initial setup transaction using the SDK, followed by subsequent charges initiated from your backend using the Transactions API."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-set-up-the-initial-recurring-payment","__idx":3},"children":["Step 1: Set up the initial recurring payment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the card components to collect the customer's card details and set up the recurring payment. Include the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recurring"]}," object in your transaction data to specify the payment frequency."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you include the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recurring"]}," object in your transaction data, the SDK automatically sets the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processingModel"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantInitiatedInitialRecurring"]}," when creating the transaction request."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"// Configure initial subscription transaction\nconst transactionData = {\n  amount: 9.99,\n  currency: 'USD',\n  entryType: 'Ecom',\n  intent: {\n    card: 'Authorisation'\n  },\n  merchantTransactionId: 'sub-setup-123',\n  merchantTransactionDate: () => new Date().toISOString(),\n  recurring: {\n    frequencyInDays: 30,\n    frequencyExpiration: '2025-12-31'\n  }\n};\n\n// Create SDK configuration\nconst sdkConfig = {\n  environment: 'test',\n  session: {\n    sessionId: 'your-session-id'\n  },\n  transactionData,\n  ownerId: 'your-owner-id'\n  // ... other SDK settings\n};\n\n// Create card components\nconst cardNumberComponent = new CardNumberComponent(sdkConfig);\nconst cardExpiryComponent = new CardExpiryDateComponent(sdkConfig);\nconst cardCvcComponent = new CardCvcComponent(sdkConfig);\n\nconst cardSubmitComponent = new CardSubmitComponent(sdkConfig, {\n  cardNumberComponent,\n  cardExpiryDateComponent: cardExpiryComponent,\n  cardCvcComponent,\n  useCardOnFile: false,\n  submitText: 'Start subscription',\n  onPostAuthorisation: async (data) => {\n    console.log('Subscription setup completed');\n    \n    // Get full result from backend\n    const result = await getAuthorisationResultFromGateway(\n      data.merchantTransactionId, \n      data.systemTransactionId\n    );\n    \n    if (result.state === 'Authorised' || result.state === 'Captured') {\n      console.log('Subscription started!');\n      \n      // Store the gatewayTokenId and subscription details in your system\n      // You'll need these for subsequent charges\n      await saveSubscription({\n        gatewayTokenId: result.fundingData.gatewayTokenId,\n        customerId: 'customer-123',\n        amount: 9.99,\n        currency: 'USD',\n        frequency: 30,\n        nextChargeDate: calculateNextChargeDate(30)\n      });\n    }\n  }\n});\n\n// Mount components\ncardNumberComponent.mount('card-number');\ncardExpiryComponent.mount('card-expiry');\ncardCvcComponent.mount('card-cvc');\ncardSubmitComponent.mount('submit-button');\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-charge-subsequent-recurring-payments","__idx":4},"children":["Step 2: Charge subsequent recurring payments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For subsequent recurring charges, you must initiate transactions from your backend using the Transactions API. PXP doesn't automatically charge customers based on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["frequencyInDays"]},", so you need to implement your own scheduler to trigger these charges."]},{"$$mdtype":"Tag","name":"Endpoint","attributes":{"method":"POST"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["/v1/transactions"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the following request to charge a customer for a subsequent recurring payment. Replace the full card details with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]}," you received from the initial transaction."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"merchant\": \"MERCHANT-1\",\n  \"site\": \"SITE-1\",\n  \"merchantTransactionId\": \"sub-charge-456\",\n  \"merchantTransactionDate\": \"2025-02-27T08:51:02.826Z\",\n  \"transactionMethod\": {\n    \"intent\": \"Purchase\",\n    \"entryType\": \"Ecom\",\n    \"fundingType\": \"Card\"\n  },\n  \"fundingData\": {\n    \"card\": {\n      \"gatewayTokenId\": \"5fbd77ce-02c1-40ed-94bc-1016660b7512\"\n    }\n  },\n  \"amounts\": {\n    \"transaction\": 9.99,\n    \"currencyCode\": \"USD\"\n  },\n  \"recurring\": {\n    \"processingModel\": \"MerchantInitiatedSubsequentRecurring\"\n  }\n}\n","lang":"json"},"children":[]},{"$$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."]}]},{"$$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."]}]},{"$$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 for this transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantTransactionDate"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["date-time"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The date and time when the transaction happened, in ISO 8601 format."]}]},{"$$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."]}]},{"$$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":["string (enum)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The payment intent. For recurring charges, use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Purchase"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorisation"]},".",{"$$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":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionMethod.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. For e-commerce transactions, this is always ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Ecom"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionMethod.fundingType"]},{"$$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 funding type. For card transactions, this is always ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Card"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData"]},{"$$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 payment method used for the transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData.card"]},{"$$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 card."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fundingData.card.gatewayTokenId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string (UUID)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The gateway token ID from the initial transaction. This replaces the need to provide full card details."]}]},{"$$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.transaction"]},{"$$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":["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 in ISO 4217 format."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recurring"]},{"$$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 recurring payment."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recurring.processingModel"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["string (enum)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The processing model for the recurring payment. Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantInitiatedSubsequentRecurring"]}," for standard subscription charges.",{"$$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":["MerchantInitiatedSubsequentRecurring"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantInitiatedReAuthorisation"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantInitiatedResubmission"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantInitiatedDelayedCharge"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MerchantInitiatedNoShow"]}]}]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"response-example","__idx":5},"children":["Response example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If your request is successful, you'll receive a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]}," response with the transaction state. You'll also receive a webhook notification."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"state\": \"Captured\",\n  \"stateData\": {},\n  \"approvalCode\": \"210693\",\n  \"merchantTransactionId\": \"sub-charge-456\",\n  \"systemTransactionId\": \"635b1b51-4a27-4d23-8c9f-8150ff7eb9dd\",\n  \"merchantTransactionDate\": \"2025-02-27T08:51:02.826Z\",\n  \"fundingData\": {\n    \"cardScheme\": \"Visa\",\n    \"maskedPrimaryAccountNumber\": \"411111******1111\",\n    \"expiryMonth\": \"09\",\n    \"expiryYear\": \"2025\",\n    \"gatewayTokenId\": \"5fbd77ce-02c1-40ed-94bc-1016660b7512\",\n    \"providerResponse\": {\n      \"provider\": \"pxpfinancial\",\n      \"code\": \"00\",\n      \"paymentAccountReference\": \"637607302178175469\",\n      \"authorisedAmount\": 9.99\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/transactions/initiate-transactions"},"children":["Learn more about initiating transactions via API"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"card-on-file-recurring-payments","__idx":6},"children":["Card-on-file recurring payments"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-set-up-the-initial-transaction","__idx":7},"children":["Step 1: Set up the initial transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To save a card, you'll first need to ask for the customer's consent during the initial transaction. If the customer ticks the checkbox, their card details will be saved as a token for future reuse."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"const transactionData = {\n  amount: 99.99,\n  currency: 'USD',\n  entryType: 'Ecom',\n  intent: {\n    card: 'Authorisation'\n  },\n  merchantTransactionId: 'order-12345',\n  merchantTransactionDate: () => new Date().toISOString()\n};\n\nconst sdkConfig = {\n  transactionData,\n  // ... other SDK configuration\n};\n\n// Create the card consent component\nconst cardConsentComponent = new CardConsentComponent(sdkConfig, {\n  label: 'Save this card for faster checkout in the future',\n  class: 'consent-checkbox'\n});\n\n// Create the card input components\nconst cardNumberComponent = new CardNumberComponent(sdkConfig);\nconst cardExpiryComponent = new CardExpiryDateComponent(sdkConfig);\nconst cardCvcComponent = new CardCvcComponent(sdkConfig);\n\n// Create the card submit component\nconst cardSubmitComponent = new CardSubmitComponent(sdkConfig, {\n  cardNumberComponent,\n  cardExpiryDateComponent: cardExpiryComponent,\n  cardCvcComponent,\n  cardConsentComponent, // Include consent component\n  useCardOnFile: false, // Use a new card, not a saved card\n  submitText: 'Pay & save card',\n  onPostTokenisation: async (data) => {\n    console.log('Card tokenised. Gateway Token ID:', data.gatewayTokenId);\n    \n    // Get full token details from backend if needed for validation\n    const tokenDetails = await getTokenDetailsFromBackend(data.gatewayTokenId);\n    console.log('Card saved for future use');\n    \n    // Store the token reference in your system\n  },\n  onPostAuthorisation: async (data) => {\n    console.log('Payment completed');\n    \n    // Get full result from backend\n    const result = await getAuthorisationResultFromGateway(data.merchantTransactionId, data.systemTransactionId);\n    \n    if (result.state === 'Authorised' || result.state === 'Captured') {\n      console.log('Payment successful, card saved for future use');\n    }\n  }\n});\n\n// Mount components\ncardNumberComponent.mount('card-number');\ncardExpiryComponent.mount('card-expiry');\ncardCvcComponent.mount('card-cvc');\ncardConsentComponent.mount('card-consent');\ncardSubmitComponent.mount('submit-button');\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-set-up-subsequent-transactions","__idx":8},"children":["Step 2: Set up subsequent transactions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For subsequent transactions with saved cards, you can choose from:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["A traditional card selection:"]}," This is best for customers with multiple saved cards and provides"," ","full card management (edit, delete, update) but requires more interaction from the customer. It uses the card-on-file component."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["A streamlined click-once checkout:"]}," This is ideal for customers with one primary payment method and offers a faster checkout experience, but less flexibility. It uses the standalone click-once component."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["A hybrid approach:"]}," This combines the two components. It defaults to displaying a primary card, but allows customers to choose a different one if they want to."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When using card-on-file or click-once components, the SDK automatically sets the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processingModel"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CardOnFileShopperInitiated"]}," for subsequent transactions."]}]},{"$$mdtype":"Tag","name":"CodeGroup","attributes":{"mode":"tabs"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"Card-on-file","header":{"title":"Card-on-file","controls":{"copy":{}}},"source":"const cardOnFileComponent = new CardOnFileComponent(sdkConfig, {\n  limitTokens: 10,\n  orderBy: {\n    lastUsageDate: { direction: 'desc', priority: 1 }\n  },\n  deleteCardButtonAriaLabel: 'Delete this card',\n  editCardInformationAriaLabel: 'Edit card details'\n});\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"Click-once standalone","header":{"title":"Click-once standalone","controls":{"copy":{}}},"source":"const clickOnceComponent = new ClickOnceStandaloneComponent(sdkConfig, {\n  limitTokens: 1,\n  isCvcRequired: false, \n  submitText: 'Complete purchase',\n  disableCardSelection: true\n});\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"Hybrid","header":{"title":"Hybrid","controls":{"copy":{}}},"source":"// Primary checkout with click-once\nconst quickCheckout = new ClickOnceStandaloneComponent(sdkConfig, {\n  limitTokens: 1,\n  submitText: 'Pay with Primary Card',\n  class: 'primary-checkout'\n});\n\n// Alternative with full card selection\nconst alternativeCheckout = new CardOnFileComponent(sdkConfig, {\n  limitTokens: 5,\n  class: 'alternative-checkout hidden' // Initially hidden\n});\n\n// Toggle between interfaces\nconst showAlternativeButton = document.createElement('button');\nshowAlternativeButton.textContent = 'Use different card';\nshowAlternativeButton.onclick = () => {\n  document.querySelector('.primary-checkout').classList.add('hidden');\n  document.querySelector('.alternative-checkout').classList.remove('hidden');\n};\n","lang":"typescript"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-the-api-for-backend-initiated-card-on-file-transactions","__idx":9},"children":["Using the API for backend-initiated card-on-file transactions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["While the components above handle shopper-initiated transactions (where the customer is present and actively making a payment), you can also use the Transactions API to charge a saved card from your backend without the customer being present."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is useful for scenarios like:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Auto-renewing a service when the customer returns to your platform."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Charging for usage-based billing at the end of a billing period."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Processing payments for bookings or reservations."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To charge a saved card via API, use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CardOnFileShopperInitiated"]}," processing model with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"merchant\": \"MERCHANT-1\",\n  \"site\": \"SITE-1\",\n  \"merchantTransactionId\": \"charge-001\",\n  \"merchantTransactionDate\": \"2025-02-27T08:51:02.826Z\",\n  \"transactionMethod\": {\n    \"intent\": \"Purchase\",\n    \"entryType\": \"Ecom\",\n    \"fundingType\": \"Card\"\n  },\n  \"fundingData\": {\n    \"card\": {\n      \"gatewayTokenId\": \"5fbd77ce-02c1-40ed-94bc-1016660b7512\"\n    }\n  },\n  \"amounts\": {\n    \"transaction\": 49.99,\n    \"currencyCode\": \"USD\"\n  },\n  \"recurring\": {\n    \"processingModel\": \"CardOnFileShopperInitiated\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/transactions/e-commerce/recurring-payments#set-up-a-card-on-file-recurring-payment"},"children":["Learn more about card-on-file payments via API"]},"."]}]},"headings":[{"value":"Recurring payments","id":"recurring-payments","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Merchant-initiated recurring payments","id":"merchant-initiated-recurring-payments","depth":2},{"value":"Step 1: Set up the initial recurring payment","id":"step-1-set-up-the-initial-recurring-payment","depth":3},{"value":"Step 2: Charge subsequent recurring payments","id":"step-2-charge-subsequent-recurring-payments","depth":3},{"value":"Response example","id":"response-example","depth":4},{"value":"Card-on-file recurring payments","id":"card-on-file-recurring-payments","depth":2},{"value":"Step 1: Set up the initial transaction","id":"step-1-set-up-the-initial-transaction","depth":3},{"value":"Step 2: Set up subsequent transactions","id":"step-2-set-up-subsequent-transactions","depth":3},{"value":"Using the API for backend-initiated card-on-file transactions","id":"using-the-api-for-backend-initiated-card-on-file-transactions","depth":3}],"frontmatter":{"seo":{"title":"Recurring payments"}},"lastModified":"2026-04-02T13:24:43.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/web/card/recurring-payments","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}