Skip to main content
Promo codes allow you to offer special pricing, free trials, and limited-time promotions to boost subscriptions and reward loyal users.

How Promo Codes Work

The system supports two types of promo codes:
1

Hardcoded Promo Codes

Built into the source code for common scenarios:
  • EXTRA - 1 week Premium + Meta Copier (FREE)
  • EXTRA2 - 2 weeks Premium + Meta Copier (FREE)
  • VIP - 1 week Basic Only (FREE)
  • DISCOUNT - 1 week Basic for ₦3,000 (generates payment link)
2

Custom Database Promo Codes

Created dynamically with custom:
  • Plan types
  • Durations
  • Pricing
  • Usage limits
  • Expiration dates

Hardcoded Promo Codes

These are immediately available without setup.

FREE Promo Codes

/promo EXTRA

 Grants: 1 week Premium + Auto Copier
💰 Cost: FREE
🔄 Usage: One-time per user
Free codes are perfect for influencer campaigns, referral rewards, or compensating users for issues.
DISCOUNT (Basic ₦3,000)
/promo DISCOUNT

 Grants: 1 week Basic
💰 Cost: ₦3,000 (40% discount from ₦5,000)
🔗 Generates: Payment link
When user enters DISCOUNT, they receive a payment button. After payment, subscription activates.

Database Promo Codes

Create flexible, trackable promo codes stored in the database.

Bot Commands for Promo Management

Admin users can create and manage promo codes directly via Telegram bot commands:

/create_promo

Interactive 7-step wizard to create custom promo codes

/list_promos

View all promo codes with usage statistics

/delete_promo CODE

Delete a specific promo code by its code

Create Promo via Bot

/create_promo
The bot will guide you through 7 steps:
  1. Promo Code - Code name (UPPERCASE, no spaces)
  2. Display Name - Human-readable name
  3. Plan Type - basic, biweekly, monthly, premium, or promo
  4. Duration - Number of days (e.g., 7, 14, 30)
  5. Free or Paid - Is it free or requires payment?
  6. Amount - If paid, amount in Naira (e.g., 3000)
  7. Copier Access - Premium MT5 copier included?
  8. Expiry Date - When the promo code expires
Creating promos via bot is faster than using Prisma code and doesn’t require database access.

List All Promos

/list_promos
Shows all promo codes with:
  • Code name and display name
  • Plan details and duration
  • Usage count vs limit
  • Active/inactive status
  • Expiry date

Delete Promo Code

/delete_promo NEWYEAR2025
Permanently removes the promo code from the database.
Deletion is irreversible. Users who already redeemed the code keep their subscriptions.

Promo Code Schema

model PromoCode {
  id               String   @id
  code             String   @unique
  name             String?  // Display name
  
  // Plan configuration
  planType         String   // "basic", "premium", "biweekly", "monthly"
  durationDays     Int
  hasCopierAccess  Boolean  @default(false)
  
  // Pricing
  isFree           Boolean  @default(false)
  amountKobo       Int?     // If not free
  
  // Expiry
  expiresAt        DateTime
  
  // Usage limits
  usageLimit       Int?     // Max total uses (null = unlimited)
  usageCount       Int      @default(0)
  perUserLimit     Int      @default(1)
  
  // Metadata
  createdBy        String   @default("admin")
  isActive         Boolean  @default(true)
  
  createdAt        DateTime
  updatedAt        DateTime
}

Create Promo Code

Use Prisma to create promo codes:
await prisma.promoCode.create({
  data: {
    code: 'NEWYEAR2025',
    name: 'New Year Special 2025',
    planType: 'monthly',
    durationDays: 30,
    hasCopierAccess: false,
    isFree: false,
    amountKobo: 1000000, // ₦10,000
    expiresAt: new Date('2025-01-31'),
    usageLimit: 100,
    perUserLimit: 1,
    isActive: true
  }
})
Code must be UPPERCASE and unique. Duplicate codes will cause errors.

Example Promo Campaigns

