Custom payment flow
Learn how to embed a custom Stripe payment form in your website or application. The client- and server-side code builds a checkout form with Stripe’s Web Elements, letting you complete a payment using several payment methods.
You can use Link in your custom payment form, allowing your customers to securely save and reuse their payment information. To learn more, see Link with Elements.
Install the Stripe Ruby library
Install the Stripe ruby gem and require it in your code. Alternatively, if you’re starting from scratch and need a Gemfile, download the project files using the link in the code editor.
Create a PaymentIntent
Add an endpoint on your server that creates a PaymentIntent. A PaymentIntent tracks the customer’s payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent’s client secret in the response to finish the payment on the client.
Configure payment methods
We enable cards and other common payment methods by default. You can enable or disable payment methods directly in the Dashboard. Before displaying the payment form, Stripe evaluates the currency, payment method restrictions, and other parameters to determine the list of supported payment methods. We prioritize payment methods that help increase conversion and are most relevant to the currency and the customer’s location.
Load Stripe.js
Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from js.stripe.com to remain compliant. Don’t include the script in a bundle or host it yourself.
Define the payment form
Add one empty placeholder div
to your checkout form for each Element that you’ll mount. Stripe inserts an iframe into each div
to securely collect the customer’s email address and payment information.
Initialize Stripe.js
Initialize Stripe.js with your publishable API keys. You’ll use Stripe.js to create the Payment Element and complete the payment on the client.
Fetch a PaymentIntent
Immediately make a request to the endpoint on your server to create a new PaymentIntent as soon as your checkout page loads. The clientSecret
returned by your endpoint is used to complete the payment.
Initialize Stripe Elements
Initialize the Stripe Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
Create the PaymentElement
Create a PaymentElement and mount it to the placeholder <div>
in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the PaymentIntent, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.
(Optional) Style the Payment Element
Customize the Payment Element UI by creating an appearance object and initializing Elements with it. Use your company’s color scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initializing Elements with a font set.
Make sure to open the preview on the right to see your changes live
Handle the submit event
Listen to the form’s submit event to know when to confirm the payment through the Stripe API.
Complete the payment
Call confirmPayment()
, passing along the PaymentElement and a return_url to indicate where Stripe should redirect the user after they complete the payment. For payments that require authentication, Stripe displays a modal for 3D Secure authentication or redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they’re redirected to the return_url
.
Handle errors
If there are any immediate errors (for example, your customer’s card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.
Show a payment status message
When Stripe redirects the customer to the return_url
, the payment_intent_client_secret
query parameter is appended by Stripe.js. Use this to retrieve the PaymentIntent to determine what to show to your customer.
Use a webhook
Stripe sends multiple events during the payment process and after the payment is complete. Use the Dashboard webhook tool or follow the webhook guide 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. Stripe recommends handling the payment_intent.succeeded, payment_intent.processing, and payment_intent.payment_failed events.
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 is what enables you to accept different types of payment methods with a single integration.