← Back to Developer
Qwiktop Qwiktop
Business API Documentation

Sell airtime, data, and bills through Qwiktop.

This guide explains how to connect your website, mobile app, POS, or reseller system to Qwiktop using a secure API key.

Versionv1.0
Effective dateJune 2026
Base URLhttps://qwiktop.com/api/v1

Table of Contents

1. What the API can do
2. Authentication
3. Balance and wallet funding
4. Product catalogues
5. Buy data, airtime, and bills
6. Transaction status checks
7. Identity and account verification
8. Testing and sandbox
9. Webhooks and signatures
10. Error handling and retry rules
11. Security checklist
12. Full cURL examples

1. What the API can do

The Qwiktop API exposes VTU operations and identity verification:

FeaturePurpose
Check balanceKnow if your Qwiktop wallet can cover orders before sending them.
Fund walletGenerate a Paystack checkout link for wallet funding.
List data plansShow live Qwiktop plans and prices in your own app.
List airtime networksShow supported airtime networks and reseller discount.
List bill providersShow electricity and cable TV providers.
Place ordersBuy data, buy airtime, or pay bills using wallet balance.
Track ordersCheck one transaction using its reference.
Verify identities and accountsCheck a Ghana Card (NIA), voter ID, bank account, Mobile Money wallet or phone number. See section 7.
Internal and admin APIs are not part of the public API.

2. Authentication

Every request must include your Qwiktop API key in the X-API-Key header.

curl "https://qwiktop.com/api/v1/balance" \
  -H "X-API-Key: qt_your_api_key"
HeaderRequiredDescription
X-API-KeyYesYour active API key from the Developer page.
Content-TypeFor POSTUse application/json when sending a request body.
Never put your API key in frontend JavaScript, mobile app bundles, GitHub, or public screenshots. Call Qwiktop from your backend/server.

3. Balance and wallet funding

GET/balance

Returns wallet, profit, and referral balances for the account that owns the API key.

{
  "status": "success",
  "data": {
    "wallet_balance": 250.00,
    "profit_balance": 12.50,
    "referral_balance": 5.00,
    "currency": "GHS"
  }
}
POST/wallet/fund

Creates a Paystack checkout session for funding the wallet.

FieldTypeRequiredDescription
amountnumberYesAmount in GHS.
{
  "amount": 100
}
{
  "status": "success",
  "message": "Wallet funding checkout initialized.",
  "data": {
    "reference": "API-FUND-...",
    "authorization_url": "https://checkout.paystack.com/...",
    "amount": 100,
    "currency": "GHS"
  }
}

4. Product catalogues

GET/data-plans?network=mtn

Returns active data plans. Prices automatically use customer or reseller pricing based on the API key owner role.

QueryRequiredAccepted values
networkNomtn, telecel, airteltigo, big-time
{
  "status": "success",
  "data": [
    {
      "id": 11,
      "network": "mtn",
      "name": "MTN Monthly 1GB",
      "size": "1GB",
      "validity": "Bundle",
      "price": 3.70,
      "currency": "GHS"
    }
  ]
}
GET/airtime/networks

Returns supported airtime networks and account discount.

GET/bill-providers

Returns bill categories and providers for electricity and cable TV.

5. Place orders

POST/buy-data
FieldTypeRequiredDescription
networkstringYesmtn, telecel, airteltigo, or big-time.
plan_idintegerYesPlan ID from /data-plans.
phonestringYesRecipient phone number, e.g. 0241234567.
POST/buy-airtime
FieldTypeRequiredDescription
networkstringYesmtn, telecel, or airteltigo.
amountnumberYesAirtime face value in GHS.
phonestringYesRecipient phone number.
POST/pay-bill
FieldTypeRequiredDescription
typestringYeselectricity or cable.
providerstringYesecg, nedco, dstv, gotv, or startimes.
accountstringYesMeter number, smartcard number, or account ID.
amountnumberYesAmount in GHS.

6. Transaction status check

GET/transactions/{reference}

Use the reference returned after an order to check the latest status.

{
  "status": "success",
  "data": {
    "reference": "QT-...",
    "type": "data",
    "service": "MTN_DATA",
    "status": "pending",
    "amount": 8.50,
    "recipient": "0241234567",
    "network": "mtn",
    "value": "1GB",
    "message": "Transaction queued",
    "created_at": "2026-09-25T12:00:00+00:00",
    "updated_at": "2026-09-25T12:00:05+00:00"
  }
}

7. Identity and account verification

