www/apps/resources/app/storefront-development/checkout/complete-cart/page.mdx
import { CodeTabs, CodeTab, Prerequisites } from "docs-ui"
export const metadata = {
title: Checkout Step 5: Complete Cart,
}
In this guide, you'll learn how to complete the cart and place the order. This is the last step of your checkout flow.
Once you finish any required actions with the third-party payment provider, you can complete the cart and place the order.
To complete the cart, send a request to the Complete Cart API route. For example:
<Note title="Tip">Learn how to install and configure the JS SDK in the JS SDK documentation.
</Note>sdk.store.cart.complete(cart.id)
.then((data) => {
if (data.type === "cart" && data.cart) {
// an error occurred
console.error(data.error)
} else if (data.type === "order" && data.order) {
// TODO redirect to order success page
alert("Order placed.")
console.log(data.order)
// unset cart ID from local storage
localStorage.removeItem("cart_id")
}
})
In the response of the request, the type field determines whether the cart completion was successful:
type is cart, it means the cart completion failed. The error response field holds the error details.type is order, it means the cart was completed and the order was placed successfully.When the cart completion is successful, it's important to unset the cart ID from the localStorage, as the cart is no longer usable.
<Prerequisites items={[ { text: "Translation Module Configured", link: "/commerce-modules/translation#configure-translation-module", } ]} />
When you complete the cart, items in the order will be in the locale that was set for the cart. This ensures that the customer sees the order details in their preferred language.
If no locale was set for the cart, then the order's items will be in the original product content.
For example, to complete the cart when the default system payment provider is used:
<Note title="Tip">This example uses the useCart hook defined in the Cart React Context guide.
export const highlights = [
["4", "useCart", "The useCart hook was defined in the Cart React Context documentation."],
["11", "handlePayment", "This function sends the request\nto the Medusa application to complete the cart."],
["22", "TODO", "If you're integrating a third-party payment provider,\nyou perform the custom logic before completing the cart."],
["25", "complete", "Send a request to the Medusa application\nto complete the cart and place the order."],
["27", data.type === "cart", "If the type returned is cart,\nit means an error occurred and the cart wasn't completed."],
["30", type === "order", "If the type returned is order,\nit means the cart was completed and the order was placed successfully."],
["34", "refreshCart", "Unset and reset the cart."],
["41", "button", "This button triggers the handlePayment function when clicked."]
]
"use client" // include with Next.js 13+
import { useState } from "react"
import { useCart } from "@/providers/cart"
import { sdk } from "@/lib/sdk"
export default function SystemDefaultPayment() {
const { cart, refreshCart } = useCart()
const [loading, setLoading] = useState(false)
const handlePayment = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault()
if (!cart) {
return
}
setLoading(true)
// TODO perform any custom payment handling logic
// complete the cart
sdk.store.cart.complete(cart.id)
.then((data) => {
if (data.type === "cart" && data.cart) {
// an error occurred
console.error(data.error)
} else if (data.type === "order" && data.order) {
// TODO redirect to order success page
alert("Order placed.")
console.log(data.order)
refreshCart()
}
})
.finally(() => setLoading(false))
}
return (
<button
onClick={handlePayment}
disabled={loading}
>
Place Order
</button>
)
}
In the example above, you create a handlePayment function in the payment component. In this function, you:
type is cart, it means that the cart completion failed. The error is set in the error response field.type is order, it means the card was completed and the order was placed successfully. You can access the order in the order response field.cart_id from the localStorage. You can redirect the customer to an order success page at this point. The redirection logic depends on the storefront framework you're using.Refer to the Stripe guide for an example on integrating a third-party provider and implementing card completion.