All phone numbers must be in E.164 format without the leading + sign:
{country_code}{subscriber_number}
The country code is required. Leading zeros from local format must be removed.
Country Reference
Uganda (256)
Kenya (254)
Tanzania (255)
Rwanda (250)
| Operator | Prefix | Example |
|---|
| MTN MoMo | 2567XX, 2568XX | 256700123456 |
| Airtel Money | 2567XX, 2575X | 256752123456 |
Local → International:0700 123 456 → 256700123456 (remove 0, add 256)
+256 700 123 456 → 256700123456 (remove +)
| Operator | Prefix | Example |
|---|
| Safaricom M-Pesa | 2547XX | 254712345678 |
| Airtel Money | 2547XX | 254733123456 |
Local → International:0712 345 678 → 254712345678 (remove 0, add 254)
+254 712 345 678 → 254712345678 (remove +)
| Operator | Prefix | Example |
|---|
| Vodacom M-Pesa | 2557XX | 255712345678 |
| Tigo | 2556XX, 2567XX | 255651234567 |
| Airtel | 2556XX, 2557XX | 255685123456 |
Local → International:0712 345 678 → 255712345678 (remove 0, add 255)
| Operator | Prefix | Example |
|---|
| MTN MoMo | 2507XX | 250780123456 |
| Airtel Money | 2507XX | 250720123456 |
Local → International:0780 123 456 → 250780123456 (remove 0, add 250)
Validation Pattern
RohoPay validates phone numbers server-side. The accepted pattern is:
^(256|254|255|250)[0-9]{7,12}$
- Must start with a supported country code:
256, 254, 255, or 250
- Followed by 7–12 digits
Normalizing Numbers in Code
function normalizePhone(raw: string, defaultCountryCode = "256"): string {
// Strip all non-digit characters
let digits = raw.replace(/\D/g, "");
// Handle +XXX format
if (raw.startsWith("+")) {
return digits; // already has country code
}
// Handle local format starting with 0
if (digits.startsWith("0")) {
digits = digits.slice(1);
}
// Prepend country code if not already present
const supported = ["256", "254", "255", "250"];
for (const code of supported) {
if (digits.startsWith(code)) return digits;
}
return defaultCountryCode + digits;
}
// Examples:
normalizePhone("0700 123 456", "256"); // → "256700123456"
normalizePhone("+254712345678"); // → "254712345678"
normalizePhone("256700123456"); // → "256700123456"
Test Numbers
In test mode, use these phone numbers to simulate different outcomes:
| Number Pattern | Outcome |
|---|
256700000000 | Always succeeds |
011177777(0-9) | Success |
011177799(0-9) | Failed |
011177778(0-9) | Pending (stays in processing) |
011177779(0-9) | Stuck in “sent to vendor” |
You can also use the 256 prefix format: 256111777771 is equivalent to 0111777771.
Test numbers only work with test_ API keys. Using them with a live_ key will return an error: TEST_NUMBER_ON_LIVE_KEY.
Validation Errors
If you send an invalid phone number, you receive:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "phone: must be a valid international format (256XXXXXXXXX, 254XXXXXXXXX, 255XXXXXXXXX, or 250XXXXXXXXX)"
}
}