API Reference ← Back to site Get Started
Developers

HitchPay API reference.

One API for multi-currency accounts, payments, cards, FX and cross-border payouts. Questions? Email [email protected].

Overview

The HitchPay API is a RESTful interface for building multi-currency accounts, wallets, USD cards, FX, payments and cross-border payouts across African markets and global corridors. All requests and responses use JSON.

Sandbox   https://sandbox.hitchpay.ng Production   https://api.hitchpay.ng

All endpoints are versioned under /v1/. Authenticate with OAuth 2.0 (client credentials) and send the Bearer token on every request.

Responses & errors

Every response uses a consistent envelope. Successful calls return status: "success" with a data object; errors return status: "error" with a code and message.

{ "status": "success", "message": "...", "data": { } } { "status": "error", "code": "INVALID_REQUEST", "message": "..." }
CodeMeaning
INVALID_REQUESTMalformed or missing parameters (400)
INVALID_TOKENMissing, expired or invalid access token (401)
KYC_REQUIREDCustomer must complete KYC first (403)
DUPLICATE_REQUESTA request with this reference already exists (409)

Pass a unique reference on write operations for idempotency. Standard HTTP status codes apply (200, 201, 400, 401, 403, 404, 409, 500).

Authentication

OAuth 2.0 Client Credentials grant. Tokens are valid for one hour.

POST/v1/oauth/token

Generate access token

Authenticate with the OAuth 2.0 Client Credentials grant using your client_id and client_secret from the HitchPay Dashboard. The returned Bearer token is valid for 3600 seconds (1 hour).

Headers
Content-Type: application/x-www-form-urlencoded
Request body
{ "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "grant_type": "client_credentials" }
Response
{ "status": "success", "message": "Access token generated successfully", "data": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } }
POST/v1/oauth/token

Refresh access token

Exchange a valid refresh_token for a new access token without re-sending your credentials.

