Trite logo
Seamless payments across Africa and beyond
Back to Home

API Reference

Detailed information about endpoints, parameters, and responses.

SDKs & Libraries

Official libraries for Node.js, Python, PHP, and more.

API Documentation

Accept payments programmatically: create payment sessions, share checkout links with your customers, and receive signed webhooks when money moves.

Getting started

The API is served from https://api.trite.tech. Create an API key in the dashboard under Settings → Integrations → API Management.

Format Info

All requests and responses are JSON. Amounts are decimal major units (e.g. 25.50) with an ISO currency code.

Authentication

Pass your key as a bearer token on every request. Your merchant account is derived from the key — there is no merchant ID parameter.

Header
Authorization: Bearer trite_sk_...

Keep your API key secure

Missing or invalid keys receive 401. The full key is shown exactly once at creation — store it securely. Keys look like trite_sk_… and can be revoked at any time. Never use your API key in browser or mobile code — server-side only.

Merchant verification

The direct charge endpoints move money on a payer's behalf, so they require your merchant account to be fully verified. This means:

  1. Email verified — confirm your email address via the link sent at registration.
  2. KYC approved — submit identity verification documents in the merchant portal under Settings and receive approval.

If either requirement is not met, those calls return 403 with a machine-readable code field:

HTTP 403 — Email Not Verified
{
  "error": "Merchant account email is not verified. Please verify your email in the merchant portal.",
  "code": "EMAIL_NOT_VERIFIED"
}
HTTP 403 — KYC Not Approved
{
  "error": "Merchant KYC verification is required. Please complete identity verification in the merchant portal.",
  "code": "KYC_NOT_APPROVED",
  "kyc_status": "PENDING"
}

KYC Status Values

The kyc_status field will be one of: PENDING, IN_REVIEW, APPROVED, REJECTED, EXPIRED, or null (no KYC record submitted yet). Only APPROVED grants API access.

Create a payment session

Creates a checkout session and returns a payment_url to hand to your customer. Sessions expire after 24 hours.

POST /api/v1/payments/initiate
curl https://api.trite.tech/api/v1/payments/initiate \
  -H "Authorization: Bearer trite_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 25.50,
    "currency": "GHS",
    "description": "Order #1234",
    "redirect_url": "https://yourstore.com/thank-you",
    "customer_email": "ama@example.com",
    "customer_name": "Ama Serwaa",
    "customer_phone": "0244123456"
  }'
HTTP 201 Created
{
  "session_id": "3f6b1c9e-...",
  "payment_url": "https://pay.trite.tech/pay/3f6b1c9e-...",
  "amount": 25.5,
  "currency": "GHS",
  "expires_at": "2026-07-08T12:00:00.000Z"
}

A session created without customer_email or customer_phone still succeeds, with a warnings array in the response. Treat those warnings as errors in waiting.

Body Parameters
FieldTypeNotes
amountnumberRequired. Positive, major units.
currencystringOptional, default USD.
descriptionstringOptional, shown at checkout.
redirect_urlstringOptional, payer is sent here after payment.
customer_emailstringWho is paying. Will become required — sessions without it are accepted for now and return a warning. Identifies the payer in your customer directory, and is the only identity we get on crypto payments.
customer_namestringOptional. Shown in your customer directory.
customer_phonestringOptional. Local or international format. Prefills the mobile money field at checkout, and is the strongest way to recognise a returning payer.
Errors: 400 invalid input, 401 bad key, 403 merchant is not currently accepting payments, 429 rate limited, 500 server error.

Check session status

Returns the session and its latest transaction. Prefer webhooks over polling for real-time updates.

GET /api/v1/payments/{session_id}/status
curl https://api.trite.tech/api/v1/payments/3f6b1c9e-.../status \
  -H "Authorization: Bearer trite_sk_..."
HTTP 200 OK
{
  "session_id": "3f6b1c9e-...",
  "status": "COMPLETED",
  "amount": 25.5,
  "currency": "GHS",
  "description": "Order #1234",
  "expires_at": "2026-07-08T12:00:00.000Z",
  "created_at": "2026-07-07T12:00:00.000Z",
  "transaction": {
    "transaction_id": "9a2d...",
    "tx_id_display": "TX-8F3K2M",
    "status": "SETTLED",
    "method": "MOBILE_MONEY",
    "amount": 25.5,
    "currency": "GHS",
    "failure_reason": null
  }
}
Sessions belonging to a different merchant return 404.

Direct charge

Debit a mobile money wallet from your own backend, with no Trite-hosted checkout page. The payer approves the charge on their handset. Ghana mobile money only — GHS is the only supported currency.

POST /api/v1/payments/charge
curl https://api.trite.tech/api/v1/payments/charge \
  -H "Authorization: Bearer trite_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 200,
    "mobile_number": "0249713683",
    "provider": "MTN",
    "currency": "GHS",
    "description": "Order #1234"
  }'
