diff --git a/site/docs/pages/checkout/checkout.mdx b/site/docs/pages/checkout/checkout.mdx
index 527dd058ef..0dcf8ba474 100644
--- a/site/docs/pages/checkout/checkout.mdx
+++ b/site/docs/pages/checkout/checkout.mdx
@@ -8,7 +8,7 @@ import App from '../../components/App';
# ``
-The `Checkout` component provides a one-click checkout experience for onchain commerce.
+The `Checkout` component provides a one-click checkout experience for onchain commerce - all for free.
Our all-in-one solution simplifies payment processing for onchain developers, removing complex integrations, high fees, and onboarding friction. Whether you're selling digital goods, services, or in-game items, this tool is for you.
@@ -20,12 +20,15 @@ Our all-in-one solution simplifies payment processing for onchain developers, re
- **Plug-and-Play Integration:** Add our `Checkout` button with just a few lines of code. No backend required.
- **Seamless Onboarding:** Support Passkey wallets to eliminate onboarding drop-offs.
- **Real-time Merchant Tooling:** Get instant payment tracking, analytics, and reporting.
+- **Dynamic Payment Flows:** Generate charges on the fly, handle variable pricing, and pass in custom metadata.
## Prerequisites
Before using the `Checkout` component, ensure you've completed the [Getting Started](/getting-started) steps.
-To use the `Checkout` component, you'll need to provide an API Key in `OnchainKitProvider`. You can get one following our [Getting Started](/getting-started#get-your-public-api-key) steps.
+::::tip
+To use the `Checkout` component, you'll need to provide a Client API Key in `OnchainKitProvider`. You can get one following our [Getting Started](/installation/nextjs#get-your-client-api-key) steps.
+:::::
### Starting a new project
@@ -63,18 +66,15 @@ Wrap the `` around your app, following the steps in [Getti
## Quickstart
+### Option 1: Simple Product Checkout
+Ideal for fixed-price items. Get started with minimal setup.
+
::::steps
### Sign up for a Coinbase Commerce account
-
Head to [Coinbase Commerce](https://beta.commerce.coinbase.com/) and sign up. This is where you’ll manage transactions, view reports, and configure payments.
### Create a product and copy the `productId`
-
In the Coinbase Commerce dashboard, create a new product and copy the `productId`.
### Import the component
@@ -89,17 +89,44 @@ import { Checkout, CheckoutButton, CheckoutStatus } from '@coinbase/onchainkit/c
```
::::
+### Option 2: Dynamic Charges
+For variable pricing, custom metadata, or multi-product checkouts, use backend-generated charges.
+
+::::steps
+
+### Sign up for a Coinbase Commerce account
+Head to [Coinbase Commerce](https://beta.commerce.coinbase.com/) and sign up. This is where you’ll manage transactions, view reports, and configure payments.
+
+### Create a Coinbase Commerce API Key
+In the [Coinbase Commerce dashboard](https://beta.commerce.coinbase.com/settings/security), create a new API Key under `Security` in `Settings`.
+
+### Set up a backend to create charges dynamically using the Coinbase Commerce API.
+See [Using chargeHandler](/checkout/checkout#using-chargehandler) for a code example.
+
+### Pass the chargeID into Checkout via the chargeHandler prop.
+
+```tsx
+const chargeHandler = async () => {
+ const response = await fetch('/createCharge', { method: 'POST' });
+ const { id } = await response.json();
+ return id; // Return charge ID
+};
+
+
+
+
+```
+::::
+
That's it! Starting selling onchain with just a few lines of code.
## Usage
### Configuring a checkout
-You can create products on the Coinbase Commerce Portal and use them in the `Checkout` component through the `productId` prop.
-
-If you'd like to create product metadata programmatically or implement a multi-product checkout, please see [Advanced Usage](/checkout/checkout#advanced-usage).
+#### Using `productId`
-Coinbase Commerce charges a [1% fee](https://help.coinbase.com/en/commerce/getting-started/fees) associated with all payments.
+You can create products on the Coinbase Commerce Portal and use them in the `Checkout` component through the `productId` prop.
```tsx twoslash
import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout';
@@ -121,6 +148,63 @@ export default function PayComponents() {
+#### Using `chargeHandler`
+
+Alternatively, you can create charges dynamically using the Coinbase Commerce API [Create Charge](https://docs.cdp.coinbase.com/commerce-onchain/reference/creates-a-charge) endpoint by passing the chargeID into Checkout via the `chargeHandler` prop.
+
+This function must have the signature `() => Promise` and must return a valid chargeId created by the create charge endpoint.
+
+:::tip
+To create charges, you'll need a Coinbase Commerce [API Key](https://docs.cdp.coinbase.com/commerce-onchain/docs/getting-started).
+:::
+
+:::danger[⚠️ Warning]
+You should protect your Coinbase Commerce API Key by only creating charges server-side.
+:::
+
+:::code-group
+```ts [backend.ts]
+// This backend endpoint should create a charge and return the response.
+app.post('/createCharge', async (req: Request, res: Response) => {
+ const options = {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ 'X-CC-Api-Key': 'your_api_key_here' // Replace this with your Coinbase Commerce API Key
+ },
+ body: JSON.stringify({
+ local_price: { amount: '1', currency: 'USDC' },
+ pricing_type: 'fixed_price',
+ metadata: { some_field: "some_value" } // Optional: Attach metadata like order ID or customer details
+ }),
+ };
+
+ const response = await fetch('https://api.commerce.coinbase.com/charges', options);
+ const data = await response.json();
+
+ res.json(data);
+});
+
+```
+
+```tsx twoslash [frontend.tsx]
+import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout';
+
+const chargeHandler = async () => {
+ const response = await fetch('https://your-backend.com/createCharge', { method: 'POST' });
+ const { id } = await response.json();
+ return id; // Return charge ID
+};
+
+
+
+
+```
+:::
+
+Note that `productId` and `chargeHandler` are mutually exclusive and only one can be provided as a prop to Checkout.
+
### Handling a successful checkout
To handle successful checkouts, use the `onStatus` prop to listen for the `success` callback.
@@ -163,8 +247,8 @@ const statusHandler = async (status: LifecycleStatus) => { // [!code focus]
// ---cut-after---
```
-:::tip[Coinbase Commerce API]
-This is an authenticated endpoint. To verify charges, you'll need a Coinbase Commerce [API Key](https://docs.cdp.coinbase.com/commerce-onchain/docs/getting-started).
+:::tip
+To verify charges, you'll need a Coinbase Commerce [API Key](https://docs.cdp.coinbase.com/commerce-onchain/docs/getting-started).
:::
:::danger[⚠️ Warning]
@@ -313,80 +397,6 @@ export default function PayComponents() {
## Advanced Usage
-### Shopping Carts and Multi-Product Checkout
-
-You can accept payments for arbitrary product metadata using the Coinbase Commerce [create charge](https://docs.cdp.coinbase.com/commerce-onchain/reference/creates-a-charge) endpoint. This is useful if you have an existing inventory management system or want to implement custom features like multi-product checkouts, carts, etc.
-
-:::tip[Coinbase Commerce API]
-This is an authenticated endpoint. To create charges, you'll need a Coinbase Commerce [API Key](https://docs.cdp.coinbase.com/commerce-onchain/docs/getting-started).
-:::
-
-#### Example server side code
-
-This Typescript example uses [Express](https://expressjs.com/) and [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
-
-```tsx twoslash [server.ts]
-import express, { Request, Response } from 'express';
-const fetch = require('node-fetch');
-
-const app = express();
-const port = 3000;
-
-app.use(express.json());
-
-// ---cut-before---
-// This endpoint should create a charge and return the response.
-app.post('/createCharge', async (req: Request, res: Response) => {
- const options = {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Accept': 'application/json',
- 'X-CC-Api-Key': 'your_api_key_here' // Replace this with your Coinbase Commerce API Key
- }
- };
-
- const response = await fetch('https://api.commerce.coinbase.com/charges', options);
- const data = await response.json();
-
- res.json(data);
-});
-// ---cut-after---
-app.listen(port, () => {
- console.log(`Server running at http://localhost:${port}`);
-});
-```
-
-:::danger[⚠️ Warning]
-Charges should only be created server-side. If you create charges on the client, users will be able to create charges associated with your Commerce Merchant account.
-:::
-
-We expose a `chargeHandler` prop on the `Checkout` component which takes a callback that is invoked every time the Checkout button is clicked.
-
-This function **must** have the signature `() => Promise` and **must** return a valid `chargeId` created by the create charge endpoint.
-
-Note that `productId` and `chargeHandler` are mutually exclusive and only one can be provided as a prop to `Checkout`.
-
-```tsx twoslash
-import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout';
-
-
-// ---cut-before---
-const chargeHandler = async () => { // [!code focus]
- // Create a charge on your backend server using the Create Charge API // [!code focus]
- // Replace this URL with your backend endpoint // [!code focus]
- const res = await fetch('api.merchant.com/createCharge'); // [!code focus]
- const data = await res.json(); // [!code focus]
- return data.id; // Return the chargeId // [!code focus]
-} // [!code focus]
-
- // [!code focus]
-
-
-// ---cut-after---
-```
-
-
### Listening to the component lifecycle
You can use our Checkout [`LifecycleStatus`](/checkout/types#lifecyclestatus) and the `onStatus` prop to listen to transaction states.