Accept a payment
Build a custom payments integration by embedding UI components on your site, using Stripe Elements. See how this integration compares to Stripe’s other integration types.
The client-side and server-side code builds a checkout form that accepts various payment methods.
Integration effort
Integration type
Combine UI components into a custom payment flow
UI customization
CSS-level customization with the Appearance API
Interested in using Stripe Tax, Discounts, and/or Automatic Currency Conversion?
We’re developing a new Payment Element integration that manages tax, discounts, and international currencies. To request early access, click here.
Set up StripeServer-side
First, create a Stripe account or sign in.
Use our official libraries to access the Stripe API from your application:
Create a PaymentIntentServer-side
Note
If you want to render the Payment Element without first creating a PaymentIntent, see Collect payment details before creating an Intent.
The PaymentIntent object represents your intent to collect payment from a customer and tracks charge attempts and state changes throughout the payment process.
Create the PaymentIntent
Create a PaymentIntent on your server with an amount and currency. In the latest version of the API, specifying the automatic_payment_methods
parameter is optional because Stripe enables its functionality by default. You can manage payment methods from the Dashboard. Stripe handles the return of eligible payment methods based on factors such as the transaction’s amount, currency, and payment flow.
Stripe uses your payment methods settings to display the payment methods you have enabled. To see how your payment methods appear to customers, enter a transaction ID or set an order amount and currency in the Dashboard. To override payment methods, manually list any that you want to enable using the payment_method_types attribute.
In the latest version of the API, specifying the automatic_payment_methods
parameter is optional because Stripe enables its functionality by default.
Note
Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.
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 detailsClient-side
You’re ready to collect payment details on the client with the Payment Element. The Payment Element is a prebuilt 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. If you do choose to use an iframe and want to accept Apple Pay or Google Pay, the iframe must have the allow attribute set to equal "payment *"
.
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.
The Payment Element renders a dynamic form that allows your customer to pick a payment method. For each payment method, the form automatically asks the customer to fill in all necessary payment details.
Customize appearance
Customize the Payment Element to match the design of your site by passing the appearance object into options
when creating the Elements
provider.
Collect addresses
By default, the Payment Element only collects the necessary billing address details. To collect a customer’s full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
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, like a bank authorization page, before being redirected to the return_url
. Card payments immediately redirect to the return_url
when a payment is successful.
If you don’t want to redirect for card payments after payment completion, you can set redirect to if_required
. This only redirects customers that check out with redirect-based payment methods.
Make sure the return_url
corresponds to a page on your website that provides the status of the payment. When Stripe redirects the customer to the return_url
, we provide the following URL query parameters:
Parameter | Description |
---|---|
payment_intent | The unique identifier for the PaymentIntent . |
payment_intent_client_secret | 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.com
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_url
, which persist through the redirect process.
Handle post-payment eventsServer-side
Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard webhook tool or follow the webhook guide to receive these events and run actions, such as 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 is what enables you to accept different types of payment methods with a single integration.
In addition to handling the payment_intent.succeeded
event, we recommend handling these other events when collecting payments with the Payment Element:
Event | Description | Action |
---|---|---|
payment_intent.succeeded | Sent when a customer successfully completes a payment. | Send the customer an order confirmation and fulfill their order. |
payment_intent.processing | Sent when a customer successfully initiates a payment, but the payment has yet to complete. This event is most commonly sent when the customer initiates a bank debit. It’s followed by either a payment_intent.succeeded or payment_intent.payment_failed event in the future. | Send the customer an order confirmation that indicates their payment is pending. For digital goods, you might want to fulfill the order before waiting for payment to complete. |
payment_intent.payment_failed | Sent when a customer attempts a payment, but the payment fails. | If a payment transitions from processing to payment_failed , offer the customer another attempt to pay. |
Test the integration
Use test payment details and the test redirect page to verify your integration. The following table contains some basic test scenarios. For detailed information about testing payments, see Testing.