# Accept a recurring payment Learn how to collect recurring payments through Pix Automático Pix Automático supports recurring payments through mandates. This lets customers authorize automatic charges for subscriptions and recurring services. ## How it works When setting up a mandate, customers authorize it in their bank app during the initial payment flow. After the mandate is created, you can charge customers automatically for future payments within the mandate terms. ### Initial payments The customer must accept an enrollment, which is the mandate. Your customer authorizes an amount and a billing cycle for recurring charges. If you want to encourage users to upgrade to a higher subscription plan without coming back on session, you can pass a higher amount in `payment_method_options.pix.mandate_options.amount`. Passing higher amounts might impact conversion rates. > If you plan to add sales tax, consider including it in the mandate amount. For subscriptions where there’s an initial payment, your customers authorize an initial charge as part of the mandate creation flow. For subscriptions where there’s no initial payment (free trials), the mandate is created without an initial charge. ### Subsequent payments When you confirm a PaymentIntent for a recurring payment, Stripe automatically: - Triggers the pre-debit notification - Waits the required 3 days - Charges the customer No additional action is required from you. ### Pre-debit notifications Your customer’s bank notifies them 3 days before issuing a charge with the exact debit amount and an option to cancel the payment. The bank generates pre-debit notifications, with no action required from you. This means that subsequent payments are charged on billing cycle plus 3 days. During the period after the notification is sent, the PaymentIntent is in `processing`. Confirmation for a recurring payment typically happens 3 days after the pre-debit notification is sent, but it can take up to 7 days with retries. Example on how subsequent payments are handled on a monthly billing cycle (See full diagram at https://docs.stripe.com/payments/pix/accept-a-recurring-payment) ### Handle Brazilian consumer tax (IOF) IOF is applicable on each recurring transaction. Learn more about [handling IOF](https://docs.stripe.com/payments/pix.md#handle-brazilian-consumer-tax). ### Customer communications In Brazil, businesses commonly send a receipt for each transaction. Learn more about [customer communications](https://docs.stripe.com/payments/pix.md#customer-communications). ### Pix Automático customization Stripe offers multiple options for you to customize the Pix Automático mandate that you set up for your customer. You can specify these options using the `payment_method_options[pix][mandate_options]` hash in the Stripe API: | Field name | Description | Default value | | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | | `reference` | The subscription name displayed to customers in their banking app on enrollment. | Defaults to the user’s displayable business name. | | `amount` | The maximum amount that can be charged in a billing cycle. Set this high enough to allow for price changes and any potential currency conversion fees and Stripe Tax liabilities payable by the buyer. | 400 BRL | | `amount_type` | Set to `maximum` to authorize payments under the mandate up to the amount. Set it to `fixed` to charge that exact amount under the mandate. | `maximum` | | `amount_includes_iof` | Whether the customer pays the IOF (default) or you absorb it on behalf of the customer. | `never` | | `payment_schedule` | The frequency at which you can collect payments. A billing cycle defines the possible charge frequency rather than a required cadence. Pix doesn’t allow you to pass a daily billing schedule. If you select a daily billing schedule, all payments will fail. | `monthly` | | `end_date` | The expiration date for the mandate. | Doesn’t expire if not provided. | | `start_date` | The start date of the mandate, in YYYY-MM-DD format. The start date should be at least 3 days in the future. | Current date plus 3 days | ### Retries After a recurring payment is scheduled, it moves to a `processing` status. After 3 days, automatic capture is attempted. If the capture fails for a retryable reason (for example, insufficient funds or network failures), we retry the payment once a day for the next 3 days. During this time, the payment stays in `processing` status until it moves to a terminal state (`succeeded` or `failed`). This is enabled by default. If you use Stripe Billing, we also support retries for cases when a payment wasn’t scheduled at all (for example, a partner error). In these cases, Stripe Billing can retry once after 1 day. Contact [Stripe support](https://support.stripe.com/) to enable this behavior. # Checkout > This is a Checkout for when payment-ui is checkout. View the full page at https://docs.stripe.com/payments/pix/accept-a-recurring-payment?payment-ui=checkout. ## Determine compatibility **Supported business locations**: US, EU, CA, GB, AU, SG, CH **Supported currencies**: `brl` **Presentment currencies**: `brl` **Payment mode**: Yes **Setup mode**: Yes **Subscription mode**: Yes To support Pix Automático payments in Checkout, express all prices for all line items in BRL (currency code `brl`). ## Set up a subscription > Build an integration to [accept a payment](https://docs.stripe.com/payments/accept-a-payment.md?integration=checkout) with Checkout before using this guide. Create a new Checkout Session in `subscription` mode and provide the mandate options for Pix. Mandate options dictate how the payment method can be saved for future payments. Since mandates can’t be updated, we recommend using values that can cover any anticipated changes to the subscription. ### Enable Pix as a payment method When creating a new [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md), you need to: 1. Add `pix` to the list of `payment_method_types`. 1. Make sure all your `line_items` use the `brl` currency. #### Stripe-hosted page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=brl" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][recurring][interval]=month" \ -d "line_items[0][price_data][recurring][interval_count]=1" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=subscription \ -d "payment_method_types[0]=pix" \ -d "payment_method_options[pix][mandate_options][amount]=2000" \ -d "payment_method_options[pix][mandate_options][payment_schedule]=monthly" \ --data-urlencode "success_url=https://example.com/success" ``` #### Embedded form ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=brl" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][recurring][interval]=month" \ -d "line_items[0][price_data][recurring][interval_count]=1" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=subscription \ -d "payment_method_options[pix][mandate_options][amount]=2000" \ -d "payment_method_options[pix][mandate_options][payment_schedule]=monthly" \ -d "payment_method_types[0]=pix" \ --data-urlencode "return_url=https://example.com/return" \ -d ui_mode=embedded_page ``` ## Test your integration To test your integration: 1. Select Pix. 1. Enter the buyer’s details and tap **Pay**. In a testing environment, you can use `000.000.000-00` as a test tax identifier (CPF or CNPJ). 1. Click **Simulate scan** to open a Stripe-hosted Pix test payment page. From this page, you can either authorize or expire the test payment. In live mode, the **Pay** button displays a Pix QR code. You need a Brazilian bank account with Pix enabled to complete or cancel this payment flow. You can also set [payment_method.billing_details.email](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_data-billing_details-email) to the following values to test different scenarios. | Email | Description | | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `{any_prefix}expire_immediately@{any_domain}` | Simulates a Pix that expires immediately. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) or [setup_intent.setup_failed](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.setup_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. No active mandate is created. Example: `expire_immediately@test.com` | | `{any_prefix}expire_with_delay@{any_domain}` | Simulates a Pix that expires after 3 minutes. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) or [setup_intent.setup_failed](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.setup_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after about 3 minutes. No active mandate is created. Example: `expire_with_delay@test.com` | | `{any_prefix}succeed_mandate_expire_payments_immediately@{any_domain}` | Simulates a Pix that a customer pays immediately. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. An active mandate is created. Recurring payments with the same payment method expire immediately. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. Example: `succeed_mandate_expire_payments_immediately@test.com` | | `{any_prefix}succeed_mandate_expire_payments_with_delay@{any_domain}` | Simulates a Pix that a customer pays after 3 minutes. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. An active mandate is created. Recurring payments with the same payment method expire after 3 minutes. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after about 3 minutes. Example: `succeed_mandate_expire_payments_with_delay@test.com` | | `{any_prefix}succeed_immediately@{any_domain}` | Simulates a Pix that a customer pays immediately. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. An active mandate is created. Any recurring payments with the same payment method succeed immediately. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. Example: `succeed_immediately@test.com` | | `{any_prefix}@{any_domain}` | Simulates a Pix that a customer pays after 3 minutes. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after approximately 3 minutes. An active mandate is created. Any recurring payments with the same payment method succeed after 3 minutes. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after approximately 3 minutes. Example: `anything@test.com` | # Elements > This is a Elements for when payment-ui is elements. View the full page at https://docs.stripe.com/payments/pix/accept-a-recurring-payment?payment-ui=elements. There are no specific configurations needed for [Payment Element](https://docs.stripe.com/payments/advanced.md). Make sure Pix Automático is enabled from the Payment Methods setting page, then: - If you use [Dynamic Payment Methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md), specify `brl` as the currency. - If you use the `payment_method_types` parameter, add `pix` to the list. - Provide the mandate options for Pix. Mandate options dictate how the payment method can be saved for future payments. Since mandates can’t be updated, we recommend using values that can cover any anticipated changes to the subscription. Learn more about the available [Pix Automático customization](https://docs.stripe.com/payments/pix/accept-a-recurring-payment.md#pix-automtico-customization) parameters. ## Test your integration To test your integration: 1. Select Pix. 1. Enter the buyer’s details and tap **Pay**. In a testing environment, you can use `000.000.000-00` as a test tax identifier (CPF or CNPJ). 1. Click **Simulate scan** to open a Stripe-hosted Pix test payment page. From this page, you can either authorize or expire the test payment. In live mode, the **Pay** button displays a Pix QR code. You need a Brazilian bank account with Pix enabled to complete or cancel this payment flow. You can also set [payment_method.billing_details.email](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_data-billing_details-email) to the following values to test different scenarios. | Email | Description | | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `{any_prefix}expire_immediately@{any_domain}` | Simulates a Pix that expires immediately. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) or [setup_intent.setup_failed](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.setup_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. No active mandate is created. Example: `expire_immediately@test.com` | | `{any_prefix}expire_with_delay@{any_domain}` | Simulates a Pix that expires after 3 minutes. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) or [setup_intent.setup_failed](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.setup_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after about 3 minutes. No active mandate is created. Example: `expire_with_delay@test.com` | | `{any_prefix}succeed_mandate_expire_payments_immediately@{any_domain}` | Simulates a Pix that a customer pays immediately. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. An active mandate is created. Recurring payments with the same payment method expire immediately. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. Example: `succeed_mandate_expire_payments_immediately@test.com` | | `{any_prefix}succeed_mandate_expire_payments_with_delay@{any_domain}` | Simulates a Pix that a customer pays after 3 minutes. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. An active mandate is created. Recurring payments with the same payment method expire after 3 minutes. The [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after about 3 minutes. Example: `succeed_mandate_expire_payments_with_delay@test.com` | | `{any_prefix}succeed_immediately@{any_domain}` | Simulates a Pix that a customer pays immediately. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. An active mandate is created. Any recurring payments with the same payment method succeed immediately. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives within several seconds. Example: `succeed_immediately@test.com` | | `{any_prefix}@{any_domain}` | Simulates a Pix that a customer pays after 3 minutes. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) or [setup_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-setup_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after approximately 3 minutes. An active mandate is created. Any recurring payments with the same payment method succeed after 3 minutes. The [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) arrives after approximately 3 minutes. Example: `anything@test.com` | ## Optional: Change the pricing of an existing subscription You can [update the pricing of an existing subscription](https://docs.stripe.com/api/subscriptions/update.md). If the new total amount in the subscription is greater than the amount in the mandate, the recurring payments might fail and trigger a [payment failed](https://docs.stripe.com/billing/subscriptions/webhooks.md#payment-failures) webhook event. Such payments *might fail* because customers have the option to set a limit, however, Stripe doesn’t have any visibility. The status of the subscription might change depending on your [subscription configuration](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-statuses). You have several options for handling these scenarios: - You can ask your customer to increase the mandate amount in their banking app. - You can update the mandate options with the new amount using the [Update Subscription](https://docs.stripe.com/api/subscriptions/update.md) API and create a [Customer Portal](https://docs.stripe.com/api/customer_portal/sessions/create.md) session for your customer to update their Pix payment method. - You can update the mandate options with the new amount using the [Update Subscription](https://docs.stripe.com/api/subscriptions/update.md) API and create a [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) in `setup` mode without an initial payment or in `payment` mode with [payment_method_options.pix.setup_future_usage](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_method_options-pix-setup_future_usage)=`off_session` (with an initial payment) to create a new mandate with a new payment method, and [update the payment method of the subscription](https://docs.stripe.com/payments/checkout/subscriptions/update-payment-details.md#set-default-payment-method). - You can cancel and re-create the subscription. ## Optional: Change the billing cycle of an existing subscription You can [update the billing cycle of an existing subscription](https://docs.stripe.com/api/subscriptions/update.md). If the payment schedule in the mandate options is more restrictive than the new interval of the subscription (for example, if the mandate’s `payment_schedule=monthly` and the new `interval=weekly`), the recurring payments fail and you receive a [payment failed](https://docs.stripe.com/billing/subscriptions/webhooks.md#payment-failures) webhook event. The status of the subscription might change depending on your [subscription configuration](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-statuses). You have several options for handling these scenarios: - You can update the mandate options with the new interval using the [Update Subscription](https://docs.stripe.com/api/subscriptions/update.md) API and create a [Customer Portal](https://docs.stripe.com/api/customer_portal/sessions/create.md) session for your customer to update their Pix payment method. - You can update the mandate options with the new interval using the [Update Subscription](https://docs.stripe.com/api/subscriptions/update.md) API and create a [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) in `setup` mode (without an initial payment) or in `payment` mode with [payment_method_options.pix.setup_future_usage](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_method_options-pix-setup_future_usage)=`off_session` (with an initial payment) to create a new mandate with a new payment method, and [update the payment method of the subscription](https://docs.stripe.com/payments/checkout/subscriptions/update-payment-details.md#set-default-payment-method). - You can cancel and re-create the subscription. ## Optional: Handle payment failures If a recurring payment fails and the reason is not related to the pricing or the billing cycle change scenarios described above, we retry the payment as described in the [Retries](https://docs.stripe.com/payments/pix/accept-a-recurring-payment.md#retries) section. If the payment fails after exhausting all of the retries, you can do one of the following: - Create a one-time payment for your customer to pay the invoice for the subscription. - Create a [Customer Portal](https://docs.stripe.com/api/customer_portal/sessions/create.md) session for your customer to pay the invoice or update their payment method. ## Optional: Handle add-on purchases after subscription creation Due to scheme restrictions, you can only charge a Pix payment method once per cycle specified in [payment_method_options.pix.mandate_options.payment_schedule](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_method_options-pix-mandate_options-payment_schedule). If you have a case where your users can buy add-ons after the subscription creation, you can follow the instructions below, depending on your use case: - If you don’t require an immediate payment and you only want to update the subscription for future payments, you can update the existing subscription using the [Update Subscription](https://docs.stripe.com/api/subscriptions/update.md) API. The restrictions mentioned in [Change the pricing of an existing subscription](https://docs.stripe.com/payments/pix/accept-a-recurring-payment.md#change-pricing-of-subscription) still apply. If the mandate restrictions mentioned in that section aren’t respected, your recurring payments might fail. - If you require an immediate payment, you can create a one-time payment by creating a Checkout Session in `payment` mode and bringing your user back on-session. Separately, if you also want to update the subscription for future payments, you can use the [Update Subscription](https://docs.stripe.com/api/subscriptions/update.md) API.