Overview

The latest version of Crossmint’s Pay Button, Pay Button V3, introduces a powerful new architecture focused on simplicity and developer experience. Migrating your existing Pay Button integration is straightforward and can typically be completed in under 15 minutes. This guide will walk you through each step.

Which Version Am I Using?

Pay Button has two versions - V2 and V3, each using its own distinct component:
  • V3: The new <CrossmintHostedCheckout /> component with React Context providers
  • V2: The legacy <CrossmintPayButton /> component
The Pay Button V3 component is available in @crossmint/client-sdk-react-ui@1.12.0 and above. Make sure to update your dependencies to the latest version.

What’s New in V3?

Better DX

React hooks, TypeScript support, and simpler APIs

Enhanced Multiple Items

Improved API for multiple NFTs with individual delivery tracking and better developer experience

Enhanced UI

More customization options and better payment method support

Key Changes

Pay Button V3 introduces several significant improvements and new capabilities:
  1. Simpler Developer Experience: More intuitive and idiomatic component API - less code, easier to understand
  2. Built-in Order Management: Complete order status UI out of the box - no more manual event handling (but fully customizable if needed)
  3. React Hooks for State Management: Replace event listeners with hooks for better control over the order lifecycle and checkout state
  4. Enhanced Multi-Item Support: Improved API for selling multiple NFTs with better individual delivery tracking for each item
  5. Better UI Customization: Includes more UI customization options - now you can control every aspect of the checkout’s appearance
  6. Advanced Cross-chain Support: Streamlined payment flows with expanded cross-chain capabilities

Component Renaming

The main checkout component has been renamed from CrossmintPayButton to CrossmintHostedCheckout to better reflect its purpose and capabilities. This component now supports multiple line items, advanced payment methods, and enhanced UI customization.

Provider Architecture

The new Pay Button V3 uses React Context providers to manage state and configuration. The CrossmintProvider handles API authentication and environment setup using a client-side API key (more details in Step 1), while CrossmintCheckoutProvider manages order state and checkout flow.
<CrossmintProvider apiKey="_YOUR_CLIENT_API_KEY_">
    <CrossmintCheckoutProvider>
        <CrossmintHostedCheckout />
    </CrossmintCheckoutProvider>
</CrossmintProvider>

Property Updates

Key property changes in Pay Button V3:
  • projectId and environment are no longer needed
  • You now specify which items to buy using lineItems, an array of items that support both collectionLocator (for primary sales with formats "crossmint:${collectionId}" or ${chain}:${contractAddress}) and tokenLocator (for secondary sales with the format ${chain}:${contractAddress}:${tokenId}). Each item includes callData that takes the same object previously passed to mintConfig - see our Item Selection guide for detailed examples
  • Replaces uiConfig with appearance - see our UI Customization guide
  • Determines environment automatically from your API key
  • Replaces event handlers with React hooks - see our Hooks guide

React Hooks for State Management

Events have been replaced with React hooks, providing better TypeScript support and a more intuitive development experience:
// Old - Event-based system
<CrossmintPayButton
    onEvent={(event) => {
        if (event.type === "payment:process.succeeded") {
            console.log("Payment successful!");
        }
    }}
/>;

// New - Hook-based system
function Checkout() {
    const { order } = useCrossmintCheckout();

    useEffect(() => {
        if (order && order.phase === "completed") {
            console.log("Purchase complete!");
        }
    }, [order]);

    return <CrossmintHostedCheckout {...props} />;
}

Enhanced Multiple Line Items Support

While V2 supported multiple items through quantity parameters and mintConfig arrays, Pay Button V3 introduces a more intuitive lineItems approach for checking out multiple items at once from the same collection for primary sales. Each line item can have different quantities and prices, with individual delivery status tracking:
<CrossmintHostedCheckout
    lineItems={[
        {
            collectionLocator: `crossmint:${collectionId}`,
            callData: {
                totalPrice: "0.001",
                quantity: 1,
            },
        },
        {
            collectionLocator: `crossmint:${collectionId}`,
            callData: {
                totalPrice: "0.002",
                quantity: 1,
            },
        },
    ]}
    payment={{
        crypto: { enabled: true },
        fiat: { enabled: true },
    }}
/>
Learn more about configuring your Pay Button in our guides:

Migration Steps

1. Get a Client API Key

Create a client-side API key with the orders.create scope enabled. More info on creating API keys here.

2. Update Dependencies

Upgrade the Crossmint React SDK to version 1.12.0 or above.
npm install @crossmint/client-sdk-react-ui@latest

3. Update Import Statements

// Old
import { CrossmintPayButton } from "@crossmint/client-sdk-react-ui";

// New
import { CrossmintProvider, CrossmintHostedCheckout } from "@crossmint/client-sdk-react-ui";

4. Update Environment Variables

Change your Crossmint environment variables (e.g. in your .env.local file or Vercel configuration):
# Old
NEXT_PUBLIC_PROJECT_ID="_YOUR_PROJECT_ID_" # No longer needed - derived from the API key
NEXT_PUBLIC_COLLECTION_ID="_YOUR_COLLECTION_ID_"
NEXT_PUBLIC_ENVIRONMENT="staging"          # No longer needed - derived from the API key

# New
NEXT_PUBLIC_CLIENT_API_KEY="_YOUR_CLIENT_API_KEY_"    # From API Keys page
NEXT_PUBLIC_COLLECTION_ID="_YOUR_COLLECTION_ID_"      # From Collection details page
The projectId and environment values are now automatically derived from the client-side API key.

5. Update Component Structure

Replace your V2 Pay Button with the new V3 component structure:
// Old - V2
<CrossmintPayButton
    projectId={projectId}
    collectionId={collectionId}
    environment={environment}
    mintConfig={{
        totalPrice: "0.001",
        quantity: 1,
    }}
/>

// New - V3
<CrossmintProvider apiKey={clientApiKey}>
    <CrossmintHostedCheckout
        lineItems={{
            collectionLocator: `crossmint:${collectionId}`,
            callData: {
                totalPrice: "0.001",
                quantity: 1,
            },
        }}
        payment={{
            crypto: { enabled: true },
            fiat: { enabled: true },
        }}
    />
</CrossmintProvider>

Advanced Features

Once you have the basic setup working, V3 now supports these additional features:

Payment Methods

Enable crypto and fiat payment options, and set preferred chains and currencies for your users. Learn more in our Payment Methods guide.
payment={{
    crypto: {
        enabled: true,
        defaultChain: "polygon",
    },
    fiat: {
        enabled: true,
        allowedMethods: {
            card: true,
            applePay: true,
            googlePay: true,
        }
    }
}}

UI Customization

Customize the appearance of your Pay Button and checkout experience. Learn more in our UI Customization guide.
appearance={{
    theme: {
        checkout: "light",    // "light" | "dark"
        button: "crossmint"   // "light" | "dark" | "crossmint"
    },
    variables: {
        colors: {
            accent: "#FF0000"  // Your brand color
        }
    },
    display: "popup",         // "popup" | "new-tab" | "same-tab"
    overlay: {
        enabled: true         // Whether to show overlay in popup mode
    }
}}
Pay Button V3 offers a streamlined appearance configuration focused on essential branding and display options. For more advanced customization needs, consider using our Embedded Checkout solution.

Order Tracking

Pay Button V3 now makes it easier to track order status using React hooks. Learn more in our React hooks guide.
import {
    CrossmintProvider,
    CrossmintCheckoutProvider,
    CrossmintHostedCheckout,
    useCrossmintCheckout,
} from "@crossmint/client-sdk-react-ui";

const clientApiKey = process.env.NEXT_PUBLIC_CLIENT_API_KEY;
const collectionId = process.env.NEXT_PUBLIC_COLLECTION_ID;

function Checkout() {
    const { order } = useCrossmintCheckout();

    useEffect(() => {
        if (order && order.phase === "completed") {
            console.log("Purchase completed!");
            // Handle successful purchase
        }
    }, [order]);

    return (
        <CrossmintHostedCheckout
            lineItems={[
                {
                    collectionLocator: `crossmint:${collectionId}`,
                    callData: {
                        totalPrice: "0.001",
                        quantity: 1,
                    },
                },
            ]}
            payment={{
                crypto: { enabled: true },
                fiat: { enabled: true },
            }}
        />
    );
}

// Wrap with both providers
function App() {
    return (
        <CrossmintProvider apiKey={clientApiKey}>
            <CrossmintCheckoutProvider>
                <Checkout />
            </CrossmintCheckoutProvider>
        </CrossmintProvider>
    );
}

Payment Configuration

Payment method configuration has been simplified in V3:
// Old - V2
<CrossmintPayButton
    checkoutProps={{
        paymentMethods: ["ETH", "fiat"],
    }}
/>

// New - V3
<CrossmintHostedCheckout
    payment={{
        crypto: {
            enabled: true,
            defaultChain: "polygon", // Optional: Set default blockchain
            defaultCurrency: "eth"   // Optional: Set default crypto currency
        },
        fiat: {
            enabled: true,
            defaultCurrency: "usd"   // Optional: Set default fiat currency
        },
        defaultMethod: "fiat"       // Optional: Set default payment method
    }}
/>
Unlike Embedded Checkout, Pay Button V3 does not support configuring individual payment methods (like disabling specific card types or wallets). All payment methods are enabled when you enable fiat or crypto payments.

Complete Example

A complete example combining all features:
<CrossmintProvider apiKey={clientApiKey}>
    <CrossmintHostedCheckout
        lineItems={{
            collectionLocator: `crossmint:${collectionId}`,
            callData: {
                totalPrice: "0.001",
                quantity: 1,
            },
        }}
        payment={{
            crypto: {
                enabled: true,
                defaultChain: "polygon",
                defaultCurrency: "eth",
            },
            fiat: {
                enabled: true,
                defaultCurrency: "usd",
            },
            defaultMethod: "fiat",
            receiptEmail: "buyer@example.com",
        }}
        appearance={{
            theme: {
                checkout: "light", // "light" | "dark"
                button: "crossmint", // "light" | "dark" | "crossmint"
            },
            variables: {
                colors: {
                    accent: "#FF0000",
                },
            },
            display: "popup", // "popup" | "new-tab" | "same-tab"
            overlay: {
                enabled: true,
            },
        }}
    />
</CrossmintProvider>