# Save Bacs Direct Debit bank details Learn how to use Checkout to save payment method details for future Bacs Direct Debit payments. Use [Stripe Checkout](https://docs.stripe.com/payments/checkout.md) to collect Bacs Direct Debit payment details in advance, with the final amount or payment date determined later. This is useful for: - Saving payment methods to a wallet to streamline future purchases. - Collecting surcharges after fulfilling a service. - [Starting a free trial for a subscription](https://docs.stripe.com/billing/subscriptions/trials.md). ## Set up Stripe [Server-side] First, you need a Stripe account. [Register now](https://dashboard.stripe.com/register). Use our official libraries for access to the Stripe API from your application: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Create a Customer [Server-side] To reuse a Bacs Direct Debit payment method for future payments, you must attach it to a *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments). Create a Customer object when someone creates an account with you and associate the ID of the Customer object with your own internal representation of a customer so you can use the stored payment method details later. If you have an existing Customer object, skip this step. ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## Create a Checkout Session [Client-side] [Server-side] [Stripe Checkout](https://docs.stripe.com/payments/checkout.md) provides a hosted payment page that is compliant with Bacs Direct Debit rules. If you would like to design your own Bacs Direct Debit form, please [contact](https://stripe.com/contact/sales) our sales team. Before you can accept Direct Debit payments, your customer must provide their bank account information and give permission to debit their account (also known as a [mandate](https://docs.stripe.com/payments/payment-methods/bacs-debit.md#mandates)) through Stripe Checkout. Add a checkout button to your website that calls a server-side endpoint to create a Checkout Session. ```html Checkout
``` Create a Checkout Session in `setup` mode to collect the required information. After creating the Checkout Session, redirect your customer to the [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) returned in the response. #### curl ```bash curl https://api.stripe.com/v1/checkout/sessions \ -u <>: \ -d "payment_method_types[]"="bacs_debit" \ -d mode=setup \ -d customer="{{CUSTOMER_ID}}" \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ ``` When your customer provides their payment method details, they’re redirected to the `success_url`, a page on your website that informs them that their payment method was saved successfully. Make the Session ID available on your success page by including the `{CHECKOUT_SESSION_ID}` template variable in the `success_url` as in the above example. > Don’t rely on the redirect to the `success_url` alone for detecting payment initiation, because: > > - Malicious users could directly access the `success_url` without paying and gain access to your goods or services. - After a successful payment, customers might close their browser tab before they’re redirected to the `success_url`. > The Bacs Direct Debit rules require that customers are sent an email notification when payment details are collected. By default, these emails are sent automatically by Stripe. You can also opt to [send your own Bacs notifications](https://docs.stripe.com/payments/payment-methods/bacs-debit.md#debit-notifications). ## Retrieve the payment method [Server-side] After a customer submits their payment details, retrieve the [PaymentMethod](https://docs.stripe.com/payments/payment-methods.md) object. A *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) stores the customer’s bank account information for future payments. You can retrieve the PaymentMethod synchronously using the `success_url` or asynchronously using *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests). The decision to retrieve the PaymentMethod synchronously or asynchronously depends on your tolerance for dropoff, as customers might not always reach the `success_url` after a successful payment (for example, it’s possible for them to close their browser tab before the redirect occurs). Using webhooks prevents your integration from experiencing this form of dropoff. #### Webhooks Handle `checkout.session.completed` webhooks, which contain a Session object. To learn more, see [setting up webhooks](https://docs.stripe.com/webhooks.md). The following example is a `checkout.session.completed` response. ```json { "id": "evt_1Ep24XHssDVaQm2PpwS19Yt0", "object": "event", "api_version": "2019-03-14", "created": 1561420781, "data": { "object": { "id": "cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k", "object": "checkout.session", "billing_address_collection": null, "client_reference_id": null, "customer": null, "customer_email": null, "display_items": [], "mode": "setup","setup_intent": "seti_1EzVO3HssDVaQm2PJjXHmLlM", "submit_type": null, "subscription": null, "success_url": "https://example.com/success" } }, "livemode": false, "pending_webhooks": 1, "request": { "id": null, "idempotency_key": null }, "type": "checkout.session.completed" } ``` Note the value of the `setup_intent` key, which is the ID for the SetupIntent created with the Checkout Session. A [SetupIntent](https://docs.stripe.com/payments/setup-intents.md) is an object used to set up the customer bank account information for future payments. [Retrieve](https://docs.stripe.com/api/setup_intents/retrieve.md) the SetupIntent object with the ID. The returned object contains the `payment_method` ID. ```curl curl https://api.stripe.com/v1/setup_intents/seti_1EzVO3HssDVaQm2PJjXHmLlM \ -u "<>:" ``` #### Success URL Obtain the `session_id` from the URL when a user redirects back to your site and [retrieve](https://docs.stripe.com/api/checkout/sessions/retrieve.md) the Session object. ```curl curl -G https://api.stripe.com/v1/checkout/sessions/{{SESSION_ID}} \ -u "<>:" \ -d "expand[]=setup_intent" ``` > To ensure the `session_id` is available from the URL, include the `session_id={CHECKOUT_SESSION_ID}` template variable in the `success_url` when creating the Checkout Session. Note the SetupIntent created during the Checkout Session. A [SetupIntent](https://docs.stripe.com/payments/setup-intents.md) is an object used to set up the customer bank account information for future payments. The returned object contains the `payment_method` ID. ## Handle post-setup events [Server-side] Once the Checkout Session completes, payment details are submitted to the bank as a mandate. The mandate can change at any time after you’ve collected it. This might be the result of the customer instructing their bank to amend the mandate or because of a change in the bank itself (for example, the customer changes to a different one). Stripe sends the following events when the mandate changes: | Event name | Description | Can accept payments? | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | | `mandate.updated` | Occurs whenever a mandate is rejected, canceled, or reactivated by the Bacs network. Check [mandate.status](https://docs.stripe.com/api/mandates/object.md#mandate_object-status) to determine if the mandate can continue to be used. | Yes, if the new status is `active` | | `payment_method.automatically_updated` | Occurs when a customer’s bank account details change. | Yes | These events are available in the [Dashboard](https://dashboard.stripe.com/events), but you can set up a *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) to handle these programmatically. ## Test the integration There are several [test bank account numbers](https://docs.stripe.com/keys.md#test-live-modes) you can use in a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes) to make sure this integration is ready. | Sort code | Account number | Description | | --------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 108800 | 00012345 | The payment succeeds and the PaymentIntent transitions from `processing` to `succeeded`. | | 108800 | 90012345 | The payment succeeds after three minutes and the PaymentIntent transitions from `processing` to `succeeded`. | | 108800 | 33333335 | The payment is accepted but then immediately fails with a `debit_not_authorized` failure code and the PaymentIntent transitions from `processing` to `requires_payment_method`. The Mandate becomes `inactive` and the PaymentMethod can’t be used again. | | 108800 | 93333335 | The payment fails after three minutes with a `debit_not_authorized` failure code and the PaymentIntent transitions from `processing` to `requires_payment_method`. The Mandate becomes `inactive` and the PaymentMethod can’t be used again. | | 108800 | 22222227 | The payment fails with an `insufficient_funds` failure code and the PaymentIntent transitions from `processing` to `requires_payment_method`. The Mandate remains `active` and the PaymentMethod can be used again. | | 108800 | 92222227 | The payment fails after three minutes with an `insufficient_funds` failure code and the PaymentIntent transitions from `processing` to `requires_payment_method`. The Mandate remains `active` and the PaymentMethod can be used again. | | 108800 | 55555559 | The payment succeeds after three minutes and the PaymentIntent transitions from `processing` to `succeeded`, but a dispute is immediately created. | | 108800 | 00033333 | Payment Method creation succeeds, but the Mandate is refused by the customer’s bank and immediately transitions to inactive. | | 108800 | 00044444 | The request to set up Bacs Direct Debit fails immediately due to an invalid account number and the customer is prompted to update their information before submitting. Payment details aren’t collected. | | 108800 | 34343434 | The payment fails with a `charge_exceeds_source_limit` failure code due to the payment amount causing the account to exceed its weekly payment volume limit. | | 108800 | 12121212 | The payment fails with a `charge_exceeds_weekly_limit` failure code due to the payment amount exceeding the account’s transaction volume limit. | You can test using any of the account numbers provided above. However, because Bacs Direct Debit payments take several days to process, use the test account numbers that operate on a three-minute delay to better simulate the behavior of live payments. > By default, Stripe automatically sends [emails](https://docs.stripe.com/payments/payment-methods/bacs-debit.md#debit-notifications) to the customer when payment details are initially collected and each time a debit will be made on their account. These notifications aren’t sent in sandboxes. ## Use the payment method for future payments [Server-side] After you set up a *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs), you can accept future Bacs Direct Debit payments by creating and confirming a [PaymentIntent](https://docs.stripe.com/payments/payment-intents.md). #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "payment_method_types[]"="bacs_debit" \ -d payment_method="{{PAYMENT_METHOD_ID}}" \ -d customer="{{CUSTOMER_ID}}" \ -d confirm=true \ -d amount=100 \ -d currency=gbp ```