> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.mangopay.com/guides/payment-methods/card/recurring/how-to/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.mangopay.com/_mcp/server. # How to process a recurring card payment This how-to guide will show you how to successfully process recurring payments with a registered card. > **Info** > > **Prerequisites** > > * A `ClientId` and an API key – if you don't have these, [contact Sales](https://mangopay.com/contact) to get access to the [Mangopay Dashboard](https://hub.mangopay.com/) > * A User object created for your end user, and their associated Wallet > * A [registered card](/guides/payment-methods/card) (Visa, Mastercard, CB, or AMEX), which is `VALID` or registered less than 24 hours ago, to make the payments Setting up a recurring card payment is necessary when the platform repeatedly charges the end user at regular intervals, such as in subscription models or payments in installments. A recurring card payment has two phases: * Customer-initiated transaction (CIT) - An initial transaction in the presence of the cardholder, for which SCA is required. * Merchant-initiated transactions (MIT) - Subsequent transactions made in the absence of the cardholder, initiated by the platform (and not subject to SCA unless required by the issuer ) [Learn more about recurring card payments](/guides/payment-methods/card/recurring) ## 1. Create the Recurring PayIn Registration The Recurring PayIn Registration object will define key information about the recurring payments such as: * The start and end date, as well as the frequency * Whether the amount is the same for each payment * Whether you want to offer zero-amount payments to your end user at the start of the recurrence (for example, during trial subscription offers) For this guide, we'll define a fixed monthly amount but not provide an end date. > [**POST** /v2.01/\{ClientId}/recurringpayinregistrations](/api-reference/recurring-payin-registrations/create-recurring-payin-registration) In the response, you will need the `Id` of the Recurring PayIn Registration for the next steps. #### API response ```json { "Id": "recpayinreg_m_01JJP2KS2A47A0P7S7CEBQPHT9", "Status": "CREATED", "ResultCode": null, "ResultMessage": null, "CurrentState": { "PayinsLinked": 0, "CumulatedDebitedAmount": { "Currency": "EUR", "Amount": 0 }, "CumulatedFeesAmount": { "Currency": "EUR", "Amount": 0 }, "LastPayinId": null }, "RecurringType": "CUSTOM", "TotalAmount": null, "CycleNumber": null, "AuthorId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "CardId": "card_m_UsklnOoXBWyyqhsN", "CreditedUserId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "CreditedWalletId": "wlt_m_01JJ70WZ9JRAZ9GE0DA36Q84NQ", "Billing": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "Shipping": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "EndDate": null, "Frequency": "Monthly", "FixedNextAmount": true, "FractionedPayment": false, "FreeCycles": 0, "FirstTransactionDebitedFunds": { "Currency": "EUR", "Amount": 10000 }, "FirstTransactionFees": { "Currency": "EUR", "Amount": 500 }, "NextTransactionDebitedFunds": null, "NextTransactionFees": null, "Migration": false, "PaymentType": "CARD_DIRECT" } ``` ## 2. Process the first recurring payment (CIT) ### Make the request Request the first payment, linking it to the registration object by using the `Id` returned in the previous step as the `RecurringPayinRegistrationId`. In our example, the first transaction amounts have been defined at the registration level. Because of this, we don’t need to define the `DebitedFunds` or `Fees` at the pay-in level. > [**POST** /v2.01/\{ClientId}/payins/recurring/card/direct](/api-reference/recurring-card-payins/create-recurring-card-payin) \ #### API response ```json { "Id": "payin_m_01JJP2PDQWD7S2W42RR6S21VZE", "Tag": "Created using Mangopay API Postman Collection", "CreationDate": 1738055301, "AuthorId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "CreditedUserId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "DebitedFunds": { "Currency": "EUR", "Amount": 10000 }, "CreditedFunds": { "Currency": "EUR", "Amount": 9500 }, "Fees": { "Currency": "EUR", "Amount": 500 }, "Status": "CREATED", "ResultCode": null, "ResultMessage": null, "ExecutionDate": null, "Type": "PAYIN", "Nature": "REGULAR", "CreditedWalletId": "wlt_m_01JJ70WZ9JRAZ9GE0DA36Q84NQ", "DebitedWalletId": null, "PaymentType": "CARD", "ExecutionType": "DIRECT", "SecureMode": null, "CardId": "card_m_UsklnOoXBWyyqhsN", "SecureModeReturnURL": "https://example.com/?transactionId=payin_m_01JJP2PDQWD7S2W42RR6S21VZE", "SecureModeRedirectURL": "https://api.sandbox.whenthen.co/payment-gateway/whenthen/threeDS/54b0c206-0a67-43d4-ace6-14a25697cf85/challenge?id=d7a9a1dd-80aa-4252-b2b4-221e1898d67f&url=aHR0cHM6Ly9hcGkuc2FuZGJveC53aGVudGhlbi5jby9wYXltZW50cy8zRFNlY3VyZS81NGIwYzIwNi0wYTY3LTQzZDQtYWNlNi0xNGEyNTY5N2NmODUvYzA1YTBhYzktNjBmZC00NDQyLWEzYzAtYjlmOTVlN2I1ODk5&amount=MzMzNDE¤cy=RVVS", "SecureModeNeeded": true, "Culture": "EN", "SecurityInfo": { "AVSResult": "NO_CHECK" }, "StatementDescriptor": "Example123", "BrowserInfo": { "AcceptHeader": "text/html, application/xhtml+xml, application/xml;q=0.9, /;q=0.8", "JavaEnabled": true, "Language": "FR-FR", "ColorDepth": 4, "ScreenHeight": 1800, "ScreenWidth": 400, "TimeZoneOffset": 60, "UserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148", "JavascriptEnabled": true }, "IpAddress": "3a55:f45c:d44e:ff6a:c63b:f2ec:3a31:eb3e", "Billing": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "Shipping": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "Requested3DSVersion": null, "Applied3DSVersion": "V2_1", "RecurringPayinRegistrationId": "recpayinreg_m_01JJP2KS2A47A0P7S7CEBQPHT9", "PreferredCardNetwork": "MASTERCARD", "CardInfo": { "BIN": "497010", "IssuingBank": "LA BANQUE POSTALE", "IssuerCountryCode": "MA", "Type": "CREDIT", "Brand": "MASTERCARD", "SubType": null } } ``` ### Redirect the user to 3DS protocol The CIT transaction always requires 3DS (the `SecureModeNeeded` value is set to true), so you need to redirect the end user to the `SecureModeRedirectURL` value to complete the authentication. For more information on how to handle 3DS redirection, see Steps 6 and 7 of the [How to process a card payment](/guides/payment-methods/card/direct/how-to) guide. ## 3. Process the subsequent recurring payments (MIT) at the defined intervals Once the first pay-in has been successfully authorized, the platform can initiate payments without the end user being present to authenticate (but note that, at any time, the issuer may request SCA - see Step 5). Create the recurring pay-in at the set interval with the dedicated endpoint. Note that in our example, we didn’t define the next transaction amounts at the registration level. As a consequence, we need to pass the `DebitedFunds` and `Fees` parameters at the pay-in level. > [**POST** /v2.01/\{ClientId}/payins/recurring/card/direct](/api-reference/recurring-card-payins/create-recurring-card-payin) \ #### API response **`200`** ```json 200 { "Id": "payin_m_01JJP59QGFVTMF9Y6YP0K3DXR0", "Tag": "Created using Mangopay API Postman Collection", "CreationDate": 1738058031, "AuthorId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "CreditedUserId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "DebitedFunds": { "Currency": "EUR", "Amount": 10000 }, "CreditedFunds": { "Currency": "EUR", "Amount": 9500 }, "Fees": { "Currency": "EUR", "Amount": 500 }, "Status": "SUCCEEDED", "ResultCode": "000000", "ResultMessage": "Success", "ExecutionDate": 1738058032, "Type": "PAYIN", "Nature": "REGULAR", "CreditedWalletId": "wlt_m_01JJ70WZ9JRAZ9GE0DA36Q84NQ", "DebitedWalletId": null, "PaymentType": "CARD", "ExecutionType": "DIRECT", "SecureMode": null, "CardId": "card_m_UsklnOoXBWyyqhsN", "SecureModeReturnURL": null, "SecureModeRedirectURL": null, "SecureModeNeeded": false, "Culture": "EN", "SecurityInfo": { "AVSResult": "NO_CHECK" }, "StatementDescriptor": "Example123", "BrowserInfo": null, "IpAddress": null, "Billing": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "Shipping": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "Requested3DSVersion": null, "Applied3DSVersion": "V2_1", "RecurringPayinRegistrationId": "recpayinreg_m_01JJP2KS2A47A0P7S7CEBQPHT9", "PreferredCardNetwork": "MASTERCARD", "CardInfo": { "BIN": "497010", "IssuingBank": "LA BANQUE POSTALE", "IssuerCountryCode": "MA", "Type": "CREDIT", "Brand": "MASTERCARD", "SubType": null } } ``` ## 4. Update the registration (if required) Some information regarding the recurring registration may be modified during the recurrence: * `CardId` - Changing this will require a new CIT for SCA * `Billing` and `Shipping` Use the [PUT Update a Recurring PayIn Registration](/api-reference/recurring-payin-registrations/update-recurring-payin-registration) endpoint to modify these details. ## 5. Handle re-authentication (when required) At any moment during the recurrence, the issuer may request that the end user authenticates again. This also occurs when changing the `CardId` in the Recurring PayIn Registration (see Step 4). The need for re-authentication is indicated by the registration object's `Status` changing to `AUTHENTICATION_NEEDED`. You can be notified of this by setting up [webhook notifications](/webhooks) for the following [event type](/webhooks/event-types): * `RECURRING_REGISTRATION_AUTH_NEEDED` In this case, you need to guide the end user through authentication during a new CIT in the same way as Step 2. ## 6. Check the recurring payments' current state The `CurrentState` of the Recurring PayIn Registration provides key information about the recurring payments: * Number of pay-ins made against the registration * Cumulated amounts of debited funds and fees * Last pay-in made against the registration Use the GET View a Recurring PayIn Registration endpoint to get this information. > [**GET** /v2.01/\{ClientId}/recurringpayinregistrations/\{RecurringPayinRegistrationId}](/api-reference/recurring-payin-registrations/view-recurring-payin-registration) \ #### API response **`API response`** ```json API response { "Id": "recpayinreg_m_01JJP2KS2A47A0P7S7CEBQPHT9", "Status": "IN_PROGRESS", "ResultCode": null, "ResultMessage": null, "CurrentState": { "PayinsLinked": 2, "CumulatedDebitedAmount": { "Currency": "EUR", "Amount": 20000 }, "CumulatedFeesAmount": { "Currency": "EUR", "Amount": 1000 }, "LastPayinId": "payin_m_01JJP59QGFVTMF9Y6YP0K3DXR0" }, "RecurringType": "CUSTOM", "TotalAmount": null, "CycleNumber": null, "AuthorId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "CardId": "card_m_UsklnOoXBWyyqhsN", "CreditedUserId": "user_m_01JHX34N3Y9BCQP7KR9QWWETDQ", "CreditedWalletId": "wlt_m_01JJ70WZ9JRAZ9GE0DA36Q84NQ", "Billing": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "Shipping": { "FirstName": "Alex", "LastName": "Smith", "Address": { "AddressLine1": "6 rue de la Cité", "AddressLine2": "Appartement 3", "City": "Paris", "Region": "île-de-France", "PostalCode": "75003", "Country": "FR" } }, "EndDate": null, "Frequency": "Monthly", "FixedNextAmount": true, "FractionedPayment": false, "FreeCycles": 0, "FirstTransactionDebitedFunds": { "Currency": "EUR", "Amount": 10000 }, "FirstTransactionFees": { "Currency": "EUR", "Amount": 500 }, "NextTransactionDebitedFunds": null, "NextTransactionFees": null, "Migration": false, "PaymentType": "CARD_DIRECT" } ``` ## 7. End the recurring payments Recurring payments may come to an end either automatically (when an `EndDate` was defined) or because the end user requests it. To end the recurring payments manually, use the Update a Recurring Registration endpoint to change the `Status` to `ENDED`. > [**PUT** /v2.01/\{ClientId}/recurringpayinregistrations/\{RecurringPayinRegistrationId}](/api-reference/recurring-payin-registrations/update-recurring-payin-registration) **`REST`** ```json REST { "Status": "ENDED" } ``` When you do this, no more recurring pay-ins can be created based on the registration. Set up [webhook notifications](/webhooks) for the following [event type](/webhooks/event-types) to be notified when a registration is ended (for example, by the end user): * `RECURRING_REGISTRATION_ENDED` ## Related resources #### [Guide](/guides/payment-methods/card/recurring) Learn more about recurring card payments #### [Endpoints](/api-reference/recurring-payin-registrations/recurring-payin-registration-object) The Recurring PayIn Registration object #### [How to](/guides/payment-methods/card/direct/how-to) Learn how to process a card payment