<Checkout />
The Checkout
component provides a one-click checkout experience for onchain commerce.
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.
Features
- 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.
Prerequisites
Before using the Checkout
component, ensure you've completed the 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 steps.
Starting a new project
If you're starting a new project, we recommend using create onchain
to scaffold your project.
npm create onchain@latest
Adding to an existing project
If you're adding Checkout
to an existing project, simply install OnchainKit.
npm install @coinbase/onchainkit
Wrap the <OnchainKitProvider />
around your app, following the steps in Getting Started.
Quickstart
Sign up for a Coinbase Commerce account
Head to Coinbase Commerce 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
import { Checkout, CheckoutButton, CheckoutStatus } from '@coinbase/onchainkit/checkout';
<Checkout productId='my-product-id' >
<CheckoutButton coinbaseBranded/> // set coinbaseBranded for branding
<CheckoutStatus />
</Checkout>
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.
Coinbase Commerce charges a 1% fee associated with all payments.
<Checkout productId='my-product-id'>
<CheckoutButton />
</Checkout>
Handling a successful checkout
To handle successful checkouts, use the onStatus
prop to listen for the success
callback.
This callback will return a LifecycleStatusData object including the TransactionReceipt and chargeId
.
For idempotent actions, like rendering your own success screen, you can simply check that the statusName
is equal to success
.
For non-idempotent actions, like order fulfillment, we recommend one of the following approaches to verify a charge has been fully paid.
- (Recommended) Check the status of the
chargeId
using the Coinbase Commerce API. - Set up a Coinbase Commerce Webhook which will notify you for successful payments.
import type { LifecycleStatus } from '@coinbase/onchainkit/checkout';
const statusHandler = async (status: LifecycleStatus) => {
const { statusName, statusData } = status;
switch (statusName) {
case 'success':
// handle success
const { chargeId } = statusData;
// use the charges api to verify the chargeId
const options = {
method: 'GET',
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/${chargeId}`);
}
}
<Checkout onStatus={statusHandler}>
<CheckoutButton />
</Checkout>
Viewing successful checkouts
You can view successful checkouts on the Coinbase Commerce Merchant Dashboard.
Customization
Add name and logo
To customize the name and logo of your application rendered in the popup, set the name
and logo
values inside OnchainKitProvider.
import { OnchainKitProvider } from '@coinbase/onchainkit';
<OnchainKitProvider
chain={base}
config={{
appearance: {
name: 'OnchainKit Playground',
logo: 'https://onchainkit.xyz/favicon/48x48.png?v4-19-24',
},
}}
>
{children}
</OnchainKitProvider>
Add Coinbase branding
You can add Coinbase branding to the component by using the coinbaseBranded
prop on CheckoutButton
.
<Checkout >
<CheckoutButton coinbaseBranded/>
</Checkout>
Disabling the button
You can disable the button using the disabled
prop on CheckoutButton
.
<Checkout >
<CheckoutButton disabled/>
</Checkout>
Customize button
You can customize the button text using the text
prop on CheckoutButton
.
<Checkout >
<CheckoutButton text='Checkout with USDC'/>
</Checkout>
Override styles
We recommend style customization by setting a custom OnchainKit theme. You can also override individual component styles using className
.
<Checkout >
<CheckoutButton className='bg-[#EA580C]'/>
</Checkout>
Advanced Usage
Shopping Carts and Multi-Product Checkout
You can accept payments for arbitrary product metadata using the Coinbase Commerce create 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.
Example server side code
This Typescript example uses Express and Fetch.
// 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);
});
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<string>
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
.
const chargeHandler = async () => {
// Create a charge on your backend server using the Create Charge API
// Replace this URL with your backend endpoint
const res = await fetch('api.merchant.com/createCharge');
const data = await res.json();
return data.id; // Return the chargeId
}
<Checkout chargeHandler={chargeHandler}>
<CheckoutButton />
</Checkout>
Listening to the component lifecycle
You can use our Checkout LifecycleStatus
and the onStatus
prop to listen to transaction states.
import type { LifecycleStatus } from '@coinbase/onchainkit/checkout';
const statusHandler = (status: LifecycleStatus) => {
const { statusName, statusData } = status;
switch (statusName) {
case 'success':
// handle success
case 'pending':
// handle payment pending
case 'error':
// handle error
default:
// handle 'init' state
}
}
<Checkout onStatus={statusHandler}>
<CheckoutButton />
</Checkout>
Example use cases
- Demand-based pricing: Allow users to select seats or ticket types for events, and dynamically calculate charges based on availability and demand.
- Product bundles: Provide users with the option to create custom product bundles, applying discounts or special pricing based on the selected items.
- Freelance Services: Allow clients to specify project details such as hours, deliverables, and deadlines, and generate charges based on these custom inputs.
Components
The components are designed to work together hierarchically. For each component, ensure the following:
<Checkout />
- Sets theproductId
orchargeHandler
prop.<CheckoutButton />
- Branding and customization of the payment button.<CheckoutStatus />
- The status of the payment.