await prisma.promoCode.create({
  data: {
    code: 'FREETRIAL',
    name: 'Free 7-Day Trial',
    planType: 'basic',
    durationDays: 7,
    hasCopierAccess: false,
    isFree: true,
    expiresAt: new Date('2025-12-31'),
    usageLimit: 500,
    perUserLimit: 1,
    isActive: true
  }
})
Use case: Acquisition campaign to convert free users
await prisma.promoCode.create({
  data: {
    code: 'INFLUENCER50',
    name: 'Influencer 50% Off',
    planType: 'premium',
    durationDays: 14,
    hasCopierAccess: true,
    isFree: false,
    amountKobo: 1100000, // ₦11,000 (50% off ₦22,000)
    expiresAt: new Date('2025-06-30'),
    usageLimit: 50,
    perUserLimit: 1,
    isActive: true
  }
})
Use case: Partner with influencer, track conversions
await prisma.promoCode.create({
  data: {
    code: 'LOYAL30',
    name: 'Loyalty Bonus - 30 Days',
    planType: 'premium',
    durationDays: 30,
    hasCopierAccess: true,
    isFree: true,
    expiresAt: new Date('2025-03-31'),
    usageLimit: null, // Unlimited
    perUserLimit: 1,
    isActive: true
  }
})
Use case: Reward users who made 3+ purchases
await prisma.promoCode.create({
  data: {
    code: 'FLASH24',
    name: '24-Hour Flash Sale',
    planType: 'biweekly',
    durationDays: 14,
    hasCopierAccess: false,
    isFree: false,
    amountKobo: 700000, // ₦7,000 (30% off ₦10,000)
    expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours
    usageLimit: 30,
    perUserLimit: 1,
    isActive: true
  }
})
Use case: Urgency-driven conversion campaign

Broadcast Promo Command

Send promotional offers to all users:
/broadcast_promo
This command:
  1. Creates a fresh payment link for ₦3,000 (7-day Basic plan)
  2. Sends message to ALL users with payment button
  3. Links expire after 48 hours
  4. Includes “Verify Promo Payment” button

Promo Broadcast Flow

1

Admin Runs Command

/broadcast_promo
2

System Creates Links

Generates payment link with metadata:
{
  planType: 'promo',
  metadata: {
    broadcastTimestamp: Date.now().toString()
  }
}
3

Users Receive Message

🔥 SPECIAL PROMO OFFER!

💎 LIMITED TIME: 7 Days for ONLY ₦3,000!

That's ₦2,000 OFF the regular Basic plan!

⚠️ Links expire in 48 hours

[🔥 Get ₦3,000 Promo (7 Days)]
[✅ Verify Promo Payment]
4

User Clicks & Pays

Payment link opens → User completes payment
5

User Verifies

Clicks “Verify Promo Payment” → Runs /verify_promo REFERENCE
6

Access Granted

Subscription created → Invite link sent
Promo Link Expiry:
  • Links expire 48 hours after broadcast
  • Each link works ONCE only
  • Users who click after expiry must wait for next broadcast

User Redemption Flow

How users redeem promo codes:

Free Promo Code

1

User Enters Code

/promo EXTRA
2

System Validates

  • Check if code exists (hardcoded or database)
  • Verify not expired (expiresAt > now)
  • Check usage limits not exceeded
  • Confirm user hasn’t used before
3

Create Subscription

await prisma.subscription.create({
  data: {
    telegramUserId: user.id,
    paystackRef: promoCode, // Store code as reference
    amountKobo: 0, // Free
    planType: 'premium',
    hasCopierAccess: true,
    expiresAt: calculateExpiryDate('premium', currentExpiry)
  }
})
4

Update Usage Count

await prisma.promoCode.update({
  where: { code: promoCode },
  data: { usageCount: { increment: 1 } }
})
5

Grant Access

Send invite link or extend existing subscription
1

User Enters Code

/promo DISCOUNT
2

System Generates Payment Link

const response = await fetch('/api/payment/link', {
  method: 'POST',
  body: JSON.stringify({
    telegramId: user.id,
    planType: 'custom',
    metadata: { promoCode: 'DISCOUNT' }
  })
})
3

User Receives Button

🎁 Special Offer!

