Skip to main content
POST
/
api
/
payment
/
auto-verify
Auto-Verify Payment
curl --request POST \
  --url https://api.example.com/api/payment/auto-verify \
  --header 'Content-Type: <content-type>' \
  --data '
{
  "reference": "<string>"
}
'
{
  "success": true,
  "message": "<string>",
  "telegramId": "<string>",
  "planType": "<string>",
  "error": "<string>"
}

Overview

This endpoint performs complete payment verification with Paystack and automatically activates the user’s subscription. It verifies the transaction status, validates the payment amount and channel, creates an invite link, saves the subscription to the database, and sends the invite link to the user via Telegram.
This endpoint is called from the payment success page to provide immediate subscription activation without waiting for the Paystack webhook.

Authentication

No authentication required. This is a public endpoint called from the payment success page.

Request

Headers

Content-Type
string
required
Must be application/json

Body Parameters

reference
string
required
The Paystack transaction reference ID to verify

Response

Success Response (200)

success
boolean
true if verification and activation succeeded
message
string
Success message: “Payment verified and invite link sent”
telegramId
string
The Telegram user ID of the subscriber
planType
string
The activated subscription plan type

Error Responses

success
boolean
false when verification fails
error
string
Detailed error message describing the failure reason

Status Codes

  • 200 - Request processed (check success field for actual result)
  • 400 - Missing reference parameter

Validation Rules

The endpoint performs the following validations:

1. Reference Validation

reference
string
required
Must be provided and cannot be empty

2. Duplicate Transaction Check

Verifies the reference hasn’t been used before by checking the database for existing subscriptions with the same paystackRef. Error: “This transaction has already been redeemed”

3. Paystack Verification

Verifies the transaction with Paystack API:
  • Transaction must exist
  • Transaction status must be “success”
Errors:
  • “Payment verification failed”
  • “Payment was not completed successfully”

4. Payment Channel Validation

Ensures payment was made through an allowed channel:
  • bank_transfer (preferred)
  • card (also accepted)
Error: “Invalid payment method”

5. Telegram ID Validation

Extract Telegram ID from transaction metadata (required for subscription activation). Error: “Payment not linked to Telegram account”

6. Amount Validation

Verifies the paid amount matches the plan price:
  • Tolerance: ±NGN 1,500 (to account for Paystack fees)
  • Amount must be at least the expected plan amount
Error: “Payment amount (NGN X) is less than required (NGN Y)“

Subscription Activation Process

1

Unban Previously Removed Users

If the user was previously removed for non-payment, unban them from the Telegram channel using unbanChatMember().
2

Create Invite Link

Generate a one-time Telegram invite link valid for 24 hours using createInviteLink().Error: “Failed to create invite link”
3

Calculate Expiry Date

Compute subscription expiry based on plan duration:
  • Basic: 7 days
  • Bi-weekly: 14 days
  • Monthly: 30 days
  • Premium: 14 days
  • Promo: 7 days
4

Save to Database

Create subscription record with:
  • telegramUserId
  • telegramUsername
  • paystackRef
  • customerEmail
  • amountKobo
  • planType
  • hasCopierAccess
  • startedAt (current timestamp)
  • expiresAt (calculated expiry)
  • inviteLinkUsed
Error: “Failed to save subscription”
5

Send Telegram Message

Send invite link and subscription details to the user via Telegram bot.For Premium plans with copier access, includes MT5 setup instructions.
6

Set Conversation State (Premium Only)

For Premium plans, initialize MT5 setup conversation state to account_number step.

Examples

curl -X POST https://your-domain.com/api/payment/auto-verify \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "ref_abc123xyz789"
  }'

Success Response Example

{
  "success": true,
  "message": "Payment verified and invite link sent",
  "telegramId": "123456789",
  "planType": "premium"
}

Error Response Examples

Telegram Message Content

Basic Plans Message

✅ Payment Verified Successfully!

💎 Plan: Basic VIP
💰 Amount: NGN 5,000
📅 Access expires: Mar 10, 2026

Here is your one-time invite link (valid for 24 hours):
👉 https://t.me/+abc123xyz

Click the link to join the channel. The link can only be used once.

Type /status anytime to check your subscription.

Premium Plan Message (with MT5 Copier)

Implementation Notes

Required Environment Variables:
  • PAYSTACK_SECRET_KEY - For Paystack API verification
  • TELEGRAM_BOT_TOKEN - For sending messages and creating invite links
  • Database connection (Prisma) must be configured

Metadata Extraction Logic

The endpoint extracts Telegram ID from transaction metadata in two ways:
  1. Direct metadata fields: metadata.telegram_id
  2. Custom fields array: Searches metadata.custom_fields for variable_name === 'telegram_id'
This dual approach ensures compatibility with different payment link creation methods.

Plan Type Detection

Similarly extracts plan type from:
  1. metadata.plan_type
  2. Custom field with variable_name === 'plan_type'
  3. Defaults to 'basic' if not found

Amount Tolerance

Paystack adds transaction fees, so the endpoint allows up to NGN 1,500 (150,000 kobo) variance:
  • ₦5,000 plan: ~₦100-200 in fees
  • ₦22,000 plan: ~₦1,000 in fees

Premium Plan Features

For plans with hasCopierAccess: true:
  • Extended message with MT5 setup instructions
  • Conversation state initialized to account_number step
  • User can type /mt5setup to configure their copier

Database Schema

The subscription record created includes:
{
  telegramUserId: string       // Telegram user ID
  telegramUsername?: string    // Telegram username
  telegramName: string         // Display name from Paystack
  paystackRef: string          // Transaction reference (unique)
  customerEmail?: string       // Customer email
  amountKobo: number          // Amount paid in kobo
  planType: PlanType          // Plan type enum
  hasCopierAccess: boolean    // MT5 copier access flag
  startedAt: Date             // Subscription start
  expiresAt: Date             // Subscription expiry
  inviteLinkUsed: string      // Invite link generated
}

Error Handling

All errors are logged to console with context:
console.log('Auto-verifying payment:', reference)
console.log('Auto-verifying for telegram_id:', telegramId, 'plan:', planType)
console.error('Verification failed:', verification.error)
console.error('Error saving subscription:', error)
console.error('Error in auto-verify:', error)
This enables debugging payment issues through server logs.

Build docs developers (and LLMs) love