Sell NFTs with payment collection, order verification, and minting—all in a single widget.
When to use:
NFT drops and launches
In-game item purchases
Digital collectible storefronts
Installation
How It Works
Player selects item
↓
Widget handles payment (crypto or fiat)
↓
Your backend verifies order
↓
NFT minted directly to player's wallet
The Sale widget handles:
Payment collection (crypto + fiat via credit card, Apple Pay, Google Pay)
Wallet connection (if not already connected)
Insufficient balance flows (swap, bridge, onramp)
Transaction signing
Your backend handles:
Order creation with item details
Payment verification
NFT minting via Minting API
Quick Start
import { checkout } from '@imtbl/sdk' ;
import { Environment } from '@imtbl/sdk/config' ;
const { Checkout , WidgetType , WidgetTheme , CommerceFlowType , CommerceEventType } = checkout ;
const checkoutSDK = new Checkout ({
baseConfig: {
environment: Environment . SANDBOX ,
publishableKey: 'YOUR_PUBLISHABLE_KEY' ,
},
});
// Basic sale flow
export async function openSale (
elementId : string ,
items : checkout . SaleItem [],
environmentId : string
) {
const widgets = await checkoutSDK . widgets ({ config: { theme: WidgetTheme . DARK } });
const widget = widgets . create ( WidgetType . IMMUTABLE_COMMERCE );
widget . mount ( elementId , {
flow: CommerceFlowType . SALE ,
items ,
environmentId ,
});
widget . addListener ( CommerceEventType . SUCCESS , ( data ) => {
console . log ( 'Purchase complete:' , data );
widget . unmount ();
});
widget . addListener ( CommerceEventType . FAILURE , ( data ) => {
console . error ( 'Purchase failed:' , data );
widget . unmount ();
});
widget . addListener ( CommerceEventType . CLOSE , () => {
widget . unmount ();
});
return widget ;
}
// Example: Game store items
export const EXAMPLE_ITEMS : checkout . SaleItem [] = [
{
productId: 'starter-pack' ,
name: 'Starter Pack' ,
description: '10 cards + 500 gold' ,
image: 'https://example.com/pack.png' ,
qty: 1 ,
},
{
productId: 'legendary-sword' ,
name: 'Legendary Sword' ,
description: 'A powerful weapon' ,
image: 'https://example.com/sword.png' ,
qty: 1 ,
},
];
Parameters
Parameter Type Description flow'SALE'Required. Specifies the sale flow itemsSaleItem[]Items to purchase environmentIdstringYour Hub environment ID collectionNamestringCollection name (display only) excludePaymentTypesstring[]Payment methods to hide
Item Structure
interface SaleItem {
productId : string ; // Your internal product ID
name : string ; // Display name
description ?: string ; // Short description
image : string ; // Image URL
qty : number ; // Quantity
}
Events
Event Description Payload SUCCESSPurchase completed { transactionHash, tokens }FAILUREPurchase failed { error }CLOSEUser closed widget — REQUEST_BRIDGEUser needs to bridge — REQUEST_SWAPUser needs to swap — REQUEST_ONRAMPUser needs fiat onramp —
Payment Options
Crypto Payments
Users can pay with tokens on Immutable Chain:
Currency Default Notes USDC ✅ Base currency IMX ✅ Native token Custom ERC-20 Optional Must be whitelisted
If users don’t have enough tokens, the widget offers:
Swap from another token
Bridge from Ethereum
Buy with fiat
Fiat Payments
Users can pay with credit card, Apple Pay, or Google Pay:
Funds settle to your wallet in USDC
Powered by Transak
KYC may be required for larger amounts
Backend Integration
The Sale widget requires a backend to:
Define available products and prices
Verify payment completion
Mint NFTs to purchasers
Primary Sales Backend Set up backend minting for primary sales
Backend Flow
1. Widget calls your /orders endpoint
↓
2. Your backend returns order details (items, prices)
↓
3. User completes payment in widget
↓
4. Widget calls your /confirm endpoint with tx hash
↓
5. Your backend verifies payment and mints NFTs
Transaction Limits
Maximum 350 items per transaction due to gas limits. For larger orders, split into multiple transactions.
Next Steps