InterWeave Academy

View Categories

Quickstart

Custom payment flow

View the text-based guide

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.

Download full app
Don’t code? Use Stripe’s no-code options or get help from our partners.
1Set up the server

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.

2Build a checkout page on the client

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

3Complete the payment on the client

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.

Scroll to Top