> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pay with Other Crypto

> Create a fully customized checkout experience with crypto payments.

## Introduction

In this quickstart you'll learn how to accept multiple different cryptocurrencies as payment using Crossmint's headless APIs, to purchase an NFT on the `polygon-amoy` testnet.

## Prerequisites

<Snippet file="headless-checkout-prereqs.mdx" />

If you are choosing to do this quickstart in your own console or IDE, consider you will need to have a way to prompt and sign crypto payments, like using Metamask.

### External Prerequisites

* Your crypto wallet of choice - Metamask, Coinbase Wallet, etc.
* A small balance of testnet currency in whichever cryptocurrency you would like to pay with
  * [Ethereum, Base, Polygon](https://www.alchemy.com/faucets) - note that some of these faucets require a minimum of 0.1 ETH on mainnet, to prevent abuse
  * [Solana devnet](https://solana.com/developers/guides/getstarted/solana-token-airdrop-and-faucets)

## Integration Steps

This quickstart will primarily focus on the API calls necessary to implement headless checkout in your project. You will also need to build out the frontend experience for your users.

### 1. Create an Order

<Snippet file="headless-create-order-preamble.mdx" />

<Tabs>
  <Tab title="Pay with ETH">
    ```json theme={null}
    {
        "payment": {
            "method": "base-sepolia",
            "currency": "eth",
            "payerAddress": "0xabcd1234..."
        },
        "lineItems": [
            {
                "collectionLocator": "crossmint:<collectionId>",
                "callData": {
                    "totalPrice": "0.0001"
                }
            }
        ]
    }
    ```
  </Tab>

  <Tab title="Pay with ERC20s">
    ```json theme={null}
    {
        "payment": {
            "method": "base-sepolia",
            "currency": "usdc" | "degen" | "brett" | ... ,
            "payerAddress": "0xabcd1234..."
        },
        "lineItems": [
            {
                "collectionLocator": "crossmint:<collectionId>",
                "callData": {
                    "totalPrice": "0.0001"
                }
            }
        ]
    }
    ```
  </Tab>

  <Tab title="Pay with SOL">
    ```json theme={null}
    {
        "payment": {
            "method": "solana",
            "currency": "sol",
            "payerAddress": "7NxpS1cMZ8..."
        },
        "lineItems": [
            {
                "collectionLocator": "crossmint:<collectionId>",
                "callData": {
                    "totalPrice": "0.0001"
                }
            }
        ]
    }
    ```
  </Tab>

  <Tab title="Pay with SPLs">
    ```json theme={null}
    {
        "payment": {
            "method": "solana",
            "currency": "usdc" | "bonk" | ... ,
            "payerAddress": "7NxpS1cMZ8..."
        },
        "lineItems": [
            {
                "collectionLocator": "crossmint:<collectionId>",
                "callData": {
                    "totalPrice": "0.0001"
                }
            }
        ]
    }
    ```
  </Tab>

  <Tab title="Pay with MATIC">
    ```json theme={null}
    {
        "payment": {
            "method": "polygon-amoy",
            "currency": "matic",
            "payerAddress": "0xabcd1234..."
        },
        "lineItems": [
            {
                "collectionLocator": "crossmint:<collectionId>",
                "callData": {
                    "totalPrice": "0.0001"
                }
            }
        ]
    }
    ```
  </Tab>
</Tabs>

<Accordion title="Example Response">
  ```json theme={null}
  {
    "clientSecret": "_removed_",
    "order": {
      "orderId": "cc40e6af-f8dc-4ac2-8e26-d91a32f271cf",
      "phase": "quote",
      "locale": "en-US",
      "lineItems": [
        {
          "chain": "polygon-amoy",
          "quantity": 1,
          "callData": {
            "quantity": 1
          },
          "metadata": {
            "name": "Headless Demo",
            "description": "NFT Checkout Demo",
            "imageUrl": "https://utfs.io/f/cd8545b7-3410-4fcd-988d-cd11951ed53c-g287ok.png"
          },
          "quote": {
            "status": "requires-recipient",
            "charges": {
              "unit": {
                "amount": "0.000169004",
                "currency": "eth"
              }
            },
            "totalPrice": {
              "amount": "0.000169004",
              "currency": "eth"
            }
          },
          "delivery": {
            "status": "awaiting-payment"
          }
        }
      ],
      "quote": {
        "status": "requires-recipient",
        "quotedAt": "_DATE_",
        "expiresAt": "_DATE_",
        "totalPrice": {
          "amount": "0.000169004",
          "currency": "eth"
        }
      },
      "payment": {
        "status": "requires-quote"
      }
    }
  }
  ```
</Accordion>

<Note>
  In the requests above the `payerAddress` has been included, however if your user has not yet connected their wallet
  you may omit this field, allow them to connect their wallet after creating the order, and submit the `payerAddress`
  at a later time.
</Note>

<Snippet file="headless-create-order-ending.mdx" />

### 2. Update the Order with Recipient

<Snippet file="headless-update-order-preamble.mdx" />

<Tabs>
  <Tab title="Email recipient">
    ```json theme={null}
    {
        "recipient": {
            "email": "test@example.com"
        }
    }
    ```
  </Tab>

  <Tab title="Wallet recipient">
    ```json theme={null}
    {
        "recipient": {
            "walletAddress": "0xabcd1234..."
        }
    }
    ```
  </Tab>
</Tabs>

<Note>
  Notice you only need to pass the object that your are updating, in this case, `recipient`. You can also update
  multiple properties in the same call. Available properties for update include `recipient`, `locale`, and the
  `payment` object.
</Note>

<Note>
  If specifying a recipient by wallet address, ensure the address is valid for the chain your **collection** is on,
  which may differ from the chain the **payment is being performed** on.
</Note>

<Accordion title="Example Response">
  ```json theme={null}
  {
    "orderId": "cc40e6af-f8dc-4ac2-8e26-d91a32f271cf",
    "phase": "payment",
    "locale": "en-US",
    "lineItems": [
      {
        "chain": "polygon-amoy",
        "quantity": 1,
        "callData": {
          "quantity": 1
        },
        "metadata": {
          "name": "Headless Demo",
          "description": "NFT Checkout Demo",
          "imageUrl": "https://utfs.io/f/cd8545b7-3410-4fcd-988d-cd11951ed53c-g287ok.png"
        },
        "quote": {
          "status": "valid",
          "charges": {
            "unit": {
              "amount": "0.0001681558",
              "currency": "eth"
            }
          },
          "totalPrice": {
            "amount": "0.0001681558",
            "currency": "eth"
          }
        },
        "delivery": {
          "status": "awaiting-payment"
        }
      }
    ],
    "payment": {
      "status": "awaiting-payment",
      "preparation": {
        "method": "crypto",
        "chain": "base-sepolia",
        "payerAddress": "0x6C3b3225759Cbda68F96378A9F0277B4374f9F06",
        "serializedTransaction": "0x02f9012683aa36a744848917370085080992ce6c82629c94a105c311fa72b8fb78c992ecbdb8b02ea5bd394d869a9d359ca000b8f465794a68624763694f694a49557a49314e694973496e523563434936496b705856434a392e65794a756232356a5a534936496a4d3559544e6d4d444d334c544d7a4e6d51744e4441305a5331684d6a45774c575268593249335957526b5a4456694e794973496d39795a4756795357526c626e52705a6d6c6c63694936496d4e6a4e44426c4e6d466d4c5759345a474d744e47466a4d6930345a5449324c5751354d57457a4d6d59794e7a466a5a694973496d6c68644349364d5463784e546b334f54557a4e33302e662d4949646c653375314c58634c7845765438754e336d74786370764a686f31384a5a4b76483768456659c0"
      }
    }
  }
  ```

  <Warning>
    Notice at the bottom, the new `serializedTransaction` property. This is a unique identifier let's Crossmint know exactly which order you are updating.
    Anytime you update an order you ***must*** use the returned `serializedTransaction` property.
  </Warning>
</Accordion>

### 3. Show Purchase Preview to User

Now, after you've told Crossmint systems what you want, and you have passed a valid place to send the NFT, Crossmint will return a quote with prices for the desired items
Within the returned response, you'll find the `lineItems` array which contains the metadata and a quote for each line item. Within a quote, a detailed breakdown of its charges can be found.

<Tabs>
  <Tab title="Preview Screenshot">
    <Frame type="simple">
      <img src="https://mintcdn.com/crossmint/QK6rWfcUCMmvIQPT/images/payments/headless/purchase-preview.jpg?fit=max&auto=format&n=QK6rWfcUCMmvIQPT&q=85&s=9d1ec25d05b3ede1e6c5cb68134c371f" alt="preview purchase screenshot" width="2002" height="584" data-path="images/payments/headless/purchase-preview.jpg" />
    </Frame>
  </Tab>

  <Tab title="Code Example">
    <Note>
      If you are developing in an IDE or in terminal, the returned `lineitems` may be stuck in an \[Object], or be in a
      hard-to-understand object format. You can make this human-readable for yourself by adding `JSON.stringify(response)`
    </Note>

    ```jsx theme={null}
    <div class="flex flex-col justify-start w-full mb-5 item">
        <div class="flex w-full items-center justify-start border-b border-[#E7E9ED] py-2">
            <div class="flex items-center justify-between w-full">
                <div class="flex items-center">
                    <img src="{order.lineItems[0].metadata.image}" class="flex w-10 h-10 mr-4 rounded-md" />
                    <div class="flex flex-col items-start justify-start">
                        <h3 class="font-medium">{order.lineItems[0].metadata.name}</h3>
                        <p class="text-sm text-text-secondary">{order.lineItems[0].metadata.description.slice(0, 20)}</p>
                    </div>
                </div>
                <div class="flex flex-col">
                    <p>Unit: {order.lineItems[0].quote.charges["unit"].amount}</p>
                    <p>Gas: {order.lineItems[0].quote.charges?.["gas"]?.amount}</p> // Gas charge may not be defined, depending
                    on the collection's chain
                </div>
            </div>
        </div>
        <div class="flex w-full flex-col items-center justify-start gap-y-0.5 pt-2">
            <div class="flex items-center justify-between w-full">
                <p class="text-sm font-medium text-text-primary">Total price</p>
                <span class="text-sm font-medium text-text-primary">
                    {order.quote.totalPrice.amount} {order.quote.totalPrice.currency}
                </span>
            </div>
        </div>
    </div>
    ```
  </Tab>

  <Tab title="lineItems Example">
    ```json theme={null}
    {
        // some properties removed for brevity
        "order": {
            "lineItems": [
                {
                    "chain": "polygon-amoy",
                    "quantity": 1,
                    "callData": {
                        "quantity": 1
                    },
                    "metadata": {
                        "name": "Headless Demo",
                        "description": "NFT Checkout Demo",
                        "imageUrl": "https://utfs.io/f/cd8545b7-3410-4fcd-988d-cd11951ed53c-g287ok.png"
                    },
                    "quote": {
                        "status": "valid",
                        "charges": {
                            "unit": {
                                "amount": "0.000169004",
                                "currency": "eth"
                            }
                        },
                        "totalPrice": {
                            "amount": "0.000169004",
                            "currency": "eth"
                        }
                    },
                    "delivery": {
                        "status": "awaiting-payment"
                    }
                }
            ]
        }
    }
    ```
  </Tab>
</Tabs>

### 4. Request Payment from User

You now need to request crypto payment from the user.

You will use the `serializedTransaction` returned in the purchase preview from the previous step. The `serializedTransaction` needs to be structured into a transaction object, which can then be passed to a crypto payment prompter, like viem's `sendTransaction` or wagmi's `sendTransactionAsync`.

Whichever method you use, it should open the user's default wallet extension in the browser and allow the user to complete the cross-chain payment.

<Check>
  If you've followed along this far you can simply paste the `serializedTransaction` property returned in your
  previous API call into the app below. This will allow you to sign and send the transaction.
</Check>

<Tabs>
  <Tab title="Send EVM Payment">
    <Frame type="simple">
      <iframe src="https://headless-sendpayment.vercel.app" width="730px" height="500px" />
    </Frame>
  </Tab>

  <Tab title="Send Solana Payment">
    <Warning>
      Ensure your wallet is connected to the **devnet** network, otherwise your funds may be lost!
    </Warning>

    <Frame type="simple">
      <iframe src="https://headless-sendpayment.vercel.app/solana" width="730px" height="500px" />
    </Frame>
  </Tab>

  <Tab title="Code Example">
    ```tsx theme={null}
    "use client";

    import { ConnectButton } from "@rainbow-me/rainbowkit";
    import { useState } from "react";
    import { parseTransaction } from "viem"; // Refer to their documentation details to make viem work for your needs
    import { useSendTransaction } from "wagmi"; // Refer to their documentation details to make wagmi work for your needs

    export default function Home() {
        const { data: hash, isPending, sendTransactionAsync } = useSendTransaction();

        const signAndSendTransaction = async () => {
            const serializedTxn = "0x_your_serialized_transaction_response";
            const txn = parseTransaction(serializedTxn || "0x");

            await sendTransactionAsync({
                to: txn.to as `0x${string}`,
                value: BigInt(txn.value ? txn.value.toString() : "0"),
                data: txn.data as `0x${string}`,
                chainId: txn.chainId,
            });
        };
        return <button onClick={() => signAndSendTransaction()}>Send Transaction</button>;
    }
    ```
  </Tab>

  <Tab title="Full Repository Example">
    For a deeper example, refer to the repository linked below, which is the exact code running in the App tab.

    <Card title="headless-sendpayment" icon="github" href="https://github.com/crossmint/headless-sendpayment">
      Refer to the full repo for complete code examples
    </Card>
  </Tab>
</Tabs>

### 5. Poll for Status Updates

<Snippet file="poll-for-status-updates.mdx" />

## Next Steps

<Snippet file="headless-next-steps.mdx" />
