Accept a payment
Customize with the Appearance API. Clone a sample integration from the docs or on GitHub.
If you’re looking for the individual Card Element guide, see Accept a card payment.
You can build a custom payment flow by embedding the Payment Element, which allows you to accept multiple payment methods using a single integration.
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:
Enable payment methods
View your payment methods settings and enable the payment methods you want to support. You need at least one payment method enabled to create a PaymentIntent in the next step. Stripe enables card payments by default so you can skip this step if you want to start with cards only. By default, Stripe enables cards and other prevalent payment methods that can help you reach more customers, but we recommend turning on additional payment methods that are relevant for your business and customers. See the Payment method integration options page for information on product and payment method support, and see our pricing page for fees.
Create a PaymentIntentServer-side
Stripe uses a PaymentIntent object to represent your intent to collect payment from a customer, tracking charge attempts and payment state changes throughout the process.
The payment methods shown to customers during the checkout process are also included on the PaymentIntent. You can let Stripe select enabled payment methods from your Dashboard or you can list them manually. Unless your integration requires that you list payment methods manually, we recommend letting Stripe select payment methods from your Dashboard. This is because 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 customer’s location. For example, if you pass the eur
currency on the PaymentIntent and have OXXO enabled in the Dashboard, the customer won’t see OXXO because OXXO doesn’t support eur
payments.
Each payment method must support the currency passed in the PaymentIntent and your business must operate in one of the countries each payment method supports. See Payment method integration options to understand which payment methods support which currencies.
If you use payment_method_types
instead of automatic_payment_methods
, Stripe returns an error when you specify a payment method type that is not supported in a particular currency.
Included in the returned PaymentIntent is a client secret, which the client side uses to securely complete the payment process instead of passing the entire PaymentIntent object. 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 the payment information to Stripe over an HTTPS connection. The checkout page address must also start with https://
rather than http://
for your integration to work.
You can test your integration without using HTTPS. 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. Depending on their payment method, the form automatically requests that the customer fills in all necessary payment details.
You can customize the Payment Element to match the design of your site by passing the appearance object into options
when creating the Elements
provider.
By default, the Payment Element only collects necessary billing address details. In cases where you need to collect full billing address, like for calculating tax for digital goods and services, you can use the Address Element in Billing mode.
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. |
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 two other events when collecting payments with the Payment Element:
Event | Description | Action |
---|---|---|
payment_intent.succeeded | Sent when a customer has successfully completed a payment. | Send the customer an order confirmation and fulfill their order. |
payment_intent.processing | Sent when a customer successfully initiated a payment, but the payment has yet to complete. This event is most commonly sent when a bank debit is initiated. 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 may want to fulfill the order before waiting for payment to complete. |
payment_intent.payment_failed | Sent when a customer attempted a payment, but the payment failed. | If a payment transitioned 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. Click the tabs below to view details for each payment method.
See also
Now that you’ve finished your integration, you might want to check out these other resources.