Skip to content

<Checkout />

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.

Checkout

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.
  • 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 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
npm install @coinbase/onchainkit

Wrap the <OnchainKitProvider /> around your app, following the steps in Getting Started.

Quickstart

Option 1: Simple Product Checkout

Ideal for fixed-price items. Get started with minimal setup.

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>

Option 2: Dynamic Charges

For variable pricing, custom metadata, or multi-product checkouts, use backend-generated charges.

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 Coinbase Commerce API Key

In the Coinbase Commerce dashboard, 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 for a code example.

Pass the chargeID into Checkout via the chargeHandler prop.

const chargeHandler = async () => {
  const response = await fetch('/createCharge', { method: 'POST' });
  const { id } = await response.json();
  return id; // Return charge ID
};
 
<Checkout chargeHandler={chargeHandler}>
  <CheckoutButton />
</Checkout>

That's it! Start selling onchain with just a few lines of code.

Usage

Configuring a checkout

Using productId

You can create products on the Coinbase Commerce Portal and use them in the Checkout component through the productId prop.

<Checkout productId='my-product-id'>
  <CheckoutButton />
</Checkout>
 

Using chargeHandler

Alternatively, you can create charges dynamically using the Coinbase Commerce API Create Charge endpoint by passing the chargeID into Checkout via the chargeHandler prop.

This function must have the signature () => Promise<string> and must return a valid chargeId created by the create charge endpoint.

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);
});
 

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.

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.

  1. (Recommended) Check the status of the chargeId using the Coinbase Commerce API.
  2. 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.

Viewing successful checkouts

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.

providers.tsx
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 name and logo

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

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 the productId or chargeHandler prop.
  • <CheckoutButton /> - Branding and customization of the payment button.
  • <CheckoutStatus /> - The status of the payment.

Props