{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","admonition","endpoint","br","details"]},"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":["Learn how to implement and manage recurring payments with PXP Android Components."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Recurring payments allow merchants to automatically charge customers on a regular basis for subscriptions, memberships, or ongoing services. The PXP Android SDK supports recurring payment implementation through card tokenisation and proper transaction configuration."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By implementing recurring payments, you can:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Provide a seamless subscription experience for your customers."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Reduce customer churn through automated billing."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure compliance with regional payment regulations."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Improve cash flow predictability for your business."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-recurring-payments-work","__idx":2},"children":["How recurring payments work"]},{"$$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 using the PXP Transactions API."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"card-tokenisation-approach","__idx":3},"children":["Card tokenisation approach"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Android SDK implements recurring payments through a card tokenisation approach:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Initial payment setup:"]}," The customer provides their card details and consents to recurring billing through the SDK."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Card tokenisation:"]}," Card details are securely tokenised and a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]}," is returned."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Subsequent payments:"]}," Use the stored ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]}," in backend API calls to charge customers without requiring their interaction."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"recurring-transaction-data","__idx":4},"children":["Recurring transaction data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Configure recurring payment information using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RecurringData"]}," class in your transaction configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"data class RecurringData(\n    val frequencyInDays: Int? = null,\n    val frequencyExpiration: String? = null\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"setting-up-recurring-payments","__idx":5},"children":["Setting up recurring payments"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"initial-subscription-setup","__idx":6},"children":["Initial subscription setup"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Configure your SDK with recurring transaction data to establish the subscription:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val transactionData = TransactionData(\n    amount = 9.99,\n    currency = \"USD\",\n    entryType = EntryType.Ecom,\n    intent = TransactionIntentData(\n        card = IntentType.Authorisation\n    ),\n    merchant = \"Your Merchant Name\",\n    merchantTransactionId = \"subscription-setup-${UUID.randomUUID()}\",\n    merchantTransactionDate = { Instant.now().toString() },\n    recurring = RecurringData(\n        frequencyInDays = 30, // Monthly billing\n        frequencyExpiration = LocalDateTime.now().plusYears(1).toString()\n    ),\n    shopper = Shopper(\n        email = \"customer@example.com\",\n        firstName = \"John\",\n        lastName = \"Doe\"\n    )\n)\n\n\nval sdkConfig = PxpSdkConfig(\n    environment = Environment.TEST,\n    session = sessionConfig,\n    transactionData = transactionData,\n    clientId = \"your-client-id\",\n    ownerType = \"MerchantGroup\",\n    ownerId = \"UnityGroup\"\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"card-on-file-for-recurring-payments","__idx":7},"children":["Card-on-file for recurring payments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the card-on-file component to manage stored payment methods for recurring billing:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val cardOnFileConfig = CardOnFileComponentConfig().apply {\n    // Configure for recurring payment selection\n    onTokenSelected = { token ->\n        Log.d(\"Recurring\", \"Selected token for recurring payment: ${token.id}\")\n        // Store token reference for future billing cycles\n        storeRecurringPaymentToken(token.id)\n    }\n    \n    onTokensLoaded = { tokens ->\n        Log.d(\"Recurring\", \"Available payment methods: ${tokens.size}\")\n        // Display available payment methods\n        displayRecurringPaymentOptions(tokens)\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When using saved cards from the card-on-file component, the SDK automatically sets the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processingModel"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CardOnFileShopperInitiated"]}," for shopper-present transactions. For backend-initiated charges with saved cards, use the Transactions API with the stored ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"new-card-setup-for-recurring","__idx":8},"children":["New card setup for recurring"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When customers add a new payment method for recurring billing:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val newCardConfig = NewCardComponentConfig().apply {\n    // Configure card consent for recurring payments\n    fields.cardConsent = CardConsentConfig(\n        label = \"I authorise recurring charges to this payment method\",\n        isRequired = true,\n        onToggleChanged = { isConsented ->\n            if (isConsented) {\n                Log.d(\"Recurring\", \"Customer consented to recurring billing\")\n                enableRecurringPaymentSetup()\n            }\n        }\n    )\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"managing-recurring-payments","__idx":9},"children":["Managing recurring payments"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"charging-subsequent-recurring-payments","__idx":10},"children":["Charging subsequent recurring payments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After the initial setup, you initiate subsequent recurring charges from your backend using the PXP Transactions API with the stored ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"Endpoint","attributes":{"method":"POST"},"children":["/v1/transactions"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example API request:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"merchant\": \"MERCHANT-1\",\n  \"site\": \"SITE-1\",\n  \"merchantTransactionId\": \"recurring-charge-789\",\n  \"merchantTransactionDate\": \"2025-03-15T10:30:00.000Z\",\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":{"width":"30%","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":["fundingData.card.gatewayTokenId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The token ID obtained from the initial payment setup (returned in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostTokenisation"]}," callback)."]}]},{"$$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"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Must be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"MerchantInitiatedSubsequentRecurring\""]}," for recurring charges after the initial setup."]}]},{"$$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"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Purchase\""]}," for immediate charge or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Authorisation\""]}," for pre-authorisation."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example API response:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"state\": \"Captured\",\n  \"provider\": {\n    \"code\": \"00\",\n    \"message\": \"Successful\",\n    \"transactionId\": \"TXN-987654321\"\n  },\n  \"fundingData\": {\n    \"card\": {\n      \"cardScheme\": \"VISA\",\n      \"expiryMonth\": \"12\",\n      \"expiryYear\": \"2026\",\n      \"lastFour\": \"4242\",\n      \"gatewayTokenId\": \"5fbd77ce-02c1-40ed-94bc-1016660b7512\"\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gatewayTokenId"]}," is stored securely by PXP and can be reused for future recurring charges. Implement your own scheduling system to call this API at the appropriate billing intervals."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For more details about the Transactions API, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/transactions/initiate-transactions"},"children":["Initiate transactions"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"card-submit-for-recurring-transactions","__idx":11},"children":["Card submit for recurring transactions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Configure the card submit component to handle recurring payment processing:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val cardSubmitConfig = CardSubmitComponentConfig().apply {\n    // Set component references\n    newCardComponent = newCardComponent\n    \n    // Configure recurring payment callbacks\n    onPreTokenisation = {\n        Log.d(\"Recurring\", \"Starting tokenisation for recurring payment\")\n        true // Proceed with tokenisation\n    }\n    \n    onPostTokenisation = { result ->\n        when (result) {\n            is CardTokenisationResult.Success -> {\n                Log.d(\"Recurring\", \"Token created for recurring payment: ${result.gatewayTokenId}\")\n                // Store token for future recurring charges\n                saveRecurringPaymentToken(result.gatewayTokenId)\n            }\n            is CardTokenisationResult.Failure -> {\n                Log.e(\"Recurring\", \"Tokenisation failed: ${result.errorReason}\")\n                handleRecurringSetupFailure(result.errorReason)\n            }\n        }\n    }\n    \n    onPostAuthorisation = { result ->\n        when (result) {\n            is AuthorizedSubmitResult -> {\n                Log.d(\"Recurring\", \"Recurring payment setup successful\")\n                Log.d(\"Recurring\", \"Provider code: ${result.providerResponse.code}\")\n                confirmRecurringPaymentSetup(result)\n            }\n            is CapturedSubmitResult -> {\n                Log.d(\"Recurring\", \"Recurring payment captured successfully\")\n                confirmRecurringPaymentSetup(result)\n            }\n            is RefusedSubmitResult -> {\n                Log.e(\"Recurring\", \"Recurring payment refused: ${result.stateData.message}\")\n                handleRecurringSetupFailure(result.stateData.message)\n            }\n            is FailedSubmitResult -> {\n                Log.e(\"Recurring\", \"Recurring payment setup failed: ${result.errorReason}\")\n                handleRecurringSetupFailure(result.errorReason)\n            }\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"frequency-configuration","__idx":12},"children":["Frequency configuration"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"common-billing-frequencies","__idx":13},"children":["Common billing frequencies"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Configure recurring payment frequency using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["frequencyInDays"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"// Different billing cycles\nval dailyBilling = RecurringData(frequencyInDays = 1)\nval weeklyBilling = RecurringData(frequencyInDays = 7)\nval monthlyBilling = RecurringData(frequencyInDays = 30)\nval quarterlyBilling = RecurringData(frequencyInDays = 90)\nval yearlyBilling = RecurringData(frequencyInDays = 365)\n\n// Custom frequencies\nval biWeeklyBilling = RecurringData(frequencyInDays = 14)\nval semiMonthlyBilling = RecurringData(frequencyInDays = 15)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"expiration-handling","__idx":14},"children":["Expiration handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set expiration dates for recurring billing agreements:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val recurringData = RecurringData(\n    frequencyInDays = 30,\n    frequencyExpiration = LocalDateTime.now()\n        .plusYears(2) // Subscription expires in 2 years\n        .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"3ds-and-recurring-payments","__idx":15},"children":["3DS and recurring payments"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"initial-setup-with-3ds","__idx":16},"children":["Initial setup with 3DS"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The first payment in a recurring series typically requires 3DS authentication:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val initialRecurringConfig = CardSubmitComponentConfig().apply {\n    // Enable 3DS for initial setup\n    onPreInitiateAuthentication = {\n        Log.d(\"Recurring\", \"Starting 3DS for recurring payment setup\")\n        PreInitiateIntegratedAuthenticationData(\n            threeDSRequestorAuthenticationIndicator = \"02\" // Recurring transaction\n        )\n    }\n    \n    onPostAuthentication = { result, authData ->\n        Log.d(\"Recurring\", \"3DS completed for recurring setup\")\n        // Process successful authentication for recurring setup\n        processRecurringAuthentication(result, authData)\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"subsequent-payments-mit","__idx":17},"children":["Subsequent payments (MIT)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Merchant-initiated transactions (MIT) for recurring payments are processed via the backend API and typically bypass 3DS authentication. The SDK is only used for the initial setup where the customer consents and provides their payment details."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recurring.processingModel"]}," field in the API request indicates the transaction type:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"MerchantInitiatedInitialRecurring\""]},": First payment in a recurring series (set automatically by SDK)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"MerchantInitiatedSubsequentRecurring\""]},": Subsequent recurring charges (set in your backend API calls)"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"error-handling","__idx":18},"children":["Error handling"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"common-recurring-payment-scenarios","__idx":19},"children":["Common recurring payment scenarios"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Handle various error conditions in recurring payment flows:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"fun handleRecurringPaymentError(error: BaseSdkException) {\n    when (error.errorCode) {\n        \"CARD_EXPIRED\" -> {\n            Log.w(\"Recurring\", \"Card expired, request updated payment method\")\n            requestPaymentMethodUpdate()\n        }\n        \"INSUFFICIENT_FUNDS\" -> {\n            Log.w(\"Recurring\", \"Payment failed due to insufficient funds\")\n            scheduleRetryAttempt()\n        }\n        \"CARD_DECLINED\" -> {\n            Log.w(\"Recurring\", \"Card declined, notify customer\")\n            notifyCustomerOfDeclinedPayment()\n        }\n        else -> {\n            Log.e(\"Recurring\", \"Unexpected error in recurring payment: ${error.message}\")\n            handleGeneralRecurringError(error)\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"retry-logic","__idx":20},"children":["Retry logic"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement retry logic for failed recurring payments:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class RecurringPaymentManager {\n    private val maxRetryAttempts = 3\n    private var retryCount = 0\n    \n    fun processRecurringPayment(tokenId: String, amount: Double) {\n        if (retryCount >= maxRetryAttempts) {\n            handleMaxRetriesExceeded()\n            return\n        }\n        \n        // Configure transaction for retry\n        val retryTransactionData = TransactionData(\n            amount = amount,\n            currency = CurrencyType.USD,\n            merchantTransactionId = \"retry-${retryCount}-${UUID.randomUUID()}\",\n            merchantTransactionDate = { Instant.now().toString() },\n            recurring = RecurringData(\n                frequencyInDays = 30,\n                frequencyExpiration = getSubscriptionExpiration()\n            )\n        )\n        \n        // Process with stored token\n        processPaymentWithToken(tokenId, retryTransactionData)\n    }\n    \n    private fun handlePaymentFailure(error: BaseSdkException) {\n        retryCount++\n        \n        if (shouldRetry(error.errorCode)) {\n            scheduleRetry()\n        } else {\n            handlePermanentFailure(error)\n        }\n    }\n}\n","lang":"kotlin"},"children":[]}]},"headings":[{"value":"Recurring payments","id":"recurring-payments","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"How recurring payments work","id":"how-recurring-payments-work","depth":2},{"value":"Card tokenisation approach","id":"card-tokenisation-approach","depth":3},{"value":"Recurring transaction data","id":"recurring-transaction-data","depth":3},{"value":"Setting up recurring payments","id":"setting-up-recurring-payments","depth":2},{"value":"Initial subscription setup","id":"initial-subscription-setup","depth":3},{"value":"Card-on-file for recurring payments","id":"card-on-file-for-recurring-payments","depth":3},{"value":"New card setup for recurring","id":"new-card-setup-for-recurring","depth":3},{"value":"Managing recurring payments","id":"managing-recurring-payments","depth":2},{"value":"Charging subsequent recurring payments","id":"charging-subsequent-recurring-payments","depth":3},{"value":"Card submit for recurring transactions","id":"card-submit-for-recurring-transactions","depth":3},{"value":"Frequency configuration","id":"frequency-configuration","depth":2},{"value":"Common billing frequencies","id":"common-billing-frequencies","depth":3},{"value":"Expiration handling","id":"expiration-handling","depth":3},{"value":"3DS and recurring payments","id":"3ds-and-recurring-payments","depth":2},{"value":"Initial setup with 3DS","id":"initial-setup-with-3ds","depth":3},{"value":"Subsequent payments (MIT)","id":"subsequent-payments-mit","depth":3},{"value":"Error handling","id":"error-handling","depth":2},{"value":"Common recurring payment scenarios","id":"common-recurring-payment-scenarios","depth":3},{"value":"Retry logic","id":"retry-logic","depth":3}],"frontmatter":{"seo":{"title":"Recurring payments"}},"lastModified":"2026-04-02T13:24:43.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/android/card/recurring-payments","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}