NFT Rewards
Create and manage on-chain NFT rewards to incentivize customers with points, discounts, free products, event passes, and exclusive access.
Prerequisites
- Podium SDK installed and configured
- A merchant profile (see Merchant Setup recipe)
- Understanding of NFT basics
NFT Rewards let merchants incentivize customers with on-chain rewards. Rewards can be points, discounts, free products, event passes, or exclusive access. Each reward is minted as an NFT to the user's wallet, providing verifiable ownership and enabling cross-platform reward portability. This guide covers the full reward lifecycle: creation, configuration, publishing, distribution, and management.
Create an NFT reward
Start by creating a reward with a specific type. Available types are POINTS, FREE_PRODUCT, DISCOUNT_CODE, EVENT_PASS, CUSTOM_REWARD, and EXCLUSIVE_ACCESS:
// Create an NFT reward for the merchant
const reward = await client.nftRewards.createNftReward({
requestBody: {
type: 'POINTS', // POINTS, FREE_PRODUCT, DISCOUNT_CODE, EVENT_PASS, CUSTOM_REWARD, EXCLUSIVE_ACCESS
creatorId: 'creator_xyz', // The merchant's ID
},
})
console.log(reward)
// {
// id: 'reward_abc123',
// type: 'POINTS',
// status: 'DRAFT',
// creatorId: 'creator_xyz',
// createdAt: '2025-01-15T...',
// }Configure reward metadata
Update the reward with NFT metadata including name, description, and image. The metadata will be stored on-chain when the NFT is minted:
// Update NFT details
const updatedReward = await client.nftRewards.replace({
id: reward.id,
requestBody: {
name: 'Loyalty Points NFT',
description: '100 points redeemable at Awesome Store',
// Image URL typically points to IPFS for on-chain permanence
imageUrl: 'ipfs://QmXxx.../reward-badge.png',
points: 100, // For POINTS type rewards
},
})
console.log(updatedReward)
// {
// id: 'reward_abc123',
// type: 'POINTS',
// status: 'DRAFT',
// name: 'Loyalty Points NFT',
// description: '100 points redeemable at Awesome Store',
// imageUrl: 'ipfs://QmXxx.../reward-badge.png',
// points: 100,
// }Publish the reward
Once configured, publish the reward to make it available for distribution. Published rewards can be granted to users:
// Publish the reward (makes it available for distribution)
const publishedReward = await client.nftRewards.publish({
id: reward.id,
})
console.log(publishedReward)
// {
// id: 'reward_abc123',
// status: 'PUBLISHED',
// name: 'Loyalty Points NFT',
// ...
// }Grant a reward to a user
Mint the NFT reward to a user. The reward is minted on-chain to their wallet address:
// Grant the reward to a user
const grant = await client.nftRewards.createNftRewardGrant({
id: reward.id,
requestBody: {
userId: 'user_xyz', // The user receiving the reward
creatorId: 'creator_xyz', // The merchant granting it
},
})
console.log(grant)
// {
// success: true,
// txHash: '0x...',
// tokenId: 1,
// }List merchant rewards
Get all rewards created by a merchant to display in a dashboard or management UI:
// List all rewards for a merchant
const rewards = await client.merchantNftRewards.listNftRewards({
creatorId: 'creator_xyz',
})
console.log(rewards)
// {
// data: [
// {
// id: 'reward_abc123',
// type: 'POINTS',
// status: 'PUBLISHED',
// name: 'Loyalty Points NFT',
// grantCount: 42,
// },
// {
// id: 'reward_def456',
// type: 'DISCOUNT_CODE',
// status: 'DRAFT',
// name: '20% Off Next Purchase',
// grantCount: 0,
// },
// ],
// total: 2,
// }Disable a reward
Disable a reward to prevent new grants. Existing grants remain valid:
// Disable a reward (no new grants allowed)
const disabledReward = await client.nftRewards.disable({
id: 'reward_abc123',
})
console.log(disabledReward)
// {
// id: 'reward_abc123',
// status: 'DISABLED',
// name: 'Loyalty Points NFT',
// grantCount: 42, // Existing grants still valid
// }Complete Example
Here's a complete working example combining all the steps:
import { createPodiumClient } from '@podiumcommerce/node-sdk'
const client = createPodiumClient({
apiKey: process.env.PODIUM_API_KEY,
})
// Create and configure a new reward
async function createLoyaltyReward(
creatorId: string,
name: string,
points: number,
imageUrl: string // Typically an IPFS URL for on-chain permanence
) {
// Step 1: Create the reward
const reward = await client.nftRewards.createNftReward({
requestBody: {
type: 'POINTS',
creatorId,
},
})
// Step 2: Configure metadata
await client.nftRewards.replace({
id: reward.id,
requestBody: {
name,
description: `${points} loyalty points`,
imageUrl, // e.g., 'ipfs://QmXxx.../image.png'
points,
},
})
// Step 3: Publish
const published = await client.nftRewards.publish({ id: reward.id })
console.log('Created reward:', published.id)
return published
}
// Grant rewards to multiple users (e.g., after a purchase)
async function grantRewardsToUsers(
rewardId: string,
creatorId: string,
userIds: string[]
) {
const results = await Promise.all(
userIds.map(userId =>
client.nftRewards.createNftRewardGrant({
id: rewardId,
requestBody: { userId, creatorId },
})
)
)
console.log(`Granted reward to ${results.length} users`)
return results
}
// Get reward analytics for a merchant
async function getRewardAnalytics(creatorId: string) {
const rewards = await client.merchantNftRewards.listNftRewards({ creatorId })
return {
totalRewards: rewards.total,
publishedRewards: rewards.data.filter(r => r.status === 'PUBLISHED').length,
totalGrants: rewards.data.reduce((sum, r) => sum + r.grantCount, 0),
byType: rewards.data.reduce((acc, r) => {
acc[r.type] = (acc[r.type] || 0) + 1
return acc
}, {} as Record<string, number>),
}
}
// Usage
const reward = await createLoyaltyReward(
'creator_xyz',
'Welcome Bonus',
100,
'ipfs://QmXxx.../welcome-badge.png'
)
// Grant to new customers
await grantRewardsToUsers(reward.id, 'creator_xyz', [
'user_123',
'user_456',
'user_789',
])
// Check analytics
const analytics = await getRewardAnalytics('creator_xyz')
console.log('Reward analytics:', analytics)Explore the full API
See all available endpoints and parameters in the API reference.