Headers
Content-Type: application/x-www-form-urlencoded
Request body
{ "grant_type": "refresh_token", "refresh_token": "YOUR_REFRESH_TOKEN", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET" }
Response
{ "status": "success", "message": "Access token generated successfully", "data": { "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "eyJhbGciOi..." } }

Wallet

Balances across your currency wallets.

GET/v1/wallet/balance

Get wallet balance

Retrieve available and ledger balances across all your currency wallets.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN
Response
{ "status": "success", "message": "Wallet balance retrieved successfully.", "data": { "balances": [ { "currency": "NGN", "available_balance": 38646.97, "ledger_balance": 79975.00 }, { "currency": "USD", "available_balance": 2000.00, "ledger_balance": 0.00 }, { "currency": "KES", "available_balance": 15000.00, "ledger_balance": 15000.00 }, { "currency": "GHS", "available_balance": 500.00, "ledger_balance": 500.00 } ] } }

Payments

Accept payments via hosted checkout and virtual accounts.

POST/v1/payments/initiate

Initiate payment

Start a payment and receive a hosted checkout URL to redirect your customer to. Pass a unique reference for idempotency.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN Content-Type: application/json
Request body
{ "amount": 100, "currency": "USD", "reference": "REF_001", "callback_url": "https://yourapp.com/callback", "allow_currency_selection": true, "customer": { "name": "John Doe", "email": "[email protected]", "phone": "08012345678" } }
Response
{ "status": "success", "message": "Payment initiated successfully.", "data": { "reference": "HCHK248EBF3863", "payment_url": "https://checkout.hitchpay.ng/pay/HCHK248EBF3863" } }
GET/v1/payments/verify/{reference}

Verify payment

Confirm the final status of a payment using its reference.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN
Response
{ "status": "success", "message": "Payment verified", "data": { "status": "successful", "amount": "100.00", "currency": "NGN", "amount_paid": "100.50", "reference": "HCHK380B3716D4", "paid_at": "2025-11-06T01:59:23.000Z", "payment_channel": "dynamic_account", "customer": { "name": "Jane Doe", "email": "[email protected]" } } }
POST/v1/payments/dynamic-account

Create dynamic account

Generate a temporary virtual bank account for a single payment. The account is valid for 15 minutes unless payment is received.

Headers
Authorization: Bearer {access_token} Content-Type: application/json
Request body
{ "reference": "1232456789", "amount": 1000, "currency": "NGN", "description": "Testing" }
Response
{ "status": "success", "message": "Dynamic account generated. Awaiting payment.", "data": { "tracking_id": "EXTPAYA2165E437665", "merchant_reference": "1232456789", "account_number": "6020006173", "account_name": "HitchAfricaTech Checkout", "amount": 1000, "currency": "NGN", "valid_for": 900, "expires_in": "15 minutes", "status": "pending" } }

Banking

Issue virtual NGN, USD, GBP & EUR accounts for your customers.

POST/v1/customer/generate-account

Create static account

Generate a permanent, reusable virtual account number for a KYC-verified customer.

Headers
Authorization: Bearer {access_token} Content-Type: application/json
Request body
{ "customer_id": "01113ca3-d86e-4812-ace7-69fe7d72fb4f", "bank_type": "dotbank" }
Response
{ "status": "success", "message": "Account generated successfully.", "data": { "tracking_id": "EXTACCT75718C8F163A", "account_number": "1000164160", "account_name": "Olajide Olamide", "bank_name": "Dot MFB", "bank_code": "50162", "provider": "dotbank", "status": "active", "date_created": "1776705788" } }

Customer & KYC

Enroll customers and complete identity verification.

POST/v1/customer/enroll

Enroll customer

Create a customer record. Customers start with a pending_kyc status until KYC is submitted and approved.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN Content-Type: application/json
Request body
{ "customerid": "CUST_001", "email": "[email protected]", "phone": "07068363556", "firstname": "Olajide", "lastname": "Olamide", "dob": "12-04-1990", "nationality": "NG", "image": "https://storage.yourapp.com/customers/profile-abc123.jpg", "address": { "house_no": 2, "street": "12 Victoria Island Road", "city": "Lagos", "state": "Lagos", "postal_code": "100001", "country": "NG" } }
Response
{ "status": "success", "message": "Customer created successfully.", "data": { "uuid": "42feffe9-d625-412e-bfa5-2f3089a11735", "customerid": "CUST_001", "firstname": "Olajide", "lastname": "Olamide", "email": "[email protected]", "phone": "07068363556", "created_at": "1773591858", "kyc_status": "pending_kyc" } }
POST/v1/customer/{uuid}/kyc

Submit KYC

Submit identity documents for a customer. Verification runs asynchronously; the result is delivered via the kyc.approved / kyc.rejected webhooks.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN Content-Type: application/json
Request body
{ "type": "drivers_license", "country": "NG", "document_front": "https://storage.yourapp.com/kyc/id-front-abc123.jpg", "document_back": "https://storage.yourapp.com/kyc/id-back-abc123.jpg" }
Response
{ "status": "success", "message": "KYC information submitted successfully. Verification is in progress.", "data": { "uuid": "42feffe9-d625-412e-bfa5-2f3089a11735", "customerid": "2912", "kyc_status": "pending" } }

Global payments

Cross-border transfers and collections with live FX.

GET/v1/crossborder/rates

Get exchange rate

Fetch a live quote for a cross-border conversion.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN
Query parameters
ParamDescription
source_currencyCurrency being sent
destination_currencyCurrency the recipient receives
amountAmount in the source currency
Response
{ "status": "success", "message": "Rate retrieved successfully.", "data": { "source_currency": "USD", "destination_currency": "NGN", "source_amount": 10, "destination_amount": 16000, "exchange_rate": 1600.0, "fee": 0.5, "fee_currency": "USD" } }
POST/v1/crossborder/global-transfer

Initiate transfer

Send a cross-border payout to a bank account or mobile-money wallet. Use GET /crossborder/channels and /networks to resolve channel_id and network_id.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN Content-Type: application/json
Request body
{ "customer_uuid": "dda04ec3-3774-4750-ae7b-0c070e8d084b", "amount": 100, "source_currency": "USD", "destination_currency": "KES", "reference": "REF_BANK_001", "reason": "School fees", "beneficiary": { "account_name": "Jane Doe", "account_number": "0123456789", "network_id": "30f11b2e-0905-4c09-ba5f-d05aa4e4a11c", "channel_id": "de274d59-46b3-49a8-8836-3c0cc5b73a4f", "account_type": "bank", "country_code": "KE" } }
Response
{ "status": "success", "message": "Cross-border transfer initiated successfully.", "data": { "reference": "HTCB13BE4DAC468B", "external_reference": "REF_BANK_001", "status": "processing", "provider_status": "created", "provider_reference": "81939272-9c53-5671-8dd3-0a445ef19c48", "amount_sent": 100, "source_currency": "USD", "estimated_amount_received": 12873.28, "destination_currency": "KES" } }
GET/v1/crossborder/global-transfer/{reference}

Get transfer status

Poll the status of a cross-border transfer.

Headers
Authorization: Bearer {ACCESS_TOKEN}
Response
{ "status": "success", "message": "Transfer status retrieved successfully.", "data": { "reference": "HTCBE5C7CAE5A463", "external_reference": "REF_BANK_001", "status": "processing", "amount_sent": 100, "source_currency": "USD", "estimated_amount_received": 12873.28, "destination_currency": "KES", "failure_reason": null, "beneficiary": { "account_name": "Jane Doe", "country_code": "KE", "account_type": "bank" } } }
POST/v1/crossborder/global-collection

Initiate collection

Collect funds cross-border from a payer via bank or mobile money.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN Content-Type: application/json
Request body
{ "customer_uuid": "dda04ec3-3774-4750-ae7b-0c070e8d084b", "amount": 5000, "currency": "KES", "channel_id": "de274d59-46b3-49a8-8836-3c0cc5b73a4f", "account_number": "254722123456", "network_id": "30f11b2e-0905-4c09-ba5f-d05aa4e4a11c", "reason": "entertainment", "reference": "REF7292901912", "dial_code": "+254", "account_type": "bank", "country_code": "KE" }
Response
{ "status": "success", "message": "Cross-border collection initiated successfully.", "data": { "reference": "HTCCBEF4EC275285", "external_reference": "REF7292901912", "status": "processing", "amount": 5000, "currency": "KES", "account_type": "bank", "bankInfo": { "accountName": "HitchPay Collections", "accountNumber": "1234567890", "bankName": "National Bank of Kenya", "bankCode": "52" } } }
GET/v1/crossborder/channels

Channels & networks

List supported payout channels, then GET /v1/crossborder/networks for the banks and mobile-money operators on each channel. Use the returned channel_id and network_id when initiating transfers and collections.

Headers
Authorization: Bearer YOUR_ACCESS_TOKEN
Response
{ "status": "success", "message": "Channels retrieved successfully.", "data": [ { "channel_id": "de274d59-...", "name": "Bank", "country_code": "KE" } ] }

Webhooks

HitchPay sends real-time HTTP callbacks to your endpoint for asynchronous events. Every request includes an x-hitchpay-signature header — an HMAC SHA256 digest of the raw request body, keyed with your webhook_secret.

Verifying a signature

Compute an HMAC SHA256 of the raw request body, prefix it with sha256=, and compare it to the header. Always use the unparsed body (req.rawBody).

const crypto = require('crypto');\n\nfunction verifyWebhook(req, webhookSecret) {\n const signature = req.headers['x-hitchpay-signature'];\n const computed = 'sha256=' + crypto\n .createHmac('sha256', webhookSecret)\n .update(req.rawBody)\n .digest('hex');\n return computed === signature;\n}

Webhook events

EventFires when
payment.successA payment is completed successfully
payment.failedA payment fails or is abandoned
kyc.approvedA customer's KYC is approved
kyc.rejectedA customer's KYC is rejected
crossborder.transfer.successA cross-border transfer settles
crossborder.transfer.failedA cross-border transfer fails
crossborder.collection.successA cross-border collection settles
crossborder.collection.failedA cross-border collection fails
This reference covers the core endpoints. For recipes, bills payment and the full parameter reference, contact [email protected].