API V2 (recommended)
Collect from a customer
POST /V2/deposits: the customer pays from their Mobile Money wallet after confirming with a PIN; your balance is credited on confirmation.
POST /V2/deposits#
Requests a payment from the customer. They get a PIN prompt on their phone; the payment stays pending until they confirm (or refuse), then moves to completed or failed.
Parameters#
| Field | Type | Required | Description |
|---|---|---|---|
amount | string | number | Yes | Net amount, > 0, at most 2 decimals (e.g. "1500", "12.50"). |
currency | string | Yes | Currency of an open country (e.g. CDF, USD), then checked against the phone number's country. Each country's currencies: Countries and providers. |
phone | string | Yes | Local number of the default country (0812345678) or international, with the country's dial code (+243812345678). At most 20 characters. See Countries and numbers. |
country | string | No | Phone number's country, 3-letter code (e.g. COD). Without it: local number = the platform's default country (currently DR Congo, COD), international number = country of the dial code. |
provider | string | No | Provider code (e.g. VODACOM_MPESA_COD, see Countries and providers). Inferred from the number when absent. |
reference | string | No | Your reference, unique per token, at most 100 characters (letters, digits, . _ : -). See idempotency. |
callback_url | string | No | Public HTTPS address that will receive the final status notification. |
customer_message | string | No | Text shown to the customer (SMS, history), depending on the provider: 4 to 22 characters, letters, digits and spaces. |
metadata | object | No | Up to 20 key / value pairs (strings of at most 255 characters), returned as is. |
Example#
Collect 1,000 CDF
curl -X POST "https://api.labyrinthe-rdc.com/api/V2/deposits" \
-H "Authorization: Bearer test_xxxxxxxxxxxxxxxx" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"amount":"1000","currency":"CDF","phone":"0813456789","reference":"ORDER-42","callback_url":"https://boutique.example/webhooks/labpay","customer_message":"Commande 42","metadata":{"orderId":"42"}}'With an SDK, fields follow the language conventions (callbackUrl, callback_url, CallbackUrl…) and an sdk_<uuid> reference is generated when you give none. A refusal at initiation (422 with the payment) is returned as a failed payment, not thrown.
{
"data": {
"id": "DEP-01JCX8Q3T6Y0V5W1Z2A3B4C5D6",
"reference": "ORDER-42",
"operation": "deposit",
"livemode": false,
"status": "pending",
"gateway_status": "ACCEPTED",
"amount": "1000.00",
"fee": "35.00",
"total_amount": "1035.00",
"currency": "CDF",
"country": "COD",
"phone": "0813456789",
"provider": "VODACOM_MPESA_COD",
"provider_transaction_id": null,
"failure": null,
"metadata": {
"orderId": "42"
},
"created_at": "2026-11-11T10:00:00+00:00",
"completed_at": null,
"refunded_amount": "0.00"
}
}Countries and numbers#
A single integration collects in every country open on the platform, each in its own currency. The payment's country is determined as follows:
countrygiven: the number must be valid in that country, otherwiseINVALID_PHONE_NUMBER; a country that is not open givesUNSUPPORTED_COUNTRY.- Local number without
country(e.g.0812345678): the platform's default country (default: trueinGET /V2/countries). - International number (
+…or00…) withoutcountry: country inferred from the dial code. If the dial code belongs to a country not open yet:UNSUPPORTED_COUNTRY(the message lists the available countries). - The
currencymust be one of that country's currencies, otherwiseINVALID_CURRENCY. The returned payment states itscountry.
International number and explicit country
curl -X POST "https://api.labyrinthe-rdc.com/api/V2/deposits" \
-H "Authorization: Bearer test_xxxxxxxxxxxxxxxx" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"amount":"1000","currency":"CDF","phone":"+243813456789","country":"COD","reference":"ORDER-43","callback_url":"https://boutique.example/webhooks/labpay"}'Countries open today, with their currencies and providers (read live from the platform; caps and dial codes on Countries and providers):
The list of countries and providers is not available at the moment. Try again in a few moments, or query GET /V2/countries and GET /V2/providers with your token.
Amounts and fees#
- The customer pays
amount+ deposit fees (total_amount); your balance is credited withamountonce the payment is confirmed. - If the provider does not accept decimals in the currency (e.g. Vodacom in CDF), the total paid by the customer is rounded up to the unit.
- Rates and caps: see Limits and fees.
Responses#
| Code | Meaning |
|---|---|
201 | Accepted: awaiting the customer's confirmation. |
202 | Unknown LabPay network response: the payment stays pending and its status is re-read automatically. This is not a failure. |
200 | reference already used for a completed payment: the existing payment is returned. |
422 | Invalid data (VALIDATION_ERROR, INVALID_PHONE_NUMBER…), or payment refused with data.status = failed. |
Only deliver an order on completed status, received through a signed notification or read with GET /V2/payments/{id} — never on the 201 response alone.
Possible errors: KYC_REQUIRED, TOKEN_BLOCKED, INVALID_CURRENCY, UNSUPPORTED_COUNTRY, UNSUPPORTED_PROVIDER, AMOUNT_TOO_SMALL, AMOUNT_TOO_LARGE, AMOUNT_OUT_OF_BOUNDS, DAILY_LIMIT_REACHED, MAINTENANCE, DEPOSITS_DISABLED, TEST_MODE_DISABLED, PROVIDER_TEMPORARILY_UNAVAILABLE… (see Errors).