Confirm who is behind a Ghana Card, voter ID, bank account, Mobile Money wallet or phone number before you sell to them, pay them or onboard them. Each lookup is charged to your Qwiktop wallet. Qwiktop sets the price for each service and can switch a service on or off, so ask Qwiktop for current pricing and availability.

ServiceEndpointWhat it confirms
Ghana Card (NIA)POST /verify/ghana-cardThe card number matches the name, gender and date of birth given.
Voter IDPOST /verify/voter-idThe voter ID matches the name, sex and date of birth given.
Bank accountGET /verify/bankThe name on a bank account.
Mobile MoneyGET /verify/momoThe name on a Mobile Money wallet.
Phone subscriberGET /verify/msisdnThe registered name of a phone number.
MTN identityGET /verify/mtnThe identity linked to an MTN number.

Phone numbers

Send a phone number as 0241234567, 233241234567 or +233241234567. Qwiktop treats them as the same number.

Billing, refunds and repeat lookups

Privacy: lookup results are stored encrypted, only for the account that made the lookup, and deleted after the retention period. The details you submit (card numbers, names, dates of birth) are never stored. Only send details you are entitled to check.

Response format

{
  "status": "success",
  "message": "Verified successfully",
  "data": { ... the verification result ... },
  "meta": {
    "reference": "VERIFY-3F2A9C1E-...",
    "cached": false,
    "amount_charged": 2.50,
    "currency": "GHS"
  }
}

The data object holds the result for that lookup. It typically includes the holder's name, and its exact fields depend on the service.

POST/verify/ghana-card
FieldTypeRequiredDescription
card_numberstringYesGhana Card number, e.g. GHA-123456789-0.
surnamestringYesSurname exactly as on the card.
first_namesstringYesFirst and middle names as on the card.
genderstringYesMale or Female.
date_of_birthstringYesYYYY-MM-DD.
{
  "card_number": "GHA-123456789-0",
  "surname": "Mensah",
  "first_names": "Ama Serwaa",
  "gender": "Female",
  "date_of_birth": "1990-01-31"
}
POST/verify/voter-id
FieldTypeRequiredDescription
voter_idstringYesVoter ID number (8 to 15 characters).
surnamestringYesSurname as on the voter card.
other_namesstringYesFirst and other names as on the voter card.
sexstringYesMale or Female.
date_of_birthstringYesYYYY-MM-DD.
GET/verify/bank?bank_code=030100&account_number=1234567890
FieldTypeRequiredDescription
bank_codestringYesThe bank's code.
account_numberstringYesAccount number (8 to 20 characters).
GET/verify/momo?phone_number=0241234567&network=mtn
FieldTypeRequiredDescription
phone_numberstringYesThe Mobile Money number.
networkstringYesmtn, telecel (or vodafone), airteltigo (or tigo).
GET/verify/msisdn?phone_number=0241234567
FieldTypeRequiredDescription
phone_numberstringYesThe phone number to look up.
{
  "status": "success",
  "message": "Phone number verified successfully",
  "data": {
    "ResponseCode": "0000",
    "Message": "Customer Details",
    "Label": "Customer Details",
    "Data": [{ "Display": "name", "Value": "AMA SERWAA MENSAH", "Amount": 0 }]
  },
  "meta": {
    "reference": "VERIFY-3F2A9C1E-...",
    "cached": false,
    "amount_charged": 2.50,
    "currency": "GHS"
  }
}
GET/verify/mtn?phone_number=0241234567&consent_type=sms
FieldTypeRequiredDescription
phone_numberstringYesThe MTN number.
consent_typestringNonone, sms or ussd. Defaults to none.

Verification errors

A failed verification returns status: "error", a machine-readable code, and, when an attempt was recorded, its reference.

{
  "status": "error",
  "message": "Ghana Card details do not match.",
  "code": "VERIFICATION_FAILED",
  "reference": "VERIFY-3F2A9C1E-..."
}
HTTPcodeMeaningCharged?
422VERIFICATION_FAILEDThe lookup ran but the details did not check out or nothing was found.No (refunded)
422(validation)A field is missing or malformed. The response lists each field.No
402INSUFFICIENT_BALANCEYour wallet cannot cover the lookup.No
502GATEWAY_UNAVAILABLEThe verification service could not be reached. Retry shortly.No (refunded)
503SERVICE_UNAVAILABLEThis service is not enabled for sale right now.No
503GATEWAY_NOT_CONFIGUREDVerification is being set up. Contact Qwiktop.No

8. Testing and sandbox