✨ Get 7 Days for ₦3,000!

[🔥 Pay Now]
4

User Pays

Completes payment through Paystack
5

User Verifies

/verify_basic REFERENCE
6

Access Granted

Subscription created with promo pricing

Promo Code Validation

The system performs these checks:

1. Code Exists

const promo = await prisma.promoCode.findUnique({
  where: { code: promoCode.toUpperCase() }
})

if (!promo) {
  return 'Code not found'
}

2. Code Active

if (!promo.isActive) {
  return 'Code is inactive'
}

3. Not Expired

if (new Date(promo.expiresAt) < new Date()) {
  return 'Code has expired'
}

4. Usage Limit

if (promo.usageLimit && promo.usageCount >= promo.usageLimit) {
  return 'Code usage limit reached'
}

5. Per-User Limit

const userUsageCount = await prisma.subscription.count({
  where: {
    telegramUserId: user.id,
    paystackRef: { equals: promoCode, mode: 'insensitive' }
  }
})

if (userUsageCount >= promo.perUserLimit) {
  return 'You already used this code'
}
All validation happens before creating subscription to prevent abuse.

Managing Promo Codes

List Active Promo Codes

const activeCodes = await prisma.promoCode.findMany({
  where: {
    isActive: true,
    expiresAt: { gt: new Date() }
  },
  orderBy: { createdAt: 'desc' }
})

console.log('Active Codes:', activeCodes)

Disable Promo Code

await prisma.promoCode.update({
  where: { code: 'OLDPROMO' },
  data: { isActive: false }
})

Extend Expiration

await prisma.promoCode.update({
  where: { code: 'FLASH24' },
  data: {
    expiresAt: new Date('2025-12-31')
  }
})

Check Usage Stats

const promo = await prisma.promoCode.findUnique({
  where: { code: 'NEWYEAR2025' }
})

const remaining = promo.usageLimit 
  ? promo.usageLimit - promo.usageCount 
  : 'Unlimited'

console.log(`
Promo: ${promo.name}
Used: ${promo.usageCount}
Remaining: ${remaining}
Expires: ${promo.expiresAt.toLocaleDateString()}
`)

Find Top Performing Codes

const topCodes = await prisma.promoCode.findMany({
  orderBy: { usageCount: 'desc' },
  take: 10
})

topCodes.forEach((code, i) => {
  console.log(`${i+1}. ${code.code}: ${code.usageCount} uses`)
})

Promo Code Best Practices

1

Use Memorable Codes

  • WELCOME better than XYZ123
  • SUMMER2025 better than PROMO47
  • Short and easy to type
2

Set Clear Expiration

  • Use urgency: 24-72 hours for flash sales
  • Monthly campaigns: 30 days
  • Seasonal: End of season date
3

Limit Usage

  • First 50 users: Creates FOMO
  • One per user: Prevents abuse
  • Track performance by code
4

Test Before Launch

  • Create code in database
  • Test redemption yourself
  • Verify expiry and limits work
5

Track ROI

  • Monitor usageCount
  • Calculate revenue per code
  • Compare to acquisition cost
6

Communicate Clearly

  • Show savings amount (₦2,000 OFF)
  • Display expiration prominently
  • Include call-to-action

Promo Code Ideas

Seasonal Campaigns

  • NEWYEAR2025 - January special
  • BLACKFRIDAY - Black Friday sale
  • SUMMER50 - Summer 50% off
  • XMAS - Christmas promotion

Influencer Codes

  • JOHN20 - Influencer John’s 20% off
  • TRADER50 - Trading community discount
  • YOUTUBE100 - YouTube audience special

Milestone Codes

  • 1000USERS - Celebrate 1000 users
  • LAUNCH - Product launch special
  • ANNIVERSARY - Annual celebration

Re-engagement

  • COMEBACK - Win-back churned users
  • MISSYOU - Inactive user offer
  • RETURN50 - 50% off for returners

Referral Rewards

  • FRIEND - Referral bonus
  • INVITE3 - Invite 3 friends reward
  • SHARE20 - Share and save

Build docs developers (and LLMs) love