Create a Mandate for Recurring Payments with PIS

You can embed setting up a Mandate to be used for recurring charges within a one-off payment flow. This simplifies the process in your system, as it removes the need to build extra confirmation screens or integrate new Ivy endpoints.

At a high level, the flow is the following:

  • Checkout Creation: Add a mandate object to your Checkout Create request, set the field setup to true, pass a referenceId for the Mandate to associate the respective mandate_setup_succeeded and mandate_setup_failed webhook events with your initial request later on. Additionally, you need to pass a userNotificationEmail to the Mandate object which is displayed during the Checkout when requesting to setup a Mandate (you need to notify the user about the respective events using this email address as well).

  • You can pass an optional object additionalDisplayInformation to show a cadence and amount for the Mandate to your customers.

    • Keep in mind that both the object is optional, and either of price and cadence. However, if you provide an amount, you also have to provide the currency.
    • Cadence can be any of the following: BI_WEEKLY, WEEKLY, MONTHLY, QUARTERLY, SEMI_ANNUAL, ANNUAL, ON_DEMAND
    • See how showing these values looks in the Checkout in the screenshots below.
  • Proceed the same way as you would for a usual payment flow with Checkout Sessions and send your user to Ivy’s hosted Checkout flow.

    Example Payload
    // Recommended Configuration
    {
      "price": {
        "totalNet": 100,
        "vat": 19,
        "total": 119,
        "currency": "EUR"
      },
      "referenceId": "my-unique-checkout-reference-id",
      "successCallbackUrl": "https://my-website.com/success",
      "errorCallbackUrl": "https://my-website.com/try-again",
      "...": "...",
      "mandate": {
        "setup": true, // needs to be true to setup a Mandate
        "referenceId": "my-unique-mandate-reference",
        "userNotificationEmail": "the-email-address-of-your-user-to-send-notifications-to",
        "accountHolderName": "the-account-holder-name",
        "additionalDisplayInformation": {
          "cadence": "MONTHLY",
          "price": {
            "amount": 9.99,
            "currency": "EUR"
          }
        }
      }
    }
    
  • Within the payment flow, users confirm to set up a Mandate on the Ivy screens.

  • Following a successful payment authorization that starts with the CheckoutSession, an Order will be created. Alongside this Order, a Mandate will be set up separately and without blocking the payment authorization process.

Authorization Screen for a Mandate with a 1.00€ payment immediately and 9.99€ Monthly

We emit several Mandate-related webhook events while setting up and finalizing a Mandate. To get notified via changes to your Mandate, you should subscribe to these via a webhook.

Currently, we emit the following events:

  • mandate_setup_started
  • mandate_setup_succeeded
  • mandate_setup_failed
  • mandate_revoked

Mandate Setup Started

When initiating a Checkout Create with a Mandate as described above, we will notify you when the Mandate setup has started. You can receive the mandate_setup_started event to confirm that starting the Mandate setup was successful. You will get notified later once the Mandate has been finalized via the mandate_setup_succeeded or the mandate_setup_failed event.

mandate_setup_started payload
{
  "id": "c8878bf1-ea3c-47da-aff2-4f624399b3d0",
  "type": "mandate_setup_started",
  "payload": {
    "referenceId": "my-unique-mandate-reference-id", // You are setting this in the Mandate object in /checkout/session/create
    "reference": "my-unique-checkout-reference-id", // You are setting this in /checkout/session/create
    "signature": {
      "ip": "127.0.0.1",
      "token": "uniqueToken_ab12cd34",
      "signedAt": "2024-07-24T16:38:37.240Z"
    },
    "userNotificationEmail": "[email protected]",
    "creditor": {
      "id": "ABC1289113189389",
      "name": "Creditor Name",
      "address": {
        "street": "Example Street",
        "city": "Example City",
        "postalCode": "12345",
        "country": "DE"
      }
    }
  },
  "date": "2024-07-24T16:38:48.621Z"
}

Successful Mandate Setup

Following a successful Mandate setup, you will receive the mandate_setup_succeeded webhook event. This allows you to retrieve and store the Mandate’s id which can be used to initiate charges afterwards. This webhook event contains all relevant Mandate data that can be used to inform the user about the issuance and usage of the Mandate as required by the SEPA regulation.

mandate_setup_succeeded payload
{
  "id": "", // The id of the specific webhook event. Use this in the /webhook/trigger endpoint to re-send the webhook.
  "type": "mandate_setup_succeeded",
  "payload": {
    "id": "", // The id of the Mandate to be used in the future
    "referenceId": "", // The reference provided during the initial Checkout Session under mandate.referenceId
    "reference": "", // The Mandate reference that will appear on the customer's bank statement
    "signature": {
      "ip": "",
      "token": "",
      "signedAt": ""
    },
    "creditor": {
      "address": {
        "street": "",
        "city": "",
        "postalCode": "",
        "country": "" // alpha2 country code
      },
      "id": "",
      "name": ""
    },
    "debtor": {
      // Debtor account information of the account the Mandate has been issued for
      "account": {
        "iban": "",
        "accountHolderName": "",
        "bic": ""
      }
    }
  },
  "date": "datetime" // The datetime timestamp of the webhook
}

Failed Mandate Setup

When a Mandate setup fails, you can get notified using the mandate_setup_failed webhook event. This provides more insights into why the Mandate setup failed.

Using webhook event
{
  "id": "", // The id of the specific webhook event. Use this in the /webhook/trigger endpoint to re-send the webhook.
  "type": "mandate_setup_failed",
  "payload": {
    "error": {
      "code": "",
      "message": ""
    },
    "referenceId": "" // The reference provided during the initial Checkout Session under mandate.referenceId
  },
  "date": "datetime" // The datetime timestamp of the webhook
}

Mandate Revocation

When a charge is reversed by a customer or we detect that it’s no longer valid for any other reason, we inform you about the Mandate being revoked. In this case, this Mandate can’t be used any longer to create a charge. A new Mandate needs to be set up if you want to create further charges for the respective customer.

Using webhook event
{
  "id": "", // The id of the specific webhook event. Use this in the /webhook/trigger endpoint to re-send the webhook.
  "type": "mandate_revoked",
  "payload": {
    "id": "", // The id of the Mandate
    "referenceId": "", // The reference provided during the initial Checkout Session under mandate.referenceId
    "revokedAt": "" // The datetime the Mandate has been revoked
  },
  "date": "datetime" // The datetime timestamp of the webhook
}