DottsPay
API reference

DottsPay API v1

A JSON API over HTTPS. Use it to create checkouts, verify and refund payments, manage payment links, and look up banks and balances.

Base URL

Text
https://dottspay.hiddekellabs.com/api/v1

All requests must use HTTPS. Request and response bodies are JSON.

Authentication

Send your secret key as a bearer token on every request. Find your keys in Dashboard → Developers.

HTTP
Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxx
sk_test_…
UseTest mode. Never moves real money. Objects you create are test objects.
sk_live_…
UseLive mode. Real payments. Works once your account is approved.
pk_…
UsePublic key. Not needed for server calls. Never send a secret key to a browser.

Test and live data are separate. A test key cannot see live transactions and the other way round. See Test mode.

Responses

Every response uses the same envelope. On success, status is true and the result is in data.

200 Response
{
  "status": true,
  "message": "Checkout session created",
  "data": {
    "id": "cs_8Kq2LmT4xPz9WbN3vR6hYd",
    "…": "…"
  }
}

On failure, the HTTP status is 4xx or 5xx, status is false, and code tells you what went wrong in a form your code can check.

422 Response
{
  "status": false,
  "message": "amount: Too small: expected number to be >=100",
  "code": "validation_error"
}

Errors

unauthorized
HTTP401
MeaningThe secret key is missing, malformed, revoked or wrong.
merchant_suspended
HTTP403
MeaningYour account is suspended. Contact support.
merchant_not_live
HTTP403
MeaningYou used a live key before live mode was switched on for your account.
not_found
HTTP404
MeaningThe object does not exist, or belongs to the other mode (test or live).
invalid_json
HTTP400
MeaningThe request body is not valid JSON.
validation_error
HTTP422
MeaningA parameter is missing or invalid. The message names the field.
idempotency_mismatch
HTTP422
MeaningYou reused an Idempotency-Key with a different request body.
currency_unavailable
HTTP422
MeaningThat currency is not enabled for your account.
rate_limited
HTTP429
MeaningMore than 120 requests in a minute with one key. Wait and retry.
server_error
HTTP500
MeaningSomething went wrong on our side. It is safe to retry with the same Idempotency-Key.

Retry rate_limited and server_error with a backoff. Do not retry other 4xx errors without changing the request.

Amounts

Amounts are integers in the currency's subunit. Every currency uses 1/100 units, so for NGN, ₦5,000 is 500000 kobo, and for USD, $12.50 is 1250 cents. Never send decimals.

Idempotency

Networks fail. To retry a request safely, send an Idempotency-Key header with a unique value, such as your own order ID. It is supported on POST /checkout/sessions, POST /refunds and POST /payment-links.

HTTP
Idempotency-Key: order-1042

If DottsPay has already seen that key with the same body, it returns the original response without doing the work again, and adds the header Idempotent-Replayed: true. Reusing a key with a different body returns 422 idempotency_mismatch.

Pagination

List endpoints take perPage (default 50, max 100) and page (starting at 1). They return the items in data and the totals in meta.

200 Response
{
  "status": true,
  "message": "OK",
  "data": [
    {
      "…": "…"
    }
  ],
  "meta": {
    "page": 2,
    "perPage": 50,
    "total": 137
  }
}

Rate limits

Each secret key can make 120 requests per minute. Past that, requests fail with 429 rate_limited until the minute rolls over.

About the Node examples
Node examples use the Node SDK and assume a client created with new DottsPay(process.env.DOTTSPAY_SECRET_KEY). SDK methods return the contents of data directly.

Checkout sessions

A checkout session is a hosted payment page for one payment. Create it on your server, redirect the customer to checkout_url, then verify the transaction when they return.

The checkout object

Attributes
idstring
Unique ID, starts with cs_.
checkout_urlstring
The hosted page to send your customer to.
statusstring
open, completed or expired.
modestring
test or live.
amountinteger
Amount in the subunit.
currencystring
ISO currency code, for example NGN.
emailstring | null
Customer email, if you sent one.
metadataobject | null
Your own key-value data, returned as you sent it.
callback_urlstring | null
Where the customer goes after paying.
expires_atstring
ISO 8601 time after which the session can no longer be paid.
created_atstring
ISO 8601 creation time.

Create a checkout session

POST/checkout/sessions

Supports Idempotency-Key.

Body parameters
amountintegerRequired
Amount in the subunit. Minimum 100.
currencystringOptional
ISO currency code. Default NGN.
emailstringOptional
Customer email. If you leave it out, the customer enters it on the checkout page.
namestringOptional
Customer name.
phonestringOptional
Customer phone number.
callback_urlstringOptional
After payment, DottsPay redirects to this URL with ?reference=dp_…&status=success or status=failed. Always verify the reference on your server.
metadataobjectOptional
Any JSON object. Copied onto the transaction and returned in webhooks.
curl -X POST "https://dottspay.hiddekellabs.com/api/v1/checkout/sessions" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY" \
  -H "Idempotency-Key: order-1042" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 500000,
    "email": "ada@example.com",
    "callback_url": "https://yourshop.com/payment/callback",
    "metadata": {
      "order_id": "ord_1042"
    }
  }'
Response
Response
{
  "status": true,
  "message": "Checkout session created",
  "data": {
    "id": "cs_8Kq2LmT4xPz9WbN3vR6hYd",
    "checkout_url": "https://dottspay.hiddekellabs.com/pay/c/cs_8Kq2LmT4xPz9WbN3vR6hYd",
    "status": "open",
    "mode": "test",
    "amount": 500000,
    "currency": "NGN",
    "email": "ada@example.com",
    "metadata": {
      "order_id": "ord_1042"
    },
    "callback_url": "https://yourshop.com/payment/callback",
    "expires_at": "2026-10-13T09:30:12.000Z",
    "created_at": "2026-10-12T09:30:12.000Z"
  }
}

Retrieve a checkout session

GET/checkout/sessions/{id}

Returns a checkout object.

Path parameters
idstringRequired
The session ID, starting with cs_.
curl "https://dottspay.hiddekellabs.com/api/v1/checkout/sessions/cs_8Kq2LmT4xPz9WbN3vR6hYd" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "OK",
  "data": {
    "id": "cs_8Kq2LmT4xPz9WbN3vR6hYd",
    "checkout_url": "https://dottspay.hiddekellabs.com/pay/c/cs_8Kq2LmT4xPz9WbN3vR6hYd",
    "status": "completed",
    "mode": "test",
    "amount": 500000,
    "currency": "NGN",
    "email": "ada@example.com",
    "metadata": {
      "order_id": "ord_1042"
    },
    "callback_url": "https://yourshop.com/payment/callback",
    "expires_at": "2026-10-13T09:30:12.000Z",
    "created_at": "2026-10-12T09:30:12.000Z"
  }
}

Transactions

A transaction is one payment attempt. It is created when a customer starts paying through a checkout session or a payment link.

The transaction object

Attributes
idstring
Unique ID.
referencestring
Your handle for this payment, starts with dp_. Use it to verify and refund.
statusstring
pending, success, failed, abandoned or reversed.
modestring
test or live.
amountinteger
The amount you asked for, in the subunit.
charged_amountinteger
What the customer paid. Higher than amount when the customer bears the fee.
feesinteger
Total fees for this payment.
netinteger
What you receive after fees.
currencystring
ISO currency code.
channelstring | null
How the customer paid, for example card or bank_transfer.
fee_bearerstring
merchant or customer.
settlementstring
split (paid straight to your bank), scheduled or on_demand.
customerobject
email, name and phone. Any of them can be null.
custom_fieldsobject | null
Answers to custom fields on a payment link.
metadataobject | null
The metadata from the checkout session.
payment_link_idstring | null
Set when the payment came through a payment link.
checkout_session_idstring | null
Set when the payment came through a checkout session.
failure_reasonstring | null
Why the payment failed, when it did.
paid_atstring | null
ISO 8601 time the payment succeeded.
created_atstring
ISO 8601 creation time.

List transactions

GET/transactions

Returns transactions for the key's mode, newest first.

Query parameters
statusstringOptional
Only this status: pending, success, failed, abandoned or reversed.
fromstringOptional
ISO date. Only transactions created on or after it.
tostringOptional
ISO date. Only transactions created on or before it.
perPageintegerOptional
Results per page. Default 50, maximum 100.
pageintegerOptional
Page number, starting at 1. Default 1.
curl "https://dottspay.hiddekellabs.com/api/v1/transactions?status=success&from=2026-10-01&perPage=20" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "OK",
  "data": [
    {
      "id": "cm2x9k1f00004l708qv3t2abc",
      "reference": "dp_Hk2pQx9LmT4sWb7NcY",
      "status": "success",
      "mode": "test",
      "amount": 500000,
      "charged_amount": 500000,
      "fees": 7500,
      "net": 492500,
      "currency": "NGN",
      "channel": "card",
      "fee_bearer": "merchant",
      "settlement": "split",
      "customer": {
        "email": "ada@example.com",
        "name": "Ada Obi",
        "phone": "+2348012345678"
      },
      "custom_fields": null,
      "metadata": {
        "order_id": "ord_1042"
      },
      "payment_link_id": null,
      "checkout_session_id": "cs_8Kq2LmT4xPz9WbN3vR6hYd",
      "failure_reason": null,
      "paid_at": "2026-10-12T09:31:04.000Z",
      "created_at": "2026-10-12T09:30:12.000Z"
    }
  ],
  "meta": {
    "page": 1,
    "perPage": 50,
    "total": 1
  }
}

Verify a transaction

GET/transactions/{reference}

Fetch a transaction by reference. If it is still pending, DottsPay checks with the payment network first, so the answer is as fresh as it can be. Call this before you give value.

Path parameters
referencestringRequired
The reference, starting with dp_.
curl "https://dottspay.hiddekellabs.com/api/v1/transactions/dp_Hk2pQx9LmT4sWb7NcY" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "Transaction retrieved",
  "data": {
    "id": "cm2x9k1f00004l708qv3t2abc",
    "reference": "dp_Hk2pQx9LmT4sWb7NcY",
    "status": "success",
    "mode": "test",
    "amount": 500000,
    "charged_amount": 500000,
    "fees": 7500,
    "net": 492500,
    "currency": "NGN",
    "channel": "card",
    "fee_bearer": "merchant",
    "settlement": "split",
    "customer": {
      "email": "ada@example.com",
      "name": "Ada Obi",
      "phone": "+2348012345678"
    },
    "custom_fields": null,
    "metadata": {
      "order_id": "ord_1042"
    },
    "payment_link_id": null,
    "checkout_session_id": "cs_8Kq2LmT4xPz9WbN3vR6hYd",
    "failure_reason": null,
    "paid_at": "2026-10-12T09:31:04.000Z",
    "created_at": "2026-10-12T09:30:12.000Z"
  }
}

Refunds

Refund a successful transaction in full or in part. You can make several partial refunds until the full amount is used up.

The refund object

Attributes
idstring
Unique ID.
transaction_referencestring
The dp_ reference of the refunded transaction.
amountinteger
Refunded amount in the subunit.
currencystring
ISO currency code.
statusstring
pending, processed or failed.
reasonstring | null
The reason you gave.
created_atstring
ISO 8601 creation time.

Create a refund

POST/refunds

Supports Idempotency-Key. A refund.created webhook follows.

Body parameters
referencestringRequired
The dp_ reference of a successful transaction.
amountintegerOptional
Amount to refund in the subunit. Default: everything not yet refunded.
reasonstringOptional
A note for your records.
curl -X POST "https://dottspay.hiddekellabs.com/api/v1/refunds" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY" \
  -H "Idempotency-Key: refund-ord_1042-1" \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "dp_Hk2pQx9LmT4sWb7NcY",
    "amount": 200000,
    "reason": "Customer returned one item"
  }'
Response
Response
{
  "status": true,
  "message": "Refund created",
  "data": {
    "id": "cm2xa3b7n0009l708h4kd9xyz",
    "transaction_reference": "dp_Hk2pQx9LmT4sWb7NcY",
    "amount": 200000,
    "currency": "NGN",
    "status": "pending",
    "reason": "Customer returned one item",
    "created_at": "2026-10-12T14:02:45.000Z"
  }
}

Customers

DottsPay records a customer the first time an email address pays you.

The customer object
idstring
Unique ID.
emailstring
Email address.
namestring | null
Name, if known.
phonestring | null
Phone number, if known.
created_atstring
ISO 8601 creation time.

List customers

GET/customers
Query parameters
perPageintegerOptional
Results per page. Default 50, maximum 100.
pageintegerOptional
Page number, starting at 1. Default 1.
curl "https://dottspay.hiddekellabs.com/api/v1/customers" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "OK",
  "data": [
    {
      "id": "cm2x9k1ez0002l708m6p0aaaa",
      "email": "ada@example.com",
      "name": "Ada Obi",
      "phone": "+2348012345678",
      "created_at": "2026-10-12T09:31:04.000Z"
    }
  ],
  "meta": {
    "page": 1,
    "perPage": 50,
    "total": 1
  }
}

Banks

Look up bank codes and confirm account names, for example before you save a customer's payout details.

List banks

GET/banks
Query parameters
currencystringOptional
ISO currency code. Default NGN.
curl "https://dottspay.hiddekellabs.com/api/v1/banks?currency=NGN" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "OK",
  "data": [
    {
      "code": "044",
      "name": "Access Bank"
    },
    {
      "code": "058",
      "name": "Guaranty Trust Bank"
    },
    {
      "code": "999992",
      "name": "OPay"
    },
    {
      "code": "…",
      "name": "…"
    }
  ]
}

Resolve an account number

GET/banks/resolve
Query parameters
account_numberstringRequired
The 10-digit account number.
bank_codestringRequired
The bank's code from List banks.
curl "https://dottspay.hiddekellabs.com/api/v1/banks/resolve?account_number=0123456789&bank_code=058" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "OK",
  "data": {
    "account_name": "ADA OBI"
  }
}

Balance

Retrieve your balance

GET/balance

Returns one entry per currency. This only matters for pooled settlement (scheduled or on_demand). With split settlement, money goes straight to your bank and these numbers stay at zero.

Attributes
currencystring
ISO currency code.
availableinteger
Ready to be paid out, in the subunit.
pending_payoutinteger
Already queued for payout, in the subunit.
curl "https://dottspay.hiddekellabs.com/api/v1/balance" \
  -H "Authorization: Bearer $DOTTSPAY_SECRET_KEY"
Response
Response
{
  "status": true,
  "message": "OK",
  "data": [
    {
      "currency": "NGN",
      "available": 18450000,
      "pending_payout": 5000000
    }
  ]
}