Checkout Step 4: Choose Payment Provider
In this guide, you'll learn how to implement the last step of the checkout flow, where the customer chooses the payment provider and performs any necessary actions. This is typically the fourth step of the checkout flow, but you can change the steps of the checkout flow as you see fit.
Payment Step Flow in Storefront Checkout#
The payment step requires implementing the following flow:

- Retrieve the payment providers using the List Payment Providers API route.
- Customer chooses the payment provider to use.
- If the cart doesn't have an associated payment collection, create a payment collection for it using the Create Payment Collection API route.
- Initialize the payment sessions of the cart's payment collection using the Initialize Payment Sessions API route.
- If you're using the JS SDK, it combines the third and fourth steps in a single
initiatePaymentSessionfunction.
- If you're using the JS SDK, it combines the third and fourth steps in a single
- Optionally perform additional actions for payment based on the chosen payment provider. For example, if the customer chooses Stripe, you show them the UI to enter their card details.
- You can refer to the Stripe guide for an example of how to implement this.
- If the provider's UI collects details that the provider needs to authorize the payment, such as a payment method ID, pass them to the payment session using the Update Payment Session API route. Learn more in the Update Payment Session Client Data section.
How to Implement the Payment Step Flow#
For example, to implement the payment step flow:
- This example uses the
useCarthook defined in the Cart React Context guide. - Learn how to install and configure the JS SDK in the JS SDK documentation.
In the example above, you:
- Retrieve the payment providers from the Medusa application using the List Payment Providers API route. You use those to show the customer the available options.
- When the customer chooses a payment provider, you use the
initiatePaymentSessionfunction to create a payment collection and initialize the payment session for the chosen provider.- If you're not using the JS SDK, you need to create a payment collection using the Create Payment Collection API route if the cart doesn't have one. Then, you need to initialize the payment session using the Initialize Payment Session API route.
- Once the cart has a payment session, you optionally render the UI to perform additional actions. For example, if the customer chose Stripe, you can show them the card form to enter their credit card.
In the Fetch API example, the handlePayment function implements this flow by calling the different functions in the correct order.
Update Payment Session Client Data#
Some payment providers' checkout components return details that the provider needs to authorize the payment. To pass these details to the payment session, use the JS SDK's updatePaymentSession method, which sends a request to the Update Payment Session API route:
const activePaymentSession = cart.payment_collection?.
payment_sessions?.[0]
const {
payment_collection,
} = await sdk.store.payment.updatePaymentSession(
cart.payment_collection!.id,
activePaymentSession!.id,
{
client_data: {
// data collected by the provider's checkout component
payment_method: "pm_123",
},
}
)
The method accepts the following parameters:
- The ID of the payment collection that the session belongs to.
- The ID of the payment session.
- An object with a
client_dataproperty. Medusa sets its value as the payment session'sdata.clientproperty. The rest of the session'sdatais owned by the payment provider.
The method returns the updated payment collection. You can only update a payment session whose status is pending, requires_more, or error.
Learn more about the payment session's data property in the Payment Session guide.
Troubleshooting#
Unknown Error for Zero Cart Total#
If your cart has a total of 0, you might encounter an unknown error when trying to create a payment session.
Some payment providers, such as Stripe, require a non-zero amount to create a payment session. So, if your cart has a total of , the error will be thrown on the payment provider's side.
In those cases, you can either:
- Make sure the payment session is only initialized when the cart has a total greater than
0. - Use payment providers like the Manual System Payment Provider, which doesn't create a payment session with a third-party provider.
- The Manual System Payment Provider is available by default in Medusa and can be used to handle payments without a third-party provider. It allows you to mark the order as paid without requiring any additional actions from the customer.
- Make sure to configure the Manual System Payment Provider in your store's region. Learn more in the Manage Region user guide.
Stripe Example#
If you're integrating Stripe in your Medusa application and storefront, refer to the Stripe guide for an example of how to handle the payment process using Stripe.