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

# Purchases of Multiple NFTs

> Allow users to purchase multiple NFTs in a single order

The set up differs slightly for primary (drops) and marketplace sales:

<Tabs>
  <Tab title="Primary Sales">
    Pass a quantity attribute to the `mintConfig` indicating the total number of NFTs and update the `totalPrice` accordingly.

    <Note>The price on the mintConfig must match the price on the contract. For example, if you are selling 2 NFTs for 1 ETH each, the `totalPrice` should be 2 ETH.</Note>
    <Note>For EVM contracts, ensure the attribute name matches the parameter name in your mint function. For example: If your mint function has the signature: `mintTo(address _to, uint256 _amount)` then the attribute you set in the `mintConfig` must be `_amount` instead of `quantity`.</Note>
    <Note>Make sure that all NFTs belong to the same collectionId and blockchain.</Note>

    <Accordion title="See example">
      The following examples are for the [hosted checkout button](/payments/pay-button/overview). For the [embedded checkout](/payments/embedded/overview), you may adjust the `mintConfig` analogously.

      <CodeGroup>
        ```jsx React theme={null}
        import { useState } from "react";
        import { CrossmintPayButton } from "@crossmint/client-sdk-react-ui";

        export default function App() {
          const [mintAmount, setMintAmount] = useState(1);
          const nftCost = 0.001;
          const projectId = "_YOUR_PROJECT_ID_";
          const collectionId = "_YOUR_COLLECTION_ID_";

          const handleDecrement = () => {
            if (mintAmount <= 1) return;
            setMintAmount(mintAmount - 1);
          };

          const handleIncrement = () => {
            if (mintAmount >= 3) return;
            setMintAmount(mintAmount + 1);
          };

          return (
            <div>
              <button onClick={handleDecrement}> - </button>
              <input readOnly type="number" value={mintAmount} />
              <button onClick={handleIncrement}> + </button>

              <CrossmintPayButton
                projectId={projectId}
                collectionId={collectionId}
                environment="staging"
                mintConfig={{
                  totalPrice: (nftCost * mintAmount).toString(),
                  _quantity: mintAmount, // the `_quantity` property should match what is in your mint function
                  // Add any additional minting arguments here...
                }}
              />
            </div>
          );
        }
        ```

        ```html Vanilla JS theme={null}
        <html>
          <head>
            <title>Variable QTY</title>
            <script src="https://unpkg.com/@crossmint/client-sdk-vanilla-ui@1.0.1-alpha.6/lib/index.global.js"></script>
            <style>
              #mintQty {
                background: #efefef;
                text-align: center;
                border-radius: 3px;
                margin-bottom: 5px;
              }
            </style>
          </head>
          <body>
            <button class="change-qty" id="decrement">-</button>
            <input readonly id="mintQty" type="number" value="1" />
            <button class="change-qty" id="increment">+</button>

            <crossmint-pay-button
              id="xmint-btn"
              projectId="_PROJECT_ID_"
              collectionId="_COLLECTION_ID_"
              environment="staging"
              mintConfig='{
                "totalPrice": "0.001",
                "_quantity": 1
              }'
            />

            <script>
              document.addEventListener(
                "click",
                function (event) {
                  // ignore the click event if it wasn't a change qty button
                  if (!event.target.matches(".change-qty")) return;

                  // set up min/max values for minting quantity
                  const MIN = 1;
                  const MAX = 5;

                  // get current value of qty
                  let qtyEl = document.getElementById("mintQty");
                  let qty = Number(qtyEl.value);

                  // increment or decrement the mintQty input
                  if (event.target.id === "decrement") {
                    qty = qty > MIN ? --qty : qty;
                  }
                  if (event.target.id === "increment") {
                    qty = qty < MAX ? ++qty : qty;
                  }

                  // update the input display
                  qtyEl.value = qty;

                  // calculate the totalPrice
                  let totalPrice = qty * 0.001; // where 0.001 is the cost per NFT

                  // make sure everything looks good so far
                  console.log("quantity:", qty);
                  console.log("totalPrice:", totalPrice);

                  // setup the new mintConfig
                  let mintConfigObj = {
                    type: "erc-721",
                    totalPrice: totalPrice.toString(),
                    _quantity: qty,
                  };
                  let mintConfigJson = JSON.stringify(mintConfigObj);

                  // finally update the button config
                  document
                    .getElementById("xmint-btn")
                    .setAttribute("mintConfig", mintConfigJson);
                },
                false
              );
            </script>
          </body>
        </html>
        ```
      </CodeGroup>
    </Accordion>
  </Tab>

  <Tab title="Marketplaces">
    Pass the list of NFTs on the order to the `mintConfig` as an array:

    <AccordionGroup>
      <Accordion title="EVM example">
        ```javaScript TypeScript theme={null}
        mintConfig: [{
          "type":"secondary-eth",
          "contractAddress":"0xbC…307e",
          "tokenId":"7777"
        },{
          "type":"secondary-eth",
          "contractAddress":"0x17…e54D",
          "tokenId":"8888"
        }]
        ```
      </Accordion>

      <Accordion title="Solana example">
        ```javaScript TypeScript theme={null}
        mintConfig: [{
          "mintHash":"4oDd…x6NC",
          "buyerCreatorRoyaltyPercent":100,
          "type":"solana-secondary"
        },{
          "mintHash":"J2vX…cuNo",
          "buyerCreatorRoyaltyPercent":100,
          "type":"solana-secondary"
        },{
          "mintHash":"ARn8…AiAG",
          "buyerCreatorRoyaltyPercent":100,
          "type":"solana-secondary"
        }]
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

***

### FAQ

<AccordionGroup>
  <Accordion title="What happens if some of the transactions fail?">
    **Fiat purchases** <br />
    When a user submits an order, Crossmint puts a hold on their credit card and attempts the purchase of the NFTs. If the transaction fails, the funds are released instantly (though it may take some time to be reflected on the bank statement) so the customer is never charged.

    If an order results in a mix of successful and failed purchase attempts, Crossmint will only charge for the transactions that went through and return the rest instantly. Users will receive an email receipt with the final transaction amount.<br /><br />
    **Crypto purchases**<br />
    If a transaction fails, Crossmint will return the full amount to the buyer. Any gas fees incurred will be subsidized by Crossmint.
  </Accordion>

  <Accordion title="Do all NFTs must be on the same blockchain?">
    Yes, all NFTs in a single order must be on the same blockchain.
  </Accordion>
</AccordionGroup>