Try every endpoint without spending real money or contacting a real provider. Create a Test key on the Developer page and use it exactly like a live key. Nothing you do with a test key touches your real wallet, real orders or real verification records.

Live keyTest key
Key looks likeqt-…qt-test-…
WalletYour real Qwiktop walletA virtual wallet, topped up on the Developer page
Catalogue and pricesLiveThe same live plans and prices
Orders and lookupsRealSimulated. References start with TEST-
Response headerNone addedX-Qwiktop-Mode: sandbox

How a simulated order behaves

{
  "event": "transaction.updated",
  "timestamp": "2026-09-25T12:00:00+00:00",
  "data": {
    "reference": "TEST-ABC123XYZ456",
    "status": "success",
    "service": "MTN_AIRTIME",
    "amount": 10.0,
    "test": true
  }
}

Wallet funding in the sandbox has no checkout: POST /wallet/fund credits the virtual wallet straight away and returns authorization_url: null. There is no two-minute cooldown between orders to the same number, so you can repeat tests quickly.

Make an order fail on purpose

End the phone number (data, airtime) or the account (bills) with one of these codes:

Ends withWhat happens
0001The order fails and your virtual wallet is refunded.
0002The order stays pending and never settles.
0003The order is refused straight away with a 503 error.

Make a verification fail on purpose

End the phone number, account number or voter ID with one of these codes. For a Ghana Card the nine-digit number in the middle decides, for example GHA-000000001-0.

Ends withWhat happens
0001The lookup fails with VERIFICATION_FAILED and you are not charged.
0002The lookup fails with GATEWAY_UNAVAILABLE and you are not charged.

Every other number succeeds with a clearly fake result. The same input always gives the same result. Successful lookups are charged to the virtual wallet at the real price, and the response has meta.sandbox: true.

Reset and limits

Use Reset sandbox on your test key to delete its test orders and restore the starting virtual balance. Test requests count towards your key's daily limit and respect its IP whitelist. Your account can hold a limited number of test keys. Test keys can never be turned into live keys.

Prefer clicking to coding? The API console on the Developer page lets you pick an endpoint, fill in the fields and see the response, using your test key.

9. Webhooks

If you save a webhook URL, Qwiktop sends event notifications when transaction state changes.

{
  "event": "transaction.updated",
  "timestamp": "2026-06-27T10:30:00+00:00",
  "data": {
    "reference": "QT-...",
    "status": "success",
    "service": "MTN_DATA"
  }
}

Signature verification

Every webhook contains X-Qwiktop-Signature. Compute HMAC-SHA256 over the JSON payload using your webhook secret and compare it to the header.

$expected = hash_hmac('sha256', $rawJsonBody, $webhookSecret);
if (! hash_equals($expected, $_SERVER['HTTP_X_QWIKTOP_SIGNATURE'])) {
    http_response_code(401);
    exit;
}

10. Error handling

200 / 201 Success

The request was accepted or created.

401 Unauthorized

Missing, invalid, or paused API key.

402 Insufficient balance

Wallet balance cannot cover the requested order.

422 Validation error

Required fields are missing or invalid.

429 Rate limited

Daily API limit has been reached.

503 Provider unavailable

External payment/provider system is temporarily unavailable.

Retry rules

CaseWhat to do
Network timeoutCheck transaction status before retrying. Avoid duplicate customer charges.
402 balanceFund wallet first, then retry.
422 validationFix request body. Do not retry unchanged.
503 provider issueRetry later with backoff, or allow Qwiktop queueing to finish.

11. Security checklist

12. Full cURL examples

Buy data

curl -X POST "https://qwiktop.com/api/v1/buy-data" \
  -H "X-API-Key: qt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"network":"mtn","plan_id":1,"phone":"0241234567"}'

Buy airtime

curl -X POST "https://qwiktop.com/api/v1/buy-airtime" \
  -H "X-API-Key: qt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"network":"telecel","amount":10,"phone":"0500000000"}'

Pay bill

curl -X POST "https://qwiktop.com/api/v1/pay-bill" \
  -H "X-API-Key: qt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"type":"electricity","provider":"ecg","account":"12345678901","amount":20}'

Verify a Ghana Card

curl -X POST "https://qwiktop.com/api/v1/verify/ghana-card" \
  -H "X-API-Key: qt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"card_number":"GHA-123456789-0","surname":"Mensah","first_names":"Ama Serwaa","gender":"Female","date_of_birth":"1990-01-31"}'

Look up the name on a phone number

curl "https://qwiktop.com/api/v1/verify/msisdn?phone_number=0241234567" \
  -H "X-API-Key: qt_your_api_key"