Overview
Welcome to the official WINAGGREGATOR MOMO Payment Service API documentation. Our RESTful API enables merchants, businesses, and applications in Liberia to seamlessly process MTN Mobile Money (MoMo) collections, manage disbursements (withdrawals), verify client credentials, and monitor real-time wallet balances across supported currencies (USD and LRD).
Start Without a Registered Business
Most payment providers require a registered company before you can accept a single payment. We don't. Sign up with your phone number and your national ID or passport number, and start collecting today. You register your business once you have earned the money to pay for it.
| Tier | What you provide | Can collect | Can withdraw |
|---|---|---|---|
| UNVERIFIED | Phone number and national ID | Up to $300.00 total | Up to $200.00, for registration |
| GRACE | Cap reached — documents now due | Paused | Registration allowance |
| VERIFIED | Business registration approved | Unlimited | Unlimited |
| BLOCKED | 14 days passed with no documents | Paused | Registration allowance only |
Build and earn
Integrate today and collect up to $300.00. Limits are counted in USD equivalent, so LRD payments count at the platform rate.
Withdraw to register
Take out up to $200.00 — enough to cover the Liberian business registration fee — and register your business with it.
Submit and grow
Send your registration documents. Once approved, every limit is lifted and your full balance unlocks.
The 14-day clock starts when you reach $300.00, not when you sign up. If the deadline passes without documents, new collections stop. Your balance is not lost — it is held and released in full as soon as your documents are approved, and the registration allowance stays available so you can still pay the registration fee and recover your account.
Check Your Standing — GET /api/v1/compliance/status
Readable at every tier, including while blocked, so you can always see your held balance and what is needed to release it.
Submit Documents — POST /api/v1/compliance/documents
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Company secret key. |
| documents * | array | Registry certificate numbers, TIN, or links to hosted copies. |
| note | string | Anything the reviewer should know. |
curl "https://winaggregator-mtn.com/api/v1/compliance/status?company_name=WinLib%20Enterprises&secret_string=sec_w1nL1b_98a7b6c5d4e3f2a1"
{
"status": 200,
"success": true,
"tier": "UNVERIFIED",
"can_collect": true,
"collection_cap_usd": "300.00",
"cumulative_gross_usd": "180.00",
"remaining_cap_usd": "120.00",
"registration_allowance_usd": "200.00",
"registration_allowance_remaining_usd": "200.00",
"account_balance": { "USD": "172.80", "LRD": "0.00" }
}
Regulatory Status & Licensing
WIN LIBERIA operates as a licensed Value-Added Services Aggregator in the Republic of Liberia, authorised by the Liberia Telecommunications Authority. Payments routed through this platform are handled under that licence and under our wholesale access arrangement with the mobile network operator.
Licence Record
| Licence holder | WIN LIBERIA |
| Licence type | Value-Added Services Aggregator License |
| Reference number | LTA-VASAL/WINLIBERIA-09-18-2025-005 |
| Issuing authority | Liberia Telecommunications Authority (LTA) |
| Date of issue | September 18, 2025 |
Granted Under
- The Telecommunications Act 2007 of the Republic of Liberia
-
The Amended Telecommunications Licensing Authorization Regulations (
LTA-REG-0001) -
The Regulations on the Wholesale Access to Telecommunications Networks for the Provision of Value-Added Services (
LTA-REG-0011)
Verify independently
Confirm this licence directly with the Liberia Telecommunications Authority, quoting
reference LTA-VASAL/WINLIBERIA-09-18-2025-005. The same record is
served as JSON at GET /api/v1/legal/license.
Certificate
Open full certificate
What this licence covers. It authorises WIN LIBERIA to operate as a Value-Added Services Aggregator, providing wholesale-access value-added services over Liberian telecommunications networks. Merchants building on this platform are covered by our aggregator arrangement rather than needing their own operator agreement — which is what makes starting without a registered business possible.
Why Choose WINAGGREGATOR for MTN MoMo Integration?
Integrating MTN Mobile Money (MoMo) directly into your website, app, or enterprise platform can often involve complex telco protocols, lengthy compliance cycles, and cumbersome API environments. WINAGGREGATOR eliminates these barriers by providing a modern, developer-friendly unified API built specifically for high-reliability Mobile Money operations in Liberia.
Zero-Friction Direct Integration
Get straight to live production payment collections without complex telco sandbox setups or manual partner approvals.
Dual Currency Engine (USD & LRD)
Native support for both Liberian Dollars (LRD) and US Dollars (USD) with automated real-time exchange rate calculations.
3 Integration Methods
Choose between direct REST API calls, embeddable Hosted Payment Cards, or automated recurring subscriptions.
Bank-Grade HMAC Security
Cryptographic HMAC-SHA256 signature verification guarantees parameter integrity and prevents unauthorized payment tampering.
Real-Time WebSockets Stream
Receive instant push event notifications as soon as transactions pass on the MTN network—no polling needed.
Automated Disbursements
Easily disburse payments, process customer refunds, or pay out vendors directly to any MTN Mobile Money subscriber account.
How It Works: The 1-Minute Integration & Payment Flow
From getting your initial API keys to processing your first live customer transaction and withdrawing revenue, the WINAGGREGATOR MTN MoMo workflow takes under a minute to understand and implement.
Request API Secret Key (~30 Seconds)
POST /api/v1/request-secret-string
Submit your registered company_name and phone number to receive your secure API secret key. The generated secret string acts as your primary authentication credential for all transaction requests.
Trigger Payment or Embed Widget (~10 Seconds)
POST /api/v1/collection
Initiate a collection by sending customer phone number (msisdn), amount, and currency (USD/LRD). Alternatively, direct customers to your hosted checkout card at /pay/{company_name} for instant UI checkout.
Customer Phone Authorization (USSD Push) (~15 Seconds)
MTN PROMPTThe customer immediately receives an automated pop-up prompt on their MTN Mobile Money mobile phone screen asking to authorize payment. The customer inputs their secret MTN MoMo PIN code to confirm.
Real-Time Event Notification (Instant)
WS /ws/v1/notification
Upon PIN entry, WINAGGREGATOR broadcasts a real-time PAYMENT_COLLECTED WebSocket event with transaction reference details, net merchant amounts, and timestamps directly to your backend or app.
Wallet Balances & Payout Disbursements (On Demand)
POST /api/v1/withdraw
Check multi-currency balances anytime via GET /api/v1/account-balance and disburse funds to any valid MTN Mobile Money user account instantly via the withdrawal API.
Authentication
All protected API endpoints require authenticating with your registered company_name and cryptographically generated secret_string.
secret_string in client-side code or public repositories.
Base URL & Server Configuration
/api/v1/request-secret-string
Register a new merchant company and generate a secret string key.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Merchant business name. |
| company_phone_number * | string | Company phone (MSISDN e.g., 231888123456). |
curl -X POST "https://winaggregator-mtn.com/api/v1/request-secret-string" \
-H "Content-Type: application/json" \
-d '{
"company_name": "WinLib Enterprises",
"company_phone_number": "231888123456"
}'
{
"secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1",
"message": "Your secret string has been generated successfully."
}
/api/v1/regenerate-secret-string
Rotate or regenerate a new API secret string key for a registered merchant. Supports optional verification of old_secret_string.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Merchant business name. |
| company_phone_number * | string | Company phone (MSISDN e.g., 231888123456). |
| old_secret_string | string | Optional previous secret string key for authentication. |
curl -X POST "https://winaggregator-mtn.com/api/v1/regenerate-secret-string" \
-H "Content-Type: application/json" \
-d '{
"company_name": "WinLib Enterprises",
"company_phone_number": "231888123456",
"old_secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1"
}'
{
"secret_string": "rA0edvQ6rCD2XgSJPRxACvLEf5Bn6QfF8tDZEc0l3qk",
"message": "Your secret string key has been regenerated successfully."
}
/api/v1/collection
Initiates a mobile money collection (Request-to-Pay) from a customer's phone number. Credits the net merchant amount (96% after the 4% provider fee) directly to the target currency balance (USD or LRD).
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Company secret key. |
| amount * | string | Numerical payment amount. |
| currency * | string | Currency ("USD" or "LRD"). |
| externalID * | string | Merchant reference ID. |
| msisdn * | string | Payer phone (23188, 231888, 231555). |
curl -X POST "https://winaggregator-mtn.com/api/v1/collection" \
-H "Content-Type: application/json" \
-d '{
"secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1",
"company_name": "WinLib Enterprises",
"amount": "10.00",
"currency": "USD",
"externalID": "INV-2026-001",
"msisdn": "231888123456"
}'
{
"status": 200,
"success": true,
"reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"transaction_status": "SUCCESSFUL",
"gross_amount": 10.0,
"provider_fee_deducted": 0.4,
"net_merchant_credited": 9.6,
"currency": "USD",
"msisdn": "231888123456"
}
If the payer takes their time. This call waits up to 90 seconds for the PIN prompt to be confirmed.
If it has not been confirmed by then you get 202 with
"transaction_status": "PENDING" and a status_url —
not a failure. The payment is still live: we keep tracking it, and when the payer confirms we credit your
balance and fire your webhook automatically.
Never treat PENDING as declined. Wait for the webhook, or poll
the status endpoint.
{
"status": 202,
"success": false,
"reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"externalID": "INV-2026-001",
"transaction_status": "PENDING",
"status_url": "/api/v1/collection/status/98a7b6c5-d4e3-4f2a-8b1c-90123456789a"
}
/api/v1/collection/status/{reference_id}
Returns the current outcome of a collection. If MTN has resolved the payment since your original request returned, this call settles it — crediting your balance and firing your webhook — before responding. It is safe to call as often as you like: a payment is only ever credited once, no matter how many times you poll.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Company secret key. |
Transaction States
| Status | Meaning |
|---|---|
| SUCCESSFUL | Payer confirmed. Your balance has been credited. |
| FAILED | Declined, rejected or timed out. Nothing was credited. |
| PENDING | Awaiting the payer's PIN. Keep polling or wait for the webhook. |
| EXPIRED | Never confirmed within 24 hours. Treated as failed. |
curl "https://winaggregator-mtn.com/api/v1/collection/status/98a7b6c5-d4e3-4f2a-8b1c-90123456789a?company_name=WinLib%20Enterprises&secret_string=sec_w1nL1b_98a7b6c5d4e3f2a1"
{
"status": 200,
"success": true,
"reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"externalID": "INV-2026-001",
"transaction_status": "SUCCESSFUL",
"currency": "USD",
"gross_amount": 10.0,
"provider_fee_deducted": 0.4,
"net_merchant_credited": 9.6
}
Webhooks — Payment Result Callbacks
Register one HTTPS URL and we will POST the final outcome of every collection to it — whether the payer confirms in two seconds or two minutes. This is the recommended way to learn a payment's fate: your server is told, so you never have to poll. Webhooks fire from every settlement path, including payments confirmed long after your original request returned.
| Event | Fired when |
|---|---|
| payment.successful | The payer confirmed. Your balance has already been credited when this arrives. |
| payment.failed | The payment was declined, rejected or timed out. Nothing was credited. |
| subscription.activated | A subscription's initial payment landed and the subscription is now ACTIVE. |
Register Your URL — POST /api/v1/webhook/config
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Company secret key. |
| callback_url | string | Public https:// URL. Send an empty string to disable delivery. |
Delivery Headers
| Header | Description |
|---|---|
| X-Winlib-Signature | HMAC-SHA256 hex digest of "{timestamp}.{raw body}" keyed with your secret string. |
| X-Winlib-Timestamp | ISO-8601 send time. Part of the signed message — reject anything older than ~5 minutes. |
| X-Winlib-Event | Event name, e.g. payment.successful. |
| X-Winlib-Delivery | Unique delivery id. Retries of the same event reuse it — use it to deduplicate. |
| X-Winlib-Attempt | Attempt number, 1 to 4. |
curl -X POST "https://winaggregator-mtn.com/api/v1/webhook/config" \
-H "Content-Type: application/json" \
-d '{
"company_name": "WinLib Enterprises",
"secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1",
"callback_url": "https://yourstore.com/hooks/momo"
}'
{
"event": "payment.successful",
"delivery_id": "3f2a8b1c-90de-4a5b-8c7d-1e2f3a4b5c6d",
"company_name": "WinLib Enterprises",
"timestamp": "2026-08-27T14:03:11.482913+00:00",
"reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"externalID": "INV-2026-001",
"transaction_status": "SUCCESSFUL",
"success": true,
"gross_amount": 10.0,
"provider_fee_deducted": 0.4,
"net_merchant_credited": 9.6,
"currency": "USD",
"msisdn": "231888123456",
"account_balance": { "USD": "109.60", "LRD": "0.00" }
}
Retries
Up to 4 attempts with 2s, 4s and 8s backoff. Any 2xx acknowledges; everything else retries.
Idempotency
A payment settles exactly once, so an event fires once. Still key on reference_id — a retry may arrive after you already responded.
Requirements
Public https:// only. Private, loopback and internal addresses are rejected at registration.
Always verify the signature before acting on a webhook. The payload alone is not proof it came from us. Verify against the raw request body — parsing and re-serialising the JSON changes the bytes and the signature will not match. Respond 2xx as soon as you have stored the event, and do your slow work afterwards; we time out after 10 seconds.
/api/v1/transactions
Every collection attempt made by your company, newest first — including payments still awaiting confirmation.
Useful for reconciliation and for finding the reference_id of a payment you have lost track of.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Company secret key. |
| limit | integer | 1–200. Defaults to 50. |
curl "https://winaggregator-mtn.com/api/v1/transactions?company_name=WinLib%20Enterprises&secret_string=sec_w1nL1b_98a7b6c5d4e3f2a1&limit=50"
{
"status": 200,
"success": true,
"company_name": "WinLib Enterprises",
"transactions": [
{
"reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"externalID": "INV-2026-001",
"amount": "10.00",
"currency": "USD",
"msisdn": "231888123456",
"status": "SUCCESSFUL",
"net_merchant_amount": 9.6,
"created_at": "2026-08-27T14:02:47.109882+00:00",
"settled_at": "2026-08-27T14:03:11.402551+00:00"
}
]
}
Idempotency & Replay Protection
Your externalID is the idempotency key. Each one may be charged
once per company every 24 hours. A repeat is refused with
409 Conflict before the payer is prompted, so a retried form post, a duplicated
job or a replayed checkout payload cannot charge the same customer twice.
Choose a real key
Use your own order or invoice identifier — INV-2026-001, not a timestamp.
Two customers checking out in the same second would share a timestamp and the second
would be refused.
Safe to retry on network errors
If we never reached MTN, the key is released and the same externalID works
again. Once MTN accepts the request the key stands for the full window — even if the
payment later fails.
A declined payment does not free the key
To let a customer retry after a decline, issue a new externalID
(INV-2026-001-R2). This is deliberate: it makes an accidental double charge
impossible.
# The same externalID sent twice within the window
curl -X POST "https://winaggregator-mtn.com/api/v1/collection" \
-H "Content-Type: application/json" \
-d '{
"secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1",
"company_name": "WinLib Enterprises",
"amount": "10.00",
"currency": "USD",
"externalID": "INV-2026-001",
"msisdn": "231888123456"
}'
{
"detail": {
"message": "externalID 'INV-2026-001' was already used. Each externalID may only be charged once every 24 hours.",
"externalID": "INV-2026-001",
"original_reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"original_requested_at": "2026-08-27T14:02:47.109882+00:00",
"status_url": "/api/v1/collection/status/98a7b6c5-d4e3-4f2a-8b1c-90123456789a"
}
}
Rate Limits
Every endpoint is rate limited. Limits apply per caller address and per tier, over a rolling
60-second window. The /mtn prefixed routes share a budget with their
unprefixed equivalents.
| Tier | Limit | Endpoints |
|---|---|---|
| strict | 10 / 60s | Secret issuance and regeneration, webhook configuration. |
| payment | 20 / 60s | Collection, checkout pay, withdraw, subscription create and cancel. |
| read | 120 / 60s | Payment status, transactions, balance, subscriptions, notifications, WebSocket connects. |
| payer | 180 / 60s | Hosted checkout status polling. Counted per transaction, not per address, so payers sharing a carrier NAT are not blocked. |
| public | 300 / 60s | Documentation, hosted card pages, static assets, health. |
Response Headers
| Header | Description |
|---|---|
| X-RateLimit-Limit | Requests allowed in the window for this tier. |
| X-RateLimit-Remaining | Requests left before you are throttled. |
| Retry-After | Seconds to wait. Sent on 429 responses. |
Back off, do not hammer
On 429, wait for Retry-After before retrying. Prefer
webhooks over polling — they cost you
no requests at all.
import time
import requests
def call_with_backoff(method, url, **kwargs):
for attempt in range(5):
response = requests.request(method, url, **kwargs)
if response.status_code != 429:
return response
# Honour the server's own wait time.
time.sleep(int(response.headers.get("Retry-After", 5)))
raise RuntimeError("Still rate limited after 5 attempts")
{
"status": 429,
"success": false,
"error": "Too Many Requests",
"detail": "Rate limit of 20 requests per 60s exceeded for this endpoint. Retry in 42s."
}
Embeddable Payment Card Component
Copy and paste our pre-built, ready-to-use MTN Mobile Money Payment Card directly onto your website, store, or web application. You can set the exchange rate directly in your integration code using the rate parameter (e.g., rate=200 for 1 USD = 200 LRD). Payments made through this card automatically deduct the 4% fee and credit the 96% net amount to your company account balance in real-time.
Integration Options
<iframe src="https://winaggregator-mtn.com/pay/DEVOS?amount=10.00¤cy=USD&rate=200" width="100%" height="590px" style="border:none; border-radius:24px;" allow="payment"></iframe>
<div id="winagg-momo-card" data-company="DEVOS" data-amount="10.00" data-currency="USD" data-rate="200"></div> <script src="https://winaggregator-mtn.com/static/js/checkout-widget.js"></script>
To prevent customer tampering (e.g. changing rate=200 to rate=50 in URL), sign params on your backend with your secret_string:
# Python HMAC-SHA256 Signature
msg = "DEVOS:10.00:USD:200:INV-100" # {company}:{amount}:{currency}:{rate}:{ref}
signature = hmac.new(secret.encode(), msg.encode(), hashlib.sha256).hexdigest()
# Add &signature={signature} to URL or data-signature="{signature}" to JS widget
Live Card Preview Open Full Page
/api/v1/subscription/create
Set up automated recurring subscription payments from customer MTN Mobile Money wallets. Flexible schedules supported: weekly, monthly, quarterly, yearly. Automatically executes the initial charge upon customer PIN authorization and schedules recurring charges on the next_billing_date.
When the initial payment is not confirmed in time. You get 202 and the
subscription is created with status PENDING_INITIAL_PAYMENT. It does not bill in this state.
When the payer confirms, it becomes ACTIVE, its billing schedule starts from that moment,
and a subscription.activated webhook fires.
If the payment is declined, the subscription is closed as PAYMENT_FAILED and never bills.
Poll the returned status_url or wait for the webhook. Do not retry the subscription —
that would charge the customer twice.
curl -X POST "https://winaggregator-mtn.com/api/v1/subscription/create" \
-H "Content-Type: application/json" \
-d '{
"company_name": "WinLib Enterprises",
"amount": "15.00",
"currency": "USD",
"interval": "monthly",
"msisdn": "231888123456",
"externalID": "VIP-PLAN-101",
"rate": 195.0
}'
{
"status": 200,
"success": true,
"message": "Subscription successfully created and billed for interval 'monthly'.",
"subscription": {
"subscription_id": "SUB-8A7B6C5D4E3F",
"company_name": "WinLib Enterprises",
"customer_msisdn": "231888123456",
"amount": "15.00",
"currency": "USD",
"interval": "monthly",
"status": "ACTIVE",
"next_billing_date": "2026-09-14T20:00:00.000000+00:00"
}
}
Embeddable Subscription Card Component
Embed the Subscription Card widget on your platform using iFrame or 1-line JS script:
<iframe src="https://winaggregator-mtn.com/pay/subscription/DEVOS?amount=15.00¤cy=USD&interval=monthly&rate=200" width="100%" height="640px" style="border:none; border-radius:24px;" allow="payment"></iframe>
<div id="winagg-subscription-card" data-company="DEVOS" data-amount="15.00" data-currency="USD" data-interval="monthly" data-rate="200"></div> <script src="https://winaggregator-mtn.com/static/js/subscription-widget.js"></script>
Live Subscription Card Preview Open Full Page
/api/v1/subscriptions
Retrieve all registered subscriptions for a merchant company. Supports optional filtering by subscription status (ACTIVE, CANCELLED).
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Merchant business name. |
| secret_string * | string | Company secret key for authentication. |
| status | string | Optional status filter (ACTIVE or CANCELLED). |
curl -X GET "https://winaggregator-mtn.com/api/v1/subscriptions?company_name=WinLib%20Enterprises&secret_string=sec_w1nL1b_98a7b6c5d4e3f2a1&status=ACTIVE"
{
"status": 200,
"success": true,
"company_name": "WinLib Enterprises",
"total_subscriptions": 1,
"subscriptions": [
{
"subscription_id": "SUB-8A7B6C5D4E3F",
"company_name": "WinLib Enterprises",
"customer_msisdn": "231888123456",
"amount": "15.00",
"currency": "USD",
"interval": "monthly",
"status": "ACTIVE",
"next_billing_date": "2026-09-14T20:00:00.000000+00:00"
}
]
}
/api/v1/subscription/cancel
Cancel or pause an active customer recurring subscription. Prevents future automatic recurring charges on the next billing date.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Merchant business name. |
| secret_string * | string | Merchant authentication secret key. |
| subscription_id * | string | Target subscription ID (e.g. SUB-8A7B6C5D4E3F). |
curl -X POST "https://winaggregator-mtn.com/api/v1/subscription/cancel" \
-H "Content-Type: application/json" \
-d '{
"company_name": "WinLib Enterprises",
"secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1",
"subscription_id": "SUB-8A7B6C5D4E3F"
}'
{
"status": 200,
"success": true,
"subscription_id": "SUB-8A7B6C5D4E3F",
"message": "Subscription 'SUB-8A7B6C5D4E3F' has been cancelled successfully."
}
/api/v1/withdraw
Disburse funds directly to a mobile money wallet. Verifies and deducts strictly against the requested currency balance (USD or LRD).
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Secret string key. |
| amount * | string | Withdrawal amount. |
| currency * | string | Currency ("USD" or "LRD"). |
curl -X POST "https://winaggregator-mtn.com/api/v1/withdraw" \
-H "Content-Type: application/json" \
-d '{
"company_name": "WinLib Enterprises",
"secret_string": "sec_w1nL1b_98a7b6c5d4e3f2a1",
"amount": "50.00",
"currency": "USD",
"externalID": "WD-2026-009",
"msisdn": "231888123456"
}'
{
"status": 200,
"success": true,
"reference_id": "WD-98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"response": {
"status": "SUCCESSFUL",
"financialTransactionId": "654321098",
"externalId": "WD-2026-009",
"amount": "50.00",
"currency": "USD"
}
}
/api/v1/account-balance
Query company wallet balances across supported currencies (USD and LRD).
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| company_name * | string | Company name. |
| secret_string * | string | Secret key. |
| currency | string | Optional currency filter ("USD" or "LRD"). Omit to retrieve full breakdown. |
curl -X GET "https://winaggregator-mtn.com/api/v1/account-balance?company_name=WinLib%20Enterprises&secret_string=sec_w1nL1b_98a7b6c5d4e3f2a1¤cy=USD"
{
"account_balance": {
"USD": "1450.75",
"LRD": "5000.00"
}
}
/ws/v1/notification/{user_secret_string}
Open a persistent, bi-directional WebSocket connection to receive instant payment completion events (PAYMENT_COLLECTED, WITHDRAWAL_DISBURSED) in real-time with zero polling overhead. REST polling fallback is also available at GET /api/v1/notification/{user_secret_string}.
WebSocket Protocol Details
| Parameter / Message | Type | Description |
|---|---|---|
| user_secret_string * | string (URL Path) | Company authentication secret key embedded in WebSocket connection URL. |
| ping | Client Frame | Send "ping" text frame for server heartbeat verification. Server responds with {"event": "pong"}. |
const secretKey = 'sec_w1nL1b_98a7b6c5d4e3f2a1';
const ws = new WebSocket(`wss://winaggregator-mtn.com/ws/v1/notification/${secretKey}`);
ws.onopen = () => console.log('Connected to WINAGGREGATOR WebSocket Stream');
ws.onmessage = (event) => {
const payload = JSON.parse(event.data);
console.log('Real-Time Payment Event:', payload);
};
{
"event": "PAYMENT_COLLECTED",
"externalID": "INV-2026-001",
"reference_id": "98a7b6c5-d4e3-4f2a-8b1c-90123456789a",
"gross_amount": 10.0,
"net_merchant_amount": 9.8,
"currency": "USD",
"msisdn": "231888123456",
"status": "SUCCESSFUL",
"timestamp": "2026-08-14T19:45:00.000Z"
}
HTTP Error & Status Codes
| Status | Type | Description |
|---|---|---|
| 200 OK | Success | Request processed successfully. |
| 202 Accepted | Pending | Collection accepted asynchronously; transaction polling in progress. |
| 400 Bad Request | Error | Missing required parameter, invalid MSISDN format, invalid currency, or insufficient account balance. |
| 401 Unauthorized | Error | API user unapproved or secret string key credentials invalid. |
| 403 Forbidden | Error | Request amount invalid or less than $0.00. |
| 404 Not Found | Error | Client registration credentials not found in system. |