This guide will show you how to accept credit card payments using Crossmint’s Embedded Checkout or Headless Checkout API for memecoin sales with Checkout.com as the payment provider. You’ll learn how to:
Set up credit card payments for Solana memecoin purchases in JavaScript
Implement a checkout UI using Checkout.com’s Flow component
Track order status and delivery
You can jump to the sections on the right toolbar to get integrate with either:
Crossmint runs compliance checks on all tokens to ensure they do not qualify as securities or currencies under
applicable regulations. Transactions for tokens that are determined to be too similar to securities or
currencies will fail.
Supported Tokens
Currently, memecoin checkout only supports Solana network. If you’re an enterprise customer, you can check which
tokens are supported by using the fungibleCheckoutAvailable endpoint, or reach out to support for an updated
list of supported tokens.
Delivery to External Wallets Only
Memecoin checkout only delivers memecoins to EOAs (Externally Owned Accounts), not Crossmint supported delivery
solutions, such as on-the-fly wallet creation (both Crossmint
custodial wallets and smart wallet), delivery Twitter handle, etc.
Merchant of Record
Crossmint remains the merchant of record for all transactions. Your buyers will still receive delivery
receipts and transaction
confirmations from Crossmint.
To define which fungible token you’d like to purchase, you’ll need to specify the tokenLocator in the tokenLocator format: solana:${tokenMintHash} (tokenMintHash is commonly known as contract address, CA, or mint hash).
Before implementing the checkout, note these key parameters:
maxSlippageBps: Optional slippage tolerance (default provided if not specified)
receiptEmail: Required for delivering payment receipts
executionParameters.mode: Set to “exact-in” for memecoin purchases (specifies exact USD amount to spend). Exact-out is for NFT’s, exact-in is for fungibles.
This guide will start from scratch with an empty Next.js application. You'll install the required @crossmint/client-sdk-react-ui dependency and add the embedded checkout component. To get started:
If you see this message, type y and press Enter to proceed:
Copy
Ask AI
Need to install the following packages: create-next-app@latestOk to proceed? (y)
2
Name your app `crossmint-embedded-checkout-demo` and accept the default options
Copy
Ask AI
What is your project named? crossmint-embedded-checkout-demoWould you like to use TypeScript? YesWould you like to use ESLint? YesWould you like to use Tailwind CSS? YesWould you like to use `src/` directory? NoWould you like to use App Router? (recommended) YesWould you like to customize the default import alias? No
3
Change into the directory created in previous steps
Next, we will set up a project file with Crossmint’s embedded checkout to accept memecoin purchases.
1
Add environment variables
Create .env.local in your project root:
Copy
Ask AI
NEXT_PUBLIC_CLIENT_API_KEY="_YOUR_CLIENT_API_KEY_" # From API Keys pageNEXT_PUBLIC_TOKEN_ADDRESS="6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN" # Instead of a collectionId, we will use a token address. In this case, $trumps contract addressNEXT_PUBLIC_RECIPIENT_WALLET_ADDRESS="YOUR_SOLANA_WALLET_ADDRESS" # Add desired recipient walletNEXT_PUBLIC_RECEIPT_EMAIL="YOUR_EMAIL" # Add desired recipient email
2
Create the checkout page
Create /src/app/page.tsx with:
Copy
Ask AI
"use client";import { CrossmintProvider, CrossmintEmbeddedCheckout } from "@crossmint/client-sdk-react-ui";export default function Home() { const clientApiKey = process.env.NEXT_PUBLIC_CLIENT_API_KEY as string; const tokenAddress = process.env.NEXT_PUBLIC_TOKEN_ADDRESS as string; const recipientWalletAddress = process.env.NEXT_PUBLIC_RECIPIENT_WALLET_ADDRESS as string; return ( <div className="flex flex-col items-center justify-start h-screen p-6 bg-white"> <CrossmintProvider apiKey={clientApiKey}> <div className="max-w-[450px] w-full"> <CrossmintEmbeddedCheckout recipient={{ walletAddress: recipientWalletAddress, // Wallet address to receive the memecoins }} lineItems={{ tokenLocator: `solana:${tokenAddress}`, // Token address in format solana:tokenAddress (e.g., solana:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN for TRUMP token) executionParameters: { mode: "exact-in", // The execution method for the order. It tells Crossmint to operate in buying fungibles mode amount: "5", // Amount in USD maxSlippageBps: "500" // Optional - default slippage will be applied if not specified } }} payment={{ receiptEmail: process.env.NEXT_PUBLIC_RECEIPT_EMAIL as string, // Email address to receive the receipt crypto: { enabled: false, // Only fiat is supported for memecoin purchases }, fiat: { enabled: true, }, defaultMethod: "fiat", }} /> </div> </CrossmintProvider> </div> );}
3
Run your app
Copy
Ask AI
npm run dev
Visit http://localhost:3000 to see your checkout!
4
Test your app
Memecoin purchases are only supported in production, so pay with credit card in a small amount to test the flow.
Here’s how your embedded checkout will look after implementation:
🎉 Congratulations! You’ve successfully set up your embedded memecoin checkout. Check out the Next Steps section below to learn how to customize your integration.
The first step in the headless checkout process is to create an order. An order is an object datastructure, that represents an intent to purchase in Crossmint’s systems. This guide will create a basic order, and then update it with required info step-by-step.
You can also create the entire order in one API call if the necessary information is available at the time of order
creation. This can be used for custom “one-click-checkout” experiences, should you wish to make them.
Refer to the complete create order API reference here.
Important: Memecoin purchases can only be processed in the production environment, not in staging.
Use the javascript code snippet below to create a starting point for your order.
Alternatively, use the API playground to explore and create your own order.
Copy
Ask AI
const apiKey = 'your-server-api-key'; // CHANGE THIS TO YOUR SERVER API KEYconst tokenId = 'solana:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'; // trump tokenconst deliveryAddress = 'your-solana-wallet-address'; // CHANGE THIS TO YOUR RECEIVING SOLANA WALLET ADDRESSconst receiptEmail = 'your-email@example.com'; // CHANGE THIS TO YOUR EMAILconst options = {method: 'POST',headers: {'X-API-KEY': apiKey,'Content-Type': 'application/json'},body: JSON.stringify({lineItems: {tokenLocator: tokenId,executionParameters: {mode: "exact-in", // The execution method for the order. It also tells Crossmint to operate in buying fungibles modeamount: "1", // default currency USDmaxSlippageBps: "500" // Optional, or else default autogenerated slippage will be applied}},payment: {method: "checkoutcom-flow", // Using Checkout.com as the payment processorreceiptEmail: receiptEmail},recipient: {walletAddress: deliveryAddress}})};fetch('https://www.crossmint.com/api/2022-06-09/orders', options).then(response => response.json()).then(response => console.log(JSON.stringify(response, null, 2))).catch(err => console.error(err));
After creating an order, you’ll need to render the Checkout.com Flow component to collect payment information. The Flow component is a pre-built UI that handles the payment collection process.
The Checkout.com Flow component handles the payment submission process automatically. When a user completes the payment form and clicks the payment button, the onPaymentCompleted callback will be triggered with the payment response.
Unlike with Stripe, you don’t need to manually submit the payment form. The Checkout.com Flow component takes care of the entire payment process, including validation, submission, and handling the response.
Here’s how the payment flow works with Checkout.com:
The user fills out the payment form rendered by the Flow component
The user clicks the payment button in the Flow component
The Flow component validates the payment information
If valid, the Flow component submits the payment to Checkout.com
The onPaymentCompleted callback is triggered with the payment response
You can use the payment response to update your UI and proceed to the next step
Copy
Ask AI
// Example of handling the payment completiononPaymentCompleted: (component, paymentResponse) => { console.log("Payment completed with ID:", paymentResponse.id); // Update your UI to show payment success setPaymentStatus('success'); // Proceed to the next step (e.g., order confirmation) navigateToOrderConfirmation(orderId);},
If there’s an error during the payment process, the onError callback will be triggered:
Copy
Ask AI
onError: (component, error) => { console.error("Payment error:", error, "Component:", component.type); // Update your UI to show payment failure setPaymentStatus('error'); // Display error message to the user setErrorMessage(error.message || 'Payment failed. Please try again.');},
After making the payment via whichever payment method, you’ll need to poll the Get Order API to check on the delivery status and present this info to your user.
Refer to the complete get order API reference here.
When polling for order status, you may encounter a situation where payment.status is completed but the order also contains a payment.refunded property. This indicates that the payment was initially successful but has since been refunded.
The payment.refunded object includes the following fields:
amount: The amount that was refunded
currency: The currency of the refund
txId: The on-chain transaction ID the refund was sent in
chain: The blockchain where the refund transaction occurred
When you encounter this state, your application should:
Display an appropriate message to the user indicating that their payment was refunded
Provide the transaction ID (txId) so users can verify the refund on-chain
Prevent any further actions related to the order (such as delivery expectations)
Provide options for the user to place a new order if desired
This state typically occurs when there was an issue with processing the order after payment was received, such as insufficient liquidity for memecoin purchases or compliance issues.
🎉 Congratulations! You’ve successfully set up your headless memecoin checkout. Check out the Next Steps section below to learn how to customize your integration.
Price quotes are valid for 30 seconds. After expiration, you’ll need to request a new quote from the headless
checkout API
Slippage
Crossmint applies the slippage specified in your API request via executionParameters.slippageBps. If not
provided, Crossmint will use the default slippage configuration from Crossmint’s provider
If an order expires before payment is completed (e.g., the 30-second quote validity period ends), you can either create a new order or use the refresh quote API:
Yes, you can use our embedded checkout, hosted checkout, or no-code storefront options. Contact our sales team to learn more about these solutions and find the best fit for your needs.
Crossmint KYC is currently disabled for memecoin purchases.
This means that if your buyers typically have high risk profiles, their transaction may be declined.
To increase conversion, please read the improving conversion guide.
When a user attempts a purchase, Crossmint puts a hold on their credit card. Only if the blockchain transaction succeeds, funds are captured. If the blockchain transaction fails, funds are released and the user is never charged.
The default transaction limit is 1,000 USD per user.
A single wallet address is subject to a daily limit of 1,000 USD per user, the same as for NFT purchases.
If you need a higher limit, speak to your Crossmint representative.
Yes, there is a volume limit of 1,000,000 USD worth of credit card purchases per day. This limit resets daily at 11:59 PM EST.
The order creation request includes several important parameters:
Payment Object
method: Set to checkoutcom-flow for Checkout.com credit card payments
currency: Set to usd for US Dollar payments
receiptEmail: Required for credit card payments to deliver receipt
Line Items Object
tokenLocator: Specifies the memecoin token address in the format solana:tokenAddress
executionParameters:
mode: Set to “exact-in” for memecoin purchases (specifies exact USD amount to spend)
amount: Amount to purchase in USD
maxSlippageBps: Set to “500” for 5% slippage tolerance. If not provided, the default slippage will be applied from the available liquidity provider.
Response Parameters
The order response includes Checkout.com-specific parameters:
checkoutcomPaymentSession: Contains the payment session information from Checkout.com
id: The payment session ID
payment_session_secret: The secret used to authenticate with Checkout.com
payment_session_token: The token used to initialize the Checkout.com Flow component
checkoutcomPublicKey: The public key used to initialize the Checkout.com Flow component