> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withorb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# India e-Mandates

> Set up and test India e-Mandates with Stripe for recurring payment collection

India e-Mandates allow you to collect a one-time payment authorization from Indian customers, enabling recurring or sporadic charges without requiring the customer to be present for each transaction. This is a requirement from the [Reserve Bank of India (RBI)](https://rbi.org.in//Scripts/NotificationUser.aspx?Id=11668) for recurring card payments, and Stripe supports this through their SetupIntent API with India-specific mandate options ([docs](https://docs.stripe.com/india-recurring-payments)).

When an e-Mandate is properly configured in Stripe and linked to an Orb customer, Orb can automatically charge the customer's default payment method when issuing invoices — just like any other Stripe payment method.

## Why e-Mandates require extra setup

Unlike standard card payments, India e-Mandates require the merchant to explicitly create a mandate with specific parameters (amount cap, interval, start date) as part of the payment method setup. This means you cannot simply attach a card to a Stripe customer — you must go through the SetupIntent flow with `mandate_options` configured for India.

This additional step is often a source of confusion during testing, since there is no way to create an India e-Mandate directly from the Stripe dashboard. You must use the Stripe API (or a frontend integration with Stripe Elements) to collect the mandate.

## Prerequisites

<Warning>
  All testing should be done in **Stripe test mode** and **Orb test mode**. Using live mode keys during testing can result in real charges to customers. In Orb, ensure you are operating in your test environment before connecting Stripe or creating customers.
</Warning>

Before setting up an India e-Mandate, ensure the following:

* Your Stripe **test mode** account is connected to Orb in **test mode** (see [Connecting Stripe with Orb](/integrations-and-exports/stripe#connecting-stripe-with-orb))
* You have access to your Stripe **test mode** API keys (`sk_test_` and `pk_test_` prefixed keys from the [Stripe API keys page](https://dashboard.stripe.com/test/apikeys))
* You have a test customer created in the [Stripe test dashboard](https://dashboard.stripe.com/test/customers)

## How it works

The e-Mandate collection flow involves three steps:

1. **Create a SetupIntent** with India-specific mandate options via the Stripe API
2. **Collect the card details** from the customer using Stripe Elements on the frontend
3. **Set the payment method as default** on the Stripe customer so Orb can use it for auto-collection

### SetupIntent mandate options

When creating a SetupIntent for an India e-Mandate, you must include `mandate_options` under `payment_method_options.card`. The key parameters are:

| Parameter         | Description                                                                                 |
| ----------------- | ------------------------------------------------------------------------------------------- |
| `reference`       | A unique identifier for the mandate (e.g., combining the customer ID and a timestamp)       |
| `amount`          | The maximum amount that can be charged per interval, in the smallest currency unit          |
| `amount_type`     | Set to `"maximum"` to define a cap on the charge amount                                     |
| `currency`        | The currency for the mandate (e.g., `"inr"`)                                                |
| `interval`        | How often charges can occur — `"sporadic"` for on-demand or `"monthly"` for regular billing |
| `start_date`      | Unix timestamp for when the mandate becomes active                                          |
| `supported_types` | Must include `"india"` to indicate this is an India-specific mandate                        |

The SetupIntent should also specify `usage: "off_session"` to indicate that the payment method will be used for charges when the customer is not present.

<Info>
  The `amount` field represents the **maximum** amount that can be charged per transaction, not a fixed charge amount. Set this to a value that accommodates your highest expected invoice amount for the customer.
</Info>

### Confirming the SetupIntent

On the frontend, use Stripe Elements to render a payment form and collect the customer's card details. When the customer submits the form, confirm the SetupIntent using `stripe.confirmSetup()`. Stripe handles the mandate authorization as part of this confirmation step.

### Setting the default payment method

After the SetupIntent is confirmed, the resulting payment method must be set as the customer's default in Stripe:

```javascript theme={null}
await stripe.customers.update(customerId, {
  invoice_settings: { default_payment_method: paymentMethodId },
});
```

This ensures that Orb will use this payment method when auto-collecting invoices.

## Testing with the example application

We provide a [reference implementation](https://github.com/orbcorp/stripe-mandate-example) that demonstrates the full e-Mandate collection flow using a Node.js/Express backend and a Stripe Elements frontend.

### Setup

Please follow the instructions in the [reference implementation](https://github.com/orbcorp/stripe-mandate-example/blob/main/README.md) to set up the example application.

### Test card details

Use the following Stripe test card to simulate an India e-Mandate:

| Field       | Value              |
| ----------- | ------------------ |
| Card number | `4000003560000123` |
| Expiry      | Any future date    |
| CVC         | Any 3 digits       |
| Postal code | Any 5 digits       |

### What to expect

After submitting the form with the test card:

1. The SetupIntent is confirmed and the mandate is created in Stripe
2. The payment method is set as the customer's default
3. Approximately one minute later, a `mandate.updated` webhook event fires (visible in the [Stripe developers tab](https://dashboard.stripe.com/test/events))
4. The payment method appears under "Payment methods" in the [customer's Stripe dashboard page](https://dashboard.stripe.com/test/customers)

<Note>
  The example application uses a simple implementation that generates a unique mandate reference on server startup. You will need to restart the server (`Ctrl+C` then `node server.js`) between mandate setups.
</Note>

## Connecting to Orb

Once the e-Mandate is set up and the payment method is the customer's default in Stripe, connect it to Orb:

1. Ensure the Stripe customer is [mapped to an Orb customer](/integrations-and-exports/stripe#configuring-customers) with `payment_provider` set to `stripe_charge` or `stripe_invoice`.
2. Verify that [auto-collection](/invoicing/payments#auto-collection) is enabled for the customer.
3. Orb will automatically sync the default payment method from Stripe and use it when issuing invoices.

When Orb issues an invoice for this customer, it will charge the e-Mandate payment method through Stripe. The mandate's `amount` cap must be sufficient to cover the invoice amount, or the charge will be declined by Stripe.

<Warning>
  If the invoice amount exceeds the mandate's configured `amount` cap, Stripe will decline the charge. Ensure the mandate amount is set high enough to accommodate your expected invoice amounts. There is a maximum amount cap of 15,000 INR for India e-Mandates. Anything above this amount will be rounded down to 15,000 INR.
</Warning>

## Troubleshooting

### Mandate not appearing on the customer

Ensure the SetupIntent was confirmed successfully and the payment method was explicitly set as the customer's default via `invoice_settings.default_payment_method`. Simply attaching a payment method is not sufficient — it must be set as the default.

### Charges failing after mandate setup

* Verify the mandate's `amount` cap is higher than the invoice amount
* Check that the mandate's `start_date` is in the past (the mandate must be active)
* Confirm the `mandate.updated` webhook event has fired in Stripe (this indicates the mandate is fully active)

### Webhook events to monitor

The following Stripe webhook events are relevant to the e-Mandate lifecycle:

| Event                           | Description                                                                             |
| ------------------------------- | --------------------------------------------------------------------------------------- |
| `setup_intent.succeeded`        | The SetupIntent was confirmed and the mandate was created                               |
| `mandate.updated`               | The mandate status has changed (fires \~1 minute after creation when it becomes active) |
| `payment_intent.succeeded`      | A charge against the mandate was successful                                             |
| `payment_intent.payment_failed` | A charge against the mandate failed                                                     |
