Accept an iDEAL payment
Learn how to accept iDEAL, a common payment method in the Netherlands.
iDEAL is a single use payment method where customers are required to authenticate their payment. Customers pay with iDEAL by redirecting from your website, authorising the payment, then returning to your website where you get immediate notification on whether the payment succeeded or failed.
Use Payment Elements to embed a custom Stripe payment form in your website or application. Payment Elements allows you to support iDEAL and other payment methods automatically. For advanced configurations and customisations, refer to the Accept a payment integration guide.
Note
To accept iDEAL, you must comply with our iDEAL Terms of Service.
Set up StripeServer-side
First, you need a Stripe account. Register now.
Use our official libraries for access to the Stripe API from your application:
Create a PaymentIntentServer-side
A PaymentIntent is an object that represents your intent to collect payment from a customer and tracks the lifecycle of the payment process through each stage. First, create a PaymentIntent
on your server and specify the amount to collect and the eur
currency (iDEAL doesn’t support other currencies). iDEAL has no minimum charge amount, so the payment amount
value can be as low as 1. If you already have an integration using the Payment Intents API, add ideal
to the list of payment method types for your PaymentIntent
.
Retrieve the client secret
The PaymentIntent includes a client secret that the client side uses to securely complete the payment process. You can use different approaches to pass the client secret to the client side.
Collect payment method detailsClient-side
Collect payment details on the client with the Payment Element. The Payment Element is a pre-built UI component that simplifies collecting payment details for a variety of payment methods.
The Payment Element contains an iframe that securely sends payment information to Stripe over an HTTPS connection. Avoid placing the Payment Element within another iframe because some payment methods require redirecting to another page for payment confirmation.
The checkout page address must start with https://
rather than http://
for your integration to work. You can test your integration without using HTTPS, but remember to enable it when you’re ready to accept live payments.
Submit the payment to StripeClient-side
Use stripe.confirmPayment to complete the payment using details from the Payment Element. Provide a return_url to this function to indicate where Stripe should redirect the user after they complete the payment. Your user may be first redirected to an intermediate site, such as a bank authorisation page, before being redirected to the return_
. Card payments immediately redirect to the return_
when a payment is successful.
Make sure the return_
corresponds to a page on your website that provides the status of the payment. When Stripe redirects the customer to the return_
, we provide the following URL query parameters:
Parameter | Description |
---|---|
payment_ | The unique identifier for the PaymentIntent . |
payment_ | The client secret of the PaymentIntent object. |
Caution
If you have tooling that tracks the customer’s browser session, you might need to add the stripe.
domain to the referrer exclude list. Redirects cause some tools to create new sessions, which prevents you from tracking the complete session.
Use one of the query parameters to retrieve the PaymentIntent. Inspect the status of the PaymentIntent to decide what to show your customers. You can also append your own query parameters when providing the return_
, which persist through the redirect process.
Test your integration
Use your test API keys to confirm the PaymentIntent. After confirming, you’re redirected to a test page with options to authorise or fail the payment.
- Click Authorize test payment to test the case when the payment is successful. The PaymentIntent transitions from
requires_
toaction succeeded
. - Click Fail test payment to test the case when the customer fails to authenticate. The PaymentIntent transitions from
requires_
toaction requires_
.payment_ method
OptionalHandle post-payment events
Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.
Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events also helps you accept more payment methods in the future. Learn about the differences between all supported payment methods.
Handle events manually in the Dashboard
Use the Dashboard to View your test payments in the Dashboard, send email receipts, handle payouts or retry failed payments.
Build a custom webhook
Build a custom webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.
Integrate a prebuilt app
Handle common business events, such as automation or marketing and sales, by integrating a partner application.
OptionalHandle the iDEAL redirect manually
We recommend relying on Stripe.js to handle iDEAL redirects and payments with confirmIdealPayment
. However, you can also complete the payment on your server and manually redirect your customer.
- After collecting payment method details, call stripe.createPaymentMethod to create a PaymentMethod:
const paymentMethod = await stripe.createPaymentMethod({ type: 'ideal', billing_details: { name: accountholderName.value, }, });
- On your server, confirm the PaymentIntent with the PaymentMethod ID and provide a return_url to redirect your customer after they complete the payment.Confirming the
PaymentIntent
has a status ofrequires_
with aaction next_
ofaction redirect_
.to_ url { "next_action": { "type": "redirect_to_url", "redirect_to_url": { "url": "https://hooks.stripe.com/...", "return_url": "https://example.com/checkout/complete" } }, "charges": { "data": [ { "payment_method_details": { "ideal": { "bank": "ing", "bic": "INGBNL2A",
- Redirect your customer to the URL provided in the
next_
property so they can authenticate and complete the payment.action Your customer is redirected to theconst action = intent.next_action; if (action && action.type === 'redirect_to_url') { window.location = action.redirect_to_url.url; }
return_
after they complete the payment. The URL includesurl payment_
andintent payment_
query parameters and you can also append your own query parameters, as described above.intent_ client_ secret
Bank reference
Bank name | Value |
---|---|
ABN AMRO | abn_ |
ASN Bank | asn_ |
Bunq | bunq |
ING | ing |
Knab | knab |
N26 | n26 |
Nationale-Nederlanden | nn |
Rabobank | rabobank |
Revolut | revolut |
RegioBank | regiobank |
SNS Bank (De Volksbank) | sns_ |
Triodos Bank | triodos_ |
Van Lanschot | van_ |
Yoursafe | yoursafe |