REST API Version 1.0 Token Auth

API Documentation

Integrate OguaaH Test's package purchase and vendor management into your own systems. Browse packages, initiate payments, and manage hotspot credentials through a clean, versioned REST API.

https://oguaahotspot.m-netgh.com/api/v1

Introduction

The OguaaH Test REST API gives external applications programmatic access to two core workflows:

Normal Purchase

Any authenticated user can browse packages and buy hotspot credentials for themselves or a third-party phone number.

Vendor API

Approved vendors can purchase bulk packages for customers, view credentials, and request commission payouts.

All responses are JSON. Send Accept: application/json and Content-Type: application/json on every request.

Base URL & Format

All endpoints are prefixed with the base URL below. Append the path from each endpoint reference to form the full URL.

Base URL
https://oguaahotspot.m-netgh.com/api/v1
Header Value Required
Accept application/json Always
Content-Type application/json POST/PUT
Authorization Bearer {token} Auth routes

Authentication

The API uses secure token-based authentication. Call the login endpoint to receive a Bearer token, then include it in all subsequent requests. Tokens carry abilities that gate access to certain routes:

purchase

Granted to every authenticated user. Required for package browsing and placing orders.

vendor

Additionally granted when the user has an active vendor profile. Required for all /vendor/* routes.

POST /api/v1/auth/login

Login

Authenticate with your phone number and password to receive a Bearer token. Vendor accounts automatically receive the vendor ability in addition to purchase.

Body Parameters

Parameter Type Required Description
phone string required The user's registered phone number (10 digits).
password string required The user's password.
device_name string optional Label for the token (defaults to User-Agent).
Response 200
{
  "token": "a8f3e2c1d9b47056...",
  "type": "Bearer",
  "abilities": ["purchase", "vendor"],
  "user": {
    "id": 1,
    "name": "Ernest Trekpah",
    "phone": "0244000001"
  }
}
POST /api/v1/auth/logout

Logout

Revoke the current access token. Requires a valid Bearer token.

Response 200
{ "message": "Token revoked." }
GET /api/v1/auth/me

Current User

Returns the authenticated user's profile and whether they have an active vendor account.

Response 200
{
  "id": 1,
  "name": "Ernest Trekpah",
  "phone": "0244000001",
  "is_vendor": true
}

Packages

GET /api/v1/packages

List Packages

Returns all active, visible packages. No authentication required.

Query Parameters

Parameter Type Required Description
search string optional Filter by package name or description.
type_id integer optional Filter by package type ID.
Response 200
{
  "data": [
    {
      "id": 1,
      "name": "Basic 1-Day",
      "slug": "basic-1-day",
      "price": 5.00,
      "description": "Ideal for casual browsing",
      "validity_days": 1,
      "data_limit": "1GB",
      "speed": "10Mbps",
      "bandwidth": null,
      "max_users": 1,
      "type": { "id": 1, "name": "Daily" }
    }
  ]
}
GET /api/v1/packages/{id}

Get Package

Returns a single active, visible package by its numeric ID.

Response 200
{
  "id": 1,
  "name": "Basic 1-Day",
  "slug": "basic-1-day",
  "price": 5.00,
  "description": "Ideal for casual browsing",
  "validity_days": 1,
  "data_limit": "1GB",
  "speed": "10Mbps",
  "type": { "id": 1, "name": "Daily" }
}

Normal Purchase

Purchase flow: Call Create Order → redirect your user to the returned payment_url → notifies the webhook → poll Get Order Status until status is paid and credential is present. Credentials are also sent to the recipient phone via SMS.
GET /api/v1/orders

List Orders

Paginated list of the authenticated user's orders, newest first.

Requires Authorization: Bearer {token} with purchase ability

Query Parameters

Parameter Type Required Description
status string optional Filter by status: pending, paid, failed, cancelled, refunded.
per_page integer optional Results per page. Default: 20.
page integer optional Page number.
Response 200
{
  "data": [
    {
      "order_no": "ORD-ABCDEF12345",
      "status": "paid",
      "amount": 5.00,
      "phone": "0551234567",
      "paid_at": "2025-01-15T10:30:00.000000Z",
      "created_at": "2025-01-15T10:25:00.000000Z",
      "package": { "id": 1, "name": "Basic 1-Day", "price": 5.00, "validity_days": 1 }
    }
  ],
  "meta": {
    "total": 12,
    "per_page": 20,
    "current_page": 1,
    "last_page": 1
  }
}
POST /api/v1/orders

Create Order

Creates an order and initializes a payment. Returns the checkout URL.

Requires Authorization: Bearer {token} with purchase ability

Body Parameters

Parameter Type Required Description
package_id integer required ID of the package to purchase.
phone_number string required Recipient phone number — exactly 10 digits (e.g. 0551234567).
callback_url string optional URL to redirect after payment. Defaults to the order status endpoint.

Optional Header

Header Description
X-Idempotency-Key A UUID you generate per purchase attempt. Prevents duplicate orders on retries. Auto-generated if omitted.
Response 201
{
  "payment_url": "https://checkout.paystack.com/xxxxxxxxxxxxxxxx",
  "order_no": "ORD-ABCDEF12345",
  "idempotency_key": "550e8400-e29b-41d4-a716-446655440000"
}
GET /api/v1/orders/{orderNo}

Get Order Status

Returns the current status of an order. Once status is paid, the credential object will be populated with the hotspot username and password.

Requires Authorization: Bearer {token}
Response 200
{
  "order_no": "ORD-ABCDEF12345",
  "status": "paid",
  "amount": 5.00,
  "phone": "0551234567",
  "paid_at": "2025-01-15T10:30:00.000000Z",
  "created_at": "2025-01-15T10:25:00.000000Z",
  "package": {
    "id": 1,
    "name": "Basic 1-Day",
    "price": 5.00,
    "validity_days": 1
  },
  "credential": {
    "username": "U123456",
    "password": "P789012",
    "status": "unused",
    "expires_at": null
  }
}

Order Status Values

pending paid failed cancelled

Vendor API

All /vendor/* endpoints require a token with the vendor ability and an active vendor account. A 403 is returned if the vendor account has been suspended or deactivated.

GET /api/v1/vendor/profile

Profile & Balance

Returns the authenticated vendor's profile details along with a balance summary of total earnings and withdrawable commission.

Response 200
{
  "vendor": {
    "vendor_no": "VND-0001",
    "vendor_name": "Accra Tech Hub",
    "vendor_email": "hub@example.com",
    "vendor_phone": "0201234567",
    "address": "Ring Road, Accra",
    "vendor_region": "Greater Accra",
    "vendor_status": "active",
    "commission_rate": 8.00,
    "logo_url": "https://example.com/storage/logos/vendor.png",
    "verified_at": "2025-01-01T00:00:00.000000Z"
  },
  "balance": {
    "total_earnings": 420.00,
    "available_balance": 185.00
  }
}
GET /api/v1/vendor/orders

List Vendor Orders

Paginated list of the vendor's orders, newest first.

Query Parameters

Parameter Type Required Description
status string optional Filter by status: pending, paid, failed, cancelled.
per_page integer optional Results per page. Default: 20.
page integer optional Page number.
Response 200
{
  "data": [
    {
      "order_no": "VORD-XYZ123",
      "status": "paid",
      "amount": 50.00,
      "quantity": 10,
      "commission_amount": 4.00,
      "payout_status": "unpaid",
      "customer_phone": "0551234567",
      "customer_name": "Ernes Trekpah",
      "paid_at": "2025-01-15T12:00:00.000000Z",
      "created_at": "2025-01-15T11:55:00.000000Z",
      "package": { "id": 1, "name": "Basic 1-Day", "price": 5.00 }
    }
  ],
  "meta": {
    "total": 48,
    "per_page": 20,
    "current_page": 1,
    "last_page": 3
  }
}
POST /api/v1/vendor/orders

Create Vendor Order

Creates a bulk order for a customer and returns a checkout URL. Each unit in the order generates one hotspot credential. On payment, credentials are delivered to the recipient phone via SMS.

Body Parameters

Parameter Type Required Description
package_id integer required ID of the package to purchase.
recipient_phone string required Customer phone number — exactly 10 digits.
customer_name string optional Customer's name for record-keeping.
quantity integer optional Number of units (1–50). Default: 1.

Optional Header

Header Description
X-Idempotency-Key UUID for this purchase attempt. Prevents duplicate orders on network retries. Auto-generated server-side if omitted.
Response 201
{
  "payment_url": "https://checkout.paystack.com/xxxxxxxxxxxxxxxx",
  "order_no": "VORD-XYZ123456",
  "idempotency_key": "550e8400-e29b-41d4-a716-446655440000"
}
GET /api/v1/vendor/orders/{orderNo}

Get Vendor Order

Returns a single vendor order with all generated credentials once the order is paid.

Response 200
{
  "order_no": "VORD-XYZ123456",
  "status": "paid",
  "amount": 50.00,
  "quantity": 10,
  "commission_amount": 4.00,
  "payout_status": "unpaid",
  "customer_phone": "0551234567",
  "customer_name": "Ernes Trekpah",
  "paid_at": "2025-01-15T12:00:00.000000Z",
  "package": { "id": 1, "name": "Basic 1-Day", "price": 5.00 },
  "credentials": [
    {
      "id": 101,
      "username": "V123456",
      "password": "P789012",
      "status": "unused",
      "expires_at": null,
      "sold_to_phone": null,
      "sold_to_name": null
    }
  ]
}
DELETE /api/v1/vendor/orders/{orderNo}

Cancel Vendor Order

Cancels a pending order. Only orders that have not yet been paid can be cancelled.

Response 200
{ "message": "Order cancelled." }
GET /api/v1/vendor/credentials

List Credentials

Paginated list of all hotspot credentials belonging to the vendor, across all orders.

Query Parameters

Parameter Type Required Description
status string optional Filter by credential status: unused, sold, redeemed, expired.
per_page integer optional Results per page. Default: 20.
Response 200
{
  "data": [
    {
      "id": 101,
      "username": "V123456",
      "password": "P789012",
      "status": "unused",
      "expires_at": null,
      "sold_to_phone": null,
      "sold_to_name": null,
      "sold_at": null,
      "order_no": "VORD-XYZ123456"
    }
  ],
  "meta": { "total": 95, "per_page": 20, "current_page": 1, "last_page": 5 }
}
GET /api/v1/vendor/payouts

List Payouts

Returns payout history for the vendor, with current available balance and minimum payout threshold.

Query Parameters

Parameter Type Required Description
status string optional pending, processing, completed, failed.
per_page integer optional Default: 20.
Response 200
{
  "available_balance": 185.00,
  "minimum_payout": 50.00,
  "data": [
    {
      "reference": "PAY-ABC123-20250115",
      "amount": 120.00,
      "method": "mobile_money",
      "method_label": "Mobile Money",
      "status": "completed",
      "status_label": "Completed",
      "account_details": {
        "type": "mobile_money",
        "network": "MTN",
        "number": "0551234567"
      },
      "processed_at": "2025-01-16T09:00:00.000000Z",
      "created_at": "2025-01-15T18:00:00.000000Z"
    }
  ],
  "meta": { "total": 3, "per_page": 20, "current_page": 1, "last_page": 1 }
}
POST /api/v1/vendor/payouts

Request Payout

Submits a payout request against your available commission balance. Processed within 24–48 hours.

Saved settings shortcut

If you have already saved your payout destination via PUT /vendor/payout-settings, the only required field is amount. All other fields are optional and will fall back to your saved settings automatically.

POST /api/v1/vendor/payouts
{ "amount": 185.00 }

Override / first-time setup — provide full details

Mobile Money

Bank Transfer

Request Body
// With saved settings — amount only
{ "amount": 185.00 }

// First time or override — full details
{
  "amount": 185.00,
  "payout_method": "mobile_money",
  "mobile_network": "MTN",
  "mobile_number": "0551234567"
}
Response 201
{
  "message": "Payout request submitted. It will be processed within 24\u201348 hours.",
  "payout": {
    "reference": "PAY-DEF456-20250115",
    "amount": 185.00,
    "method": "mobile_money",
    "method_label": "Mobile Money",
    "status": "pending",
    "status_label": "Pending",
    "account_details": {
      "type": "mobile_money",
      "network": "MTN",
      "number": "0551234567"
    },
    "processed_at": null,
    "created_at": "2025-01-15T20:00:00.000000Z"
  }
}
GET /api/v1/vendor/payout-settings

Get Payout Settings

Returns the vendor's saved payout destination. Returns null if no settings have been configured yet.

auto_payout and payout_threshold are read-only — they are managed by the platform and cannot be changed through the API.
Response 200
{
  "data": {
    "payout_method": "mobile_money",
    "method_label": "Mobile Money",
    "bank_code": null,
    "bank_name": null,
    "account_number": null,
    "account_name": null,
    "mobile_network": "MTN",
    "mobile_number": "0551234567",
    "auto_payout": false,
    "payout_threshold": null
  }
}
PUT /api/v1/vendor/payout-settings

Save Payout Settings

Create or update the vendor's payout destination. Use bank_code values from List Banks. Mobile network codes from List Networks.

Mobile Money

Bank Transfer

Response 200
{
  "message": "Payout settings saved.",
  "data": {
    "payout_method": "bank_transfer",
    "method_label": "Bank Transfer",
    "bank_code": "040100",
    "bank_name": "GCB Bank Limited",
    "account_number": "1234567890",
    "account_name": "Ernest Trekpah",
    "mobile_network": null,
    "mobile_number": null,
    "auto_payout": false,
    "payout_threshold": null
  }
}

Lookups & Verification

GET /api/v1/vendor/banks

List Banks

Returns the list of Ghana banks supported for payout. Results are cached. Use the code as bank_code when saving payout settings or requesting a payout.

Response 200
{
  "data": [
    { "code": "030100", "name": "Access Bank Ghana Plc" },
    { "code": "040100", "name": "GCB Bank Limited" },
    { "code": "190100", "name": "Stanbic Bank Ghana Limited" }
  ],
  "source": "cache"
}
GET /api/v1/vendor/networks

List Mobile Networks

Returns supported mobile money networks. Use code as the mobile_network value in payout requests and settings.

Response 200
{
  "data": [
    {
      "code": "MTN",
      "name": "MTN Mobile Money",
      "provider": "MTN Ghana",
      "prefixes": ["024", "025", "053", "054", "055", "059"],
      "supports_resolution": true
    },
    {
      "code": "VOD",
      "name": "Telecel Cash (Vodafone)",
      "provider": "Telecel Ghana",
      "prefixes": ["020", "050"],
      "supports_resolution": true
    },
    {
      "code": "ATL",
      "name": "AirtelTigo Money",
      "provider": "AirtelTigo Ghana",
      "prefixes": ["026", "027", "056", "057"],
      "supports_resolution": false
    }
  ]
}
POST /api/v1/vendor/verify/bank-account

Verify Bank Account

Resolves a bank account number and returns the verified account holder name. Call this before saving bank transfer settings to confirm the details are correct.

Body Parameters

Parameter Type Required Description
account_number string required The bank account number (min 6 digits).
bank_code string required Bank code from GET /vendor/banks.
Response 200
{
  "account_number": "1234567890",
  "account_name": "Ernest Trekpah",
  "bank_code": "040100",
  "bank_name": "GCB Bank Limited",
  "verified": true
}
POST /api/v1/vendor/verify/mobile-account

Verify Mobile Account

Validates a mobile money number and auto-detects the network. Returns the account holder name for MTN and Vodafone/Telecel. AirtelTigo is validated by prefix only — account_name will be null.

Body Parameters

Parameter Type Required Description
mobile_number string required 10-digit Ghana mobile number.
Response 200
{
  "phone_number": "0241234567",
  "account_name": "Ernest Trekpah",
  "network_code": "MTN",
  "network_name": "MTN Mobile Money",
  "verified": true,
  "note": null
}

Webhooks

POST /api/v1/webhooks/paystack

Webhook

This endpoint is called by after every payment event. It is not intended to be called by your application — configure it in your dashboard as the webhook URL.

Dashboard Setup

https://oguaahotspot.m-netgh.com/api/v1/webhooks/paystack

charge.success

Marks the order as paid, generates hotspot credentials, and sends them to the customer via SMS.

charge.failed

Marks the order and payment record as failed.

The webhook endpoint verifies the cryptographic signature on every incoming request. Requests with an invalid or missing signature receive a 403.

Error Reference

All error responses follow the same JSON structure. Validation errors additionally include a errors object.

Validation Error 422
{
  "message": "The phone number field must be 10 digits.",
  "errors": {
    "phone_number": [
      "The phone number field must be 10 digits."
    ]
  }
}
Code Status Meaning
401 Unauthorized Missing or invalid Bearer token.
403 Forbidden Token lacks the required ability, or vendor account is not active.
404 Not Found The requested resource does not exist or does not belong to you.
422 Unprocessable Validation failed. See the errors object for field-level messages.
429 Too Many Requests Rate limit exceeded. Back off and retry after the Retry-After header interval.
500 Server Error An unexpected error occurred. Contact support if it persists.