DevCareer x Nomba Hackathon

Judge's Walkthrough & Portal Directory

Welcome to the evaluation panel for TicketPay. Below is a structured portal directory, credentials, and step-by-step testing instructions to help you audit the system.

Student Web Portal

Register, fund wallets via instant Nomba virtual accounts, generate ride tickets, and review transaction history.

Driver mobile-first Portal

Track earnings real-time (30s auto-refresh), view transaction feeds, generate QR codes, and resolve student disputes.

Admin Management System

Register campus drivers, monitor analytics, update ticket pricing, and download QR transit pass cards.

Sandbox Testing Credentials

Admin Access

Super Admin Credentials

Use this to log into the Admin portal to manage drivers and view analytical stats.

URL admin.ticketpay.com.ng
Username admin
Password
change_this_password_in_env
Driver Access

Driver Authentication

To test a driver account, create a new driver in the Admin panel. The system will automatically return a Driver Code and a temporary password once.

URL ticketpay.com.ng/driver/login
Driver Code Generated by Admin (e.g. DRV001)
Password Displayed once upon creation

Step-by-Step Testing Flow

1

Create a Driver

Log into the Admin Panel using the credentials above, navigate to Driver Management, and register a new operator. Copy the generated temporary password from the pop-up modal.

2

Sign Up as a Student

Open the Student Portal and sign up with any email address. Click the verification link sent via email (we are integrated with mailtrap/resend) or complete the signup verification block.

3

Fund the Student Wallet

Upon registration, a Nomba Virtual Account is instantly generated and displayed on your wallet card. You can fund this wallet using the simulated webhook repush feature or transfer to test the instant real-time crediting.

4

Pay for a Ride

Generate a QR ticket in the Student dashboard. Log into the Driver Portal in a separate/incognito tab, scan the student's QR code ticket, and watch the driver's revenue increase instantly in real-time.

Nomba API Integration Highlights

Instant Provisioning on Sign-Up

We integrated Nomba's Virtual Account API so that every student gets a personal bank account numbers linked directly to their TicketPay wallet during onboarding. No manuals deposits required.

// Virtual Account Generation Flow
const result = await axios.post(`${NOMBA_BASE_URL}/v1/virtual-accounts`, {
    accountRef: `TP-${uuidv4()}`,
    accountName: studentFullName,
    bankCode: "100033", // Nomba Default
    ...
});

HMAC-SHA256 Webhook Cryptographic Validation

We engineered signature verification to validate requests sent to /api/wallets/webhook/nomba using Nomba's custom colon-delimited parameters rather than raw body strings, protected by crypto.timingSafeEqual.

// Signature calculation
const hashingPayload = `${eventType}:${requestId}:${userId}:${walletId}:${transactionId}:${transactionType}:${transactionTime}:${transactionResponseCode}:${timestamp}`;
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
const expectedSignature = hmac.update(hashingPayload).digest('base64');
const isValid = crypto.timingSafeEqual(Buffer.from(sig, 'base64'), Buffer.from(expectedSignature, 'base64'));

Redis-backed Token Rotation Strategy

Nomba tokens expire every 30 minutes. To prevent API rate limits and token expirations, we implemented a dual-key cache in Redis. The active token expires in 25 minutes, triggering background renewal using the refresh_token grant before the absolute expiration.

// Redis Cache & Expiry Check
const cachedToken = await redis.get("nomba:access_token");
if (!cachedToken) {
    const expiredToken = await redis.get("nomba:expired_access_token");
    const refresh = await redis.get("nomba:refresh_token");
    // Call Nomba /v1/auth/token/refresh using refresh_token...
}