HTTP 202 Accepted
{
  "reference": "TX-8F3K2M-A1B2C3D4",
  "transaction_id": "9a2d...",
  "session_id": "3f6b1c9e-...",
  "status": "INITIATED",
  "amount": 200,
  "currency": "GHS",
  "message": "Payment prompt sent to your phone. Please approve it."
}
Body Parameters
FieldTypeNotes
amountnumberRequired. Positive, major units — 200 means GHS 200.00.
mobile_numberstringRequired. The payer's mobile money number.
providerstringRequired. MTN, TELECEL, or AT. Not inferred from the number — a ported line would charge the wrong network.
currencystringOptional, default GHS. No other value is accepted.
descriptionstringOptional, shown on the payer's prompt where the network supports it.
payer_emailstringOptional. Recorded against the transaction and added to your customer directory once the charge settles.
payer_namestringOptional. Names the payer in your customer directory instead of showing a bare phone number.
Response status values
statusHTTPWhat to do
INITIATED202The prompt is on the payer's handset. Wait for your webhook.
OTP_REQUIRED202Collect the OTP the payer was texted and submit it below.
FAILED422The charge was rejected outright. message says why.

When a charge returns OTP_REQUIRED, submit the code against the same reference. The response uses the shapes above.

POST /api/v1/payments/charge/submit-otp
curl https://api.trite.tech/api/v1/payments/charge/submit-otp \
  -H "Authorization: Bearer trite_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "TX-8F3K2M-A1B2C3D4",
    "otp": "123456"
  }'

To read a charge's current state, use its reference. Terminal states are SETTLED and FAILED.

GET /api/v1/payments/charge/{reference}
curl https://api.trite.tech/api/v1/payments/charge/TX-8F3K2M-A1B2C3D4 \
  -H "Authorization: Bearer trite_sk_..."
HTTP 200 OK
{
  "reference": "TX-8F3K2M-A1B2C3D4",
  "transaction_id": "9a2d...",
  "session_id": "3f6b1c9e-...",
  "status": "SETTLED",
  "amount": 200,
  "currency": "GHS",
  "method": "MOBILE_MONEY",
  "failure_reason": null,
  "created_at": "2026-08-09T14:21:07.412Z",
  "updated_at": "2026-08-09T14:21:44.907Z"
}

status is INITIATED while the payer still has the prompt, then SETTLED or FAILED. failure_reason is populated only on the latter.

Prefer webhooks over polling

Mobile money settles asynchronously — a payer may approve the prompt minutes after your request returned. The payment.success webhook is the recommended completion signal and carries the same tx_id_display as your reference. If you do poll, poll every 3–5 seconds and stop after about five minutes.
Direct charge requires a verified merchant — see Merchant verification. Charges belonging to a different merchant return 404. Submitting an OTP against a charge that is no longer awaiting one returns 409.

Webhooks

Configure your endpoint URL and event subscriptions in Settings → Integrations → Webhook Configuration. Events are delivered as POST requests with a JSON envelope:

POST (To your server)
{
  "id": "evt_5c1a...",
  "type": "payment.success",
  "created_at": "2026-07-07T12:03:41.000Z",
  "data": {
    "tx_id_display": "TX-8F3K2M",
    "session_id": "3f6b1c9e-...",
    "amount": 25.5,
    "currency": "GHS",
    "method": "MOBILE_MONEY",
    "status": "SETTLED"
  }
}
Events payload
EventFires when
payment.successA payment settles (funds credited to your balance).
payment.failedA payment fails or expires. data.failure_reason explains why.
payout.successA settlement to your payout account completes.
payout.failedA settlement is declined; funds return to your balance.

Webhook Delivery Retry

Respond with any 2xx quickly (under 10 seconds) — do your processing async. Failed deliveries retry with backoff (1m, 5m, 30m, 2h, 8h, 24h) before being marked exhausted; you can redeliver manually from the dashboard.

Verifying signatures

Every delivery carries an X-Trite-Signature header: t=<unix>,v1=<hex>. Compute HMAC-SHA256 of `${t}.${rawBody}` with your signing secret (Settings → Integrations), compare timing-safely, and reject if the timestamp is more than 5 minutes old.

import crypto from "crypto";

function verifyTriteSignature(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(
    header.split(",").map((p) => p.split("="))
  );
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Rate limits

Limits are per merchant, per bucket, in a fixed one-minute window. Exceeding one returns 429 with a Retry-After header (seconds). Back off and retry after that interval.

BucketLimitEndpoints
v1/payments60/minCreate session, check session status
v1/payments/charge60/minDirect charge, submit OTP
v1/payments/charge:status300/minRead a charge by reference — a polling loop can never starve your charge bucket

Deprecations

Endpoint Deprecation

POST /api/payments/initiate is a deprecated alias of POST /api/v1/payments/initiate and now requires the same API-key authentication. Migrate to the v1 path; a removal date will be announced in advance.

SDKs

Coming Soon

SDKs & Libraries

We're working on official libraries for Node.js, Python, PHP, and more.