Custom Contracts (EVM)

Using your own Custom Contract on Polygon, Ethereum, or another EVM blockchain? The following example shows you how to use it with Paper.


Assume that this is your contract's claim function:

function claimTo(
   address _to,
   uint256 _quantity,
   uint256 _tokenId,
   string CUSTOM_ARG_1, // Any additional arguments.
   bool CUSTOM_ARG_2
    mintCompliant(_tokenId, _quantity)
    priceCompliant(_tokenId, _quantity)

You will then need a mintMethod in order for Paper to call your claim function. For the example above, your mintMethod should look like this:

mintMethod: {
  name: "claimTo", // Name of the function to call within the smart contract.
  args: {
    _to: "$WALLET",
    _quantity: "$QUANTITY",
    _tokenId: 0,
    CUSTOM_ARG_1: "xyz",
    CUSTOM_ARG_2: false
  payment: { 
    value: "0.1 * $QUANTITY", // Assuming that your NFT costs 0.1 ETH each.
    currency: "ETH"

This will ensure that when Paper calls the smart contract during any checkout flow, under the hood, we would be calling your smart contract like so:

claimTo("0x...", 1, 0, "xyz", false {
  value: ethers.utils.parseEther("0.1"),


Your smart contract method that mints the NFT must satisfy these requirements:

  1. The method must accept the buyer's wallet address as an argument.
  2. The method must allow Paper's minter wallets to mint an unlimited amount as the msg.sender. Any restrictions on the minting wallet address or quantity is not allowed.
  3. (If priced in USDC) The method must explicitly request USDC token from the msg.sender.


The mintMethod is required when creating Shareable Checkout Links, One-Time Checkout Links, or Checkout Elements. Think of it as an ABI for Paper to know how to call your claim function.

The generic format of the mintMethod is:

"mintMethod": {
  "name": "claimTo",
  "args": {
    "_to": "$WALLET",
    "_quantity": "$QUANTITY"
  "payment": {
    "value": "0.1 * $QUANTITY",
    "currency": "ETH"

Template variables


Don't know the values?

Paper supports two template variables -$WALLET and $QUANTITY that you may use if you don't know the buyer's wallet address and quantity. Note that for all other fields such as value and currency, you would need to hardcode the actual values.

Template variables will be replaced when calling your contract:

VariableReplaced with
$WALLETThe buyer's wallet address.
$QUANTITYThe quantity of tokens to mint.


The payment field should provide the price per NFT in human-readable form (not wei).

Example: "payment": { "value": "0.1 * $QUANTITY", "currency": "ETH" } for an NFT that costs 0.1 ETH per token.

Free NFTs

Set the price to zero.

Example: "payment": { value: "0 * $QUANTITY", currency: "MATIC" }

NFTs priced in USDC

Ensure your mint method explicitly requests USDC tokens from msg.sender. See USDC Pricing for more details.

Delegate a different ERC-20 payment address


This is required when interacting with the Seaport contract.

By default Paper's float wallet approves your NFT contract to request ERC-20 tokens.

To specify a different contract address that will request ERC-20 tokens from Paper's float wallet, set that address in the "spender" field:

"payment": {
  "value": "100 * $QUANTITY",
  "currency": "USDC",


I have multiple methods with the same name. Why isn't my mintMethod isn't working?

Please provide the full signature as your mintMethod. Paper will not try to "guess" the correct method.


Your contract has methods mint(address to) and mint(address to, string tokenId) and your checkout will call the former.

Provide your mintMethod as mint(address).

You do not need to modify your contract.