SilentAPI

Introduction

The SilentAPI API is organised around REST. It accepts JSON request bodies, returns JSON responses and uses standard HTTP status codes. All amounts are integers in kobo (₦1 = 100 kobo).

Base URLhttps://silentapi.site/api/v1

Authentication

Authenticate with your secret key in the Authorization header. Keys starting sk_test_ operate in test mode; sk_live_ moves real money. Get your keys →

Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Errors

Every response has a boolean status and a human-readable message. Validation errors include an errors object keyed by field.

CodeMeaning
200 / 201Success
401Missing, invalid or revoked API key
403Account suspended or live mode not activated
404Resource not found
409Duplicate reference
422Validation failed / insufficient balance
500Something went wrong on our side
POST/transactions/initialize.php

Initialize a payment

Creates a pending transaction and returns a hosted checkout URL. Redirect your customer to authorization_url.

FieldTypeDescription
amountintegerRequired. Amount in kobo (min 10000).
emailstringRequired. Customer email.
namestringCustomer name.
referencestringYour unique reference. Generated if omitted.
callback_urlurlWhere we send the customer after payment, with ?reference=&status=
metadataobjectAny JSON you want echoed back in webhooks.
channelsarrayLimit payment methods shown: card, bank, ussd, qr, mobile_money, bank_transfer. Omit for all.
Request
curl -X POST https://silentapi.site/api/v1/transactions/initialize.php \
  -H "Authorization: Bearer sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": 500000,
  "email": "ada@example.com",
  "name": "Ada Okafor",
  "reference": "order_10293",
  "callback_url": "https://yourapp.com/paid",
  "metadata": { "order_id": 10293 }
}'
Response
{
  "status": true,
  "message": "Transaction initialized",
  "data": {
    "reference": "order_10293",
    "authorization_url": "https://silentapi.site/api/v1/../../checkout.php?ref=order_10293",
    "amount": 500000,
    "fee": 7500,
    "status": "pending"
  }
}
GET/transactions/verify.php?reference={ref}

Verify a payment

Always verify server-side before delivering value. Check that status is success and the amount matches.

Request
curl https://silentapi.site/api/v1/transactions/verify.php?reference=order_10293 \
  -H "Authorization: Bearer sk_test_…"
Response
{
  "status": true,
  "data": {
    "reference": "order_10293",
    "status": "success",
    "amount": 500000,
    "fee": 7500,
    "net": 492500,
    "channel": "card",
    "paid_at": "2026-10-08T10:21:44+01:00"
  }
}
GET/transactions/list.php

List transactions

Paginated, newest first. Query: status, page, per_page (max 100).

Request
curl https://silentapi.site/api/v1/transactions/list.php \
  -H "Authorization: Bearer sk_test_…"
GET/balance.php

Wallet balance

Returns the available balance for the key's mode, in kobo.

Request
curl https://silentapi.site/api/v1/balance.php \
  -H "Authorization: Bearer sk_test_…"
Response
{
  "status": true,
  "data": { "currency": "NGN", "available": 12500000, "mode": "test" }
}
POST/virtual-accounts/create.php

Create virtual account

Issues an account for a customer. type is dedicated (a permanent account number) or dynamic (no fixed number: share payment_url, and each payment gets a fresh account number valid 30 minutes). Successful transfers trigger charge.success.

FieldTypeDescription
customer_namestringRequired.
customer_emailstringRequired in live mode.
Request
curl -X POST https://silentapi.site/api/v1/virtual-accounts/create.php \
  -H "Authorization: Bearer sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{
  "customer_name": "Chinedu Eze",
  "customer_email": "chinedu@example.com"
}'
Response
{
  "status": true,
  "data": {
    "reference": "VAC_261008A1B2C3D4E5F6",
    "account_number": "9912345678",
    "account_name": "Your Biz / Chinedu Eze",
    "bank_name": "SilentAPI Test Bank"
  }
}
GET/virtual-accounts/list.php

List virtual accounts

Paginated list of accounts issued in the key's mode.

Request
curl https://silentapi.site/api/v1/virtual-accounts/list.php \
  -H "Authorization: Bearer sk_test_…"
POST/transfers/create.php

Create a transfer (payout)

Debits your wallet (amount + fee) and sends money to a bank account. Test transfers settle instantly; live ones settle within one business day.

FieldTypeDescription
amountintegerRequired. In kobo.
bank_codestringRequired. From /banks.php.
account_numberstringRequired. 10 digits.
account_namestringRequired.
narrationstringOptional.
referencestringOptional unique reference.
Request
curl -X POST https://silentapi.site/api/v1/transfers/create.php \
  -H "Authorization: Bearer sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": 2000000,
  "bank_code": "058",
  "account_number": "0123456789",
  "account_name": "Ada Okafor",
  "narration": "Vendor payment",
  "reference": "payout_7781"
}'
GET/transfers/list.php

List / fetch transfers

Pass ?reference= to fetch a single transfer.

Request
curl https://silentapi.site/api/v1/transfers/list.php \
  -H "Authorization: Bearer sk_test_…"
POST/refunds/create.php

Refund a payment

Refunds all or part of a successful payment. Your wallet is debited immediately; if the card network rejects the refund the money is returned to your wallet and you receive refund.failed. Bank-transfer deposits to virtual accounts can't be refunded — send a transfer instead.

FieldTypeDescription
transactionstringRequired. Reference of the payment to refund.
amountintegerIn kobo. Omit for a full refund.
merchant_notestringInternal reason.
Request
curl -X POST https://silentapi.site/api/v1/refunds/create.php \
  -H "Authorization: Bearer sk_test_…" \
  -H "Content-Type: application/json" \
  -d '{
  "transaction": "order_10293",
  "amount": 200000,
  "merchant_note": "Item out of stock"
}'
Response
{
  "status": true,
  "message": "Refund pending",
  "data": {
    "reference": "RFD_2610089A1B2C3D4E5F",
    "transaction_reference": "order_10293",
    "amount": 200000,
    "status": "pending"
  }
}
GET/refunds/list.php

List / fetch refunds

Paginated list. Pass ?reference= to fetch one refund.

Request
curl https://silentapi.site/api/v1/refunds/list.php \
  -H "Authorization: Bearer sk_test_…"
GET/banks.php

List banks

Supported Nigerian banks and their codes.

Request
curl https://silentapi.site/api/v1/banks.php \
  -H "Authorization: Bearer sk_test_…"
GET/resolve-account.php?account_number=0123456789&bank_code=058

Resolve account name

Confirms the account holder's name before you send a transfer. Always show this name to your user before paying out.

FieldTypeDescription
account_numberstringRequired. 10-digit NUBAN.
bank_codestringRequired. From /banks.php.
Request
curl https://silentapi.site/api/v1/resolve-account.php?account_number=0123456789&bank_code=058 \
  -H "Authorization: Bearer sk_test_…"
Response
{
  "status": true,
  "data": {
    "account_number": "0123456789",
    "bank_code": "058",
    "account_name": "ADA OKAFOR"
  }
}

Webhooks

We send a POST with a JSON body to your webhook URL whenever an event happens. Respond with any 2xx quickly and process the event asynchronously. Verify every request with the X-SilentAPI-Signature header — an HMAC-SHA512 of the raw body using your webhook signing secret.

// PHP
$payload = file_get_contents('php://input');
$expected = hash_hmac('sha512', $payload, getenv('SILENTAPI_WEBHOOK_SECRET'));
if (!hash_equals($expected, $_SERVER['HTTP_X_SILENTAPI_SIGNATURE'] ?? '')) {
    http_response_code(401); exit;
}
$event = json_decode($payload, true);
if ($event['event'] === 'charge.success') {
    // re-verify via /transactions/verify.php, then fulfil the order
}
http_response_code(200);
// Node.js (Express)
const sig = crypto.createHmac('sha512', process.env.SILENTAPI_WEBHOOK_SECRET)
  .update(req.rawBody).digest('hex');
if (sig !== req.get('X-SilentAPI-Signature')) return res.sendStatus(401);

Events: charge.success, charge.failed, transfer.success, transfer.failed, refund.processed, refund.failed, ping.

Test mode

Use your sk_test_ key to build safely. The hosted checkout lets you simulate successful or declined payments, test virtual accounts accept simulated deposits from the dashboard, and test transfers settle instantly. Nothing in test mode touches real money.