Sadiq Sharp Sub API

Simple, clean REST API for VTU services. Integrate airtime, data, electricity, cable TV, and education bill payments into your applications with our developer-friendly API.

Real-time Delivery

Instant service delivery with reliable uptime

Secure Transactions

PIN-protected purchases & bank-grade security

Simple Integration

Clean REST API with detailed documentation

Overview

Our API provides a simple way to integrate VTU services. All requests return a consistent JSON response format. You need an API key for authentication.

Base URL
https://sadiqsharpsub.com.ng/api

All API endpoints are relative to this base URL.

Quick Start
  1. Get your API key from Developer Settings
  2. Add apikey: YOUR_API_KEY header
  3. Start making requests to our endpoints
  4. Configure webhook for transaction notifications

Authentication

All API requests require authentication using your API key as a apikey in the header.

GET /user/info

Get your account information including balance and package details.

JavaScript Example

const API_KEY = 'your_api_key_here';
const API_BASE = 'https://sadiqsharpsub.com.ng/api';

async function getUserInfo() {
    try {
        const response = await fetch(`${API_BASE}/user/info`, {
            headers: {
                apikey: `${API_KEY}`,
                'Content-Type': 'application/json'
            }
        });
        
        const data = await response.json();
        console.log('User Info:', data);
        return data;
    } catch (error) {
        console.error('Error:', error);
    }
}

Response

{
    "success": true,
    "data": {
        "user": {
            "_id": "696665c5fc18af81e018f892",
            "name": "John Doe",
            "email": "john@example.com",
            "balance": 5000.50,
            "package": "basic",
            "accountMode": "live",
            "phone": "08012345678",
            "totalSpent": {
                "total": 1500,
                "airtime": 500,
                "data": 1000,
                "electricity": 0,
                "cable": 0,
                "education": 0
            },
            "totalFunding": 6500.50,
            "lastFunding": "2024-01-10T08:16:28.787Z",
            "createdAt": "2024-01-07T16:28:07.871Z"
        }
    }
}

Response Format

All API responses follow this consistent JSON format for easy parsing and error handling.

success
Boolean indicating if request processed without errors
status
Transaction status: "success", "failed", "processing", "reversed"
message
Human-readable message about the request
data
Main response data (balance, transaction details, etc.)
redirect
Redirect URL when authentication fails

Complete Response Example

// Successful transaction
{
    "success": true,
    "status": "success",
    "message": "₦500 airtime sent successfully to 08012345678",
    "data": {
        "amount": 500,
        "costPrice": 507.5,
        "network": "mtn",
        "phone": "08012345678",
        "reference": "sadiqsharpsub_1704968412345",
        "oldBalance": 12500.5,
        "newBalance": 11993.0
    },
    "transaction": {
        "_id": "65ae8a1dd1d28a209b222da2",
        "reference": "sadiqsharpsub_1704968412345",
        "status": "success",
        "amount": "500",
        "costPrice": 507.5,
        "previousBalance": 12500.5,
        "newBalance": 11993.0,
        "createdAt": "2024-01-11T06:20:12.345Z"
    }
}

// Failed transaction
{
    "success": false,
    "status": "failed",
    "message": "Transaction failed. Please try again.",
    "data": {
        "reference": "sadiqsharpsub_1704968412346",
        "oldBalance": 12500.5,
        "newBalance": 12500.5
    }
}

Transaction Status

All service purchases return one of these status codes. Always verify status before processing.

success

Service delivered successfully. Amount deducted from balance.

failed

Service delivery failed. Amount refunded automatically.

processing

Transaction is being processed. Check status later.

reversed

Transaction was reversed. Everything refunded.

Service Endpoints

All service purchases require a 4-digit transaction PIN for security.

GET /services/pricing

Get current pricing for all services based on your package.

JavaScript Example

async function getPricing() {
    const response = await fetch(`${API_BASE}/services/pricing`, {
        headers: {
            apikey: `${API_KEY}`
        }
    });
    return await response.json();
}

// Get MTN data plans example
const pricing = await getPricing();
const mtnPlans = pricing.data.services.data.plans.MTN;
console.log('MTN Plans:', mtnPlans);
POST /services/airtime

Purchase airtime. Requires transaction PIN.

Parameter Type Required Description
phone * string Yes 11-digit phone number
network * string Yes "MTN", "AIRTEL", "GLO", "9MOBILE"
amount * number Yes Amount in Naira (min: ₦100)
transactionPin * string Yes 4-digit PIN

JavaScript Example

async function buyAirtime() {
    const data = {
        phone: "08012345678",
        network: "MTN",
        amount: 500,
        transactionPin: "1234"
    };
    
    const response = await fetch(`${API_BASE}/services/airtime`, {
        method: 'POST',
        headers: {
            apikey: `${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    });
    
    return await response.json();
}
POST /services/data

Purchase data bundle. First get planId from pricing endpoint.

Parameter Type Required Description
phone * string Yes 11-digit phone number
network * string Yes Network name
planId * string Yes Service ID from pricing data
planType * string Yes "CORPORATE GIFTING", "GIFTING", etc.
transactionPin * string Yes 4-digit PIN

JavaScript Example

async function buyData() {
    const data = {
        phone: "08012345678",
        network: "MTN",
        planId: "16", // From pricing endpoint
        planType: "CORPORATE GIFTING",
        transactionPin: "1234"
    };
    
    const response = await fetch(`${API_BASE}/services/data`, {
        method: 'POST',
        headers: {
            apikey: `${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    });
    
    return await response.json();
}
POST /services/cable/validate

Validate cable IUC number before purchase.

Parameter Type Required Description
cableProvider * string Yes "DSTV", "GOTV", "STARTIMES"
iucNumber * string Yes Cable account number
transactionPin * string Yes 4-digit PIN

JavaScript Example

async function validateCable() {
    const data = {
        cableProvider: "DSTV",
        iucNumber: "208392929",
        transactionPin: "1234"
    };
    
    const response = await fetch(`${API_BASE}/services/cable/validate`, {
        method: 'POST',
        headers: {
            apikey: `${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    });
    
    return await response.json();
}
POST /services/cable/subscribe

Subscribe to cable package after validation.

Parameter Type Required Description
cableProvider * string Yes Validated provider name
iucNumber * string Yes Validated IUC number
planName * string Yes Package name from pricing
transactionPin * string Yes 4-digit PIN
POST /services/electricity/validate

Validate meter number before purchase.

JavaScript Example

async function validateMeter() {
    const data = {
        disco: "IKEJA ELECTRICITY (IKEDC)",
        meterNumber: "208392191828929",
        meterType: 1, // 1 = prepaid, 2 = postpaid
        transactionPin: "1234"
    };
    
    const response = await fetch(`${API_BASE}/services/electricity/validate`, {
        method: 'POST',
        headers: {
            apikey: `${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    });
    
    return await response.json();
}
POST /services/education

Purchase exam PINs (WAEC, NECO, NABTEB).

Parameter Type Required Description
examType * string Yes "WAEC", "NECO", "NABTEB"
quantity * number Yes Number of PINs (max: 10)
transactionPin * string Yes 4-digit PIN

Transaction Endpoints

Query transaction details and history. Always verify transactions using these endpoints.

GET /transaction/:reference

Always verify transactions using this endpoint! Use the reference from webhooks or responses.

JavaScript Example

async function verifyTransaction(reference) {
    const response = await fetch(`${API_BASE}/transaction/${reference}`, {
        headers: {
            apikey: `${API_KEY}`
        }
    });
    
    const result = await response.json();
    
    if (result.success) {
        const transaction = result.data.transaction;
        
        // CRITICAL: Verify transaction belongs to current user
        if (transaction.userId === currentUserId) {
            console.log('Valid transaction:', transaction);
            return transaction;
        } else {
            throw new Error('Transaction does not belong to user');
        }
    } else {
        throw new Error('Transaction not found');
    }
}

// Usage when receiving webhook
const webhookReference = 'sadiqsharpsub_1704968412345';
const verifiedTx = await verifyTransaction(webhookReference);
if (verifiedTx) {
    // Process transaction in your system
    updateOrderStatus(verifiedTx.reference, verifiedTx.status);
}
GET /transaction/history

Get paginated transaction history with filtering options.

JavaScript Example

async function getTransactionHistory() {
    const params = new URLSearchParams({
        page: 1,
        limit: 20,
        status: 'success',
        service: 'airtime',
        dateFrom: new Date('2024-01-01').toISOString()
    });
    
    const response = await fetch(`${API_BASE}/transaction/history?${params}`, {
        headers: {
            apikey: `${API_KEY}`
        }
    });
    
    return await response.json();
}

Webhooks

Receive real-time notifications about transaction status changes. Configure your webhook URL in Developer Settings.

Important Security Notice

Always verify webhook data using the transaction verification endpoint. Never trust webhook data blindly.

  • Get transaction reference from webhook payload
  • Call /transaction/:reference to verify
  • Check if transaction belongs to your user
  • Only then process the transaction in your system
POST /webhook/send/:reference

Manually trigger webhook for a transaction (for testing).

JavaScript Example

async function testWebhook(reference) {
    const response = await fetch(`${API_BASE}/webhook/send/${reference}`, {
        method: 'POST',
        headers: {
            apikey: `${API_KEY}`
        }
    });
    
    return await response.json();
}

Webhook Handler Example

// Express.js webhook handler
app.post('/your-webhook-endpoint', async (req, res) => {
    try {
        const payload = req.body;
        console.log('Webhook received:', payload);
        
        // Extract transaction reference
        const reference = payload.data?.transaction?.reference;
        
        if (!reference) {
            return res.status(400).json({ error: 'No reference found' });
        }
        
        // CRITICAL: Verify the transaction with our API
        const verifiedTx = await verifyTransaction(reference);
        
        if (!verifiedTx) {
            console.error('Transaction verification failed');
            return res.status(400).json({ error: 'Invalid transaction' });
        }
        
        // Process based on event type
        const event = payload.event;
        
        switch (event) {
            case 'transaction.success':
                await updateOrderStatus(verifiedTx.reference, 'completed');
                console.log('Order completed');
                break;
                
            case 'transaction.failed':
                await updateOrderStatus(verifiedTx.reference, 'failed');
                await refundUser(verifiedTx.userId, verifiedTx.costPrice);
                console.log('Order failed, user refunded');
                break;
                
            case 'transaction.processing':
                await updateOrderStatus(verifiedTx.reference, 'processing');
                console.log('Order processing');
                break;
        }
        
        // Always return 200 to acknowledge receipt
        res.status(200).json({ received: true });
        
    } catch (error) {
        console.error('Webhook error:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
});

Webhook Payload Format

{
    "event": "transaction.success",
    "timestamp": "2024-01-11T06:20:15.678Z",
    "data": {
        "transaction": {
            "_id": "65ae8a1dd1d28a209b222da2",
            "reference": "sadiqsharpsub_1704968412345",
            "providerReference": "MTN_REF_789012",
            "userId": "65ae89ddd1d28a209b222da1",
            "category": "service",
            "service": "airtime",
            "amount": 500,
            "costPrice": 507.5,
            "previousBalance": 12500.5,
            "newBalance": 11993.0,
            "network": "mtn",
            "recipient": "08012345678",
            "status": "success",
            "description": "₦500 airtime sent successfully to 08012345678",
            "createdAt": "2024-01-11T06:20:12.345Z"
        }
    }
}
Webhook Best Practices
  • Always verify transactions before processing
  • Implement idempotency to handle duplicate webhooks
  • Use HTTPS in production
  • Log all webhook events for debugging
  • Return HTTP 200 quickly, process asynchronously
  • Implement retry logic for failed webhook deliveries
Ready to Start?

Get your API key from Developer Settings page and start integrating today. Test in sandbox mode first before going live.

Get API Key AI Integration Help