Overview

By default, Embedded checkout includes wallet connector UI. However, if your customers have already connected their wallet to your website, you can configure that connected wallet directly as the payer. This is useful when:
  • You’re already using a wallet connection solution (like RainbowKit, Solana Wallet Adapter, Web3Modal, or ConnectKit)
  • You are using embedded wallets (from Crossmint or other providers)

Quick Integration

Here’s a simple example using wagmi, viem and TanStack Query:
Make sure you have this environment variables on .env.local or directly replace it in the code bash NEXT_PUBLIC_CLIENT_API_KEY="__YOUR_CLIENT_KEY__" # From API Keys page NEXT_PUBLIC_RECIPIENT_WALLET_ADDRESS="" # Address receiving the assets NEXT_PUBLIC_RECEIPT_EMAIL="user@example.com" NEXT_PUBLIC_COLLECTION_ID="__YOUR_COLLECTION_ID__" # From Collection details page
import { CrossmintEmbeddedCheckout } from "@crossmint/client-sdk-react-ui";
import { Hex, parseTransaction } from "viem";
import { useAccount, useWalletClient } from "wagmi";
import { baseSepolia, polygonAmoy } from "wagmi/chains";

export default function Checkout() {
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();
  const collectionId = process.env.NEXT_PUBLIC_COLLECTION_ID as string;

const chainIds: Record<string, number> = {
"base-sepolia": baseSepolia.id,
"polygon-amoy": polygonAmoy.id,
} as const;

// Don't render checkout if wallet is not connected
if (!address || !walletClient) {
return (
<div className="flex flex-col items-center justify-center p-6">
<h2 className="text-xl text-gray-600 mb-4">Please connect your wallet to continue</h2>
</div>
);
}

return (
<CrossmintEmbeddedCheckout
locale="es-ES"
recipient={{
        walletAddress: process.env.NEXT_PUBLIC_RECIPIENT_WALLET_ADDRESS ?? "",
      }}
payment={{
crypto: {
// Enable crypto payment, this example only uses Crypto
enabled: true,
payer: {
address,
initialChain: "base-sepolia",
supportedChains: ["base-sepolia", "polygon-amoy"],
handleChainSwitch: async (chain) => {
await walletClient.switchChain({
id: chainIds[chain],
});
},
handleSignAndSendTransaction: async (serializedTx) => {
try {
const tx = parseTransaction(serializedTx as Hex);
const hash = await walletClient.sendTransaction({
to: tx.to,
value: tx.value,
data: tx.data ?? "0x",
gas: tx.gas,
chainId: tx.chainId,
});

                return { success: true, txId: hash };
              } catch (error) {
                return {
                  success: false,
                  errorMessage: error instanceof Error ? error.message : "Transaction failed",
                };
              }
            },
          },
        },
          fiat: { enabled: false },
          receiptEmail: process.env.NEXT_PUBLIC_RECEIPT_EMAIL ?? "",
      }}
      lineItems={{
        collectionLocator: `crossmint:${collectionId}`,
        callData: {
          quantity: 1,
        }
      }}
    />

)
}

When the user clicks the hosted checkout button, our SDK will first call handleChainSwitch to ensure the correct network is set, then handleSignAndSendTransaction to complete the purchase.

Payer Configuration

The payer prop accepts the following configuration:
PropertyTypeDescription
addressstringThe wallet address of the payer
initialChainPayerSupportedBlockchainsThe initial blockchain (e.g. “polygon”, “ethereum”, “base-sepolia”)
supportedChainsPayerSupportedBlockchains[]Optional list of supported chains. Defaults to initialChain if not specified
handleChainSwitch(chain: PayerSupportedBlockchains) => Promise<void>Function to handle chain switching
handleSignAndSendTransaction(serializedTx: string) => Promise<TransactionResponse>Function to handle transaction signing and sending, where TransactionResponse is either { success: true, txId: string } or { success: false, errorMessage: string }
You can integrate Crossmint with popular Web3 solutions:

RainbowKit

import { useConnectModal } from "@rainbow-me/rainbowkit";

// Similar implementation as above, but using RainbowKit's hooks

Web3Modal

import { useWeb3Modal } from "@web3modal/react";

// Similar implementation as above, but using Web3Modal's hooks

Best Practices

  1. Error Handling: Always return clear error messages in handleSignAndSendTransaction
  2. Chain Support: Be explicit about supported chains to avoid runtime errors
  3. User Experience: Show loading states during chain switches and transactions
  4. Wallet Connection: Ensure wallet is connected before showing checkout