Direct Pay-In¶
Initiates a server-to-server deposit where the end user sends funds to the merchant. This flow does not require a user redirect — the payment is triggered directly (e.g., via a mobile money STK push).
Endpoint¶
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
method |
Path | string | Yes | Payment method key configured for your brand (e.g., mpesa-ke, airtel-ug). Max 100 characters. |
Request Body¶
Required Fields¶
| Field | Type | Description |
|---|---|---|
amount |
Money | Payment amount and currency |
amount.value |
decimal | Amount value. Must be greater than 0. |
amount.currency |
string | ISO 4217 currency code (e.g., "KES") |
payer |
Msisdn Party | End user initiating the payment |
payer.id |
string | Your identifier for the end user (max 255 chars) |
payer.msisdn |
string | Phone number in international format (3-20 chars) |
country |
string | ISO 3166-1 alpha-2 country code (max 10 chars) |
resultUrl |
string | HTTPS URL to receive the async result callback (max 2048 chars) |
merchantReference |
string | Unique idempotency key for this transaction (max 255 chars) |
Optional Fields¶
| Field | Type | Description |
|---|---|---|
payer.firstName |
string | End user's first name (max 255 chars) |
payer.lastName |
string | End user's last name (max 255 chars) |
payer.email |
string | End user's email address (max 320 chars) |
reconciliationReference |
string | Your reconciliation identifier (max 255 chars). Defaults to merchantReference if omitted. |
labels |
object | Key-value metadata (max 10 entries). See Labels. |
Example Request¶
POST /gateway/mmo/v2/direct/payin/mpesa-ke HTTP/1.1
Host: api.payalo.com
X-Api-Key: <your-api-key>
Content-Type: application/json
{
"amount": {
"value": 500.00,
"currency": "KES"
},
"payer": {
"id": "user-42",
"msisdn": "+254712345678",
"firstName": "Jane",
"lastName": "Doe",
"email": "[email protected]"
},
"country": "KE",
"resultUrl": "https://merchant.example.com/webhooks/payalo",
"merchantReference": "dep-20240601-001",
"reconciliationReference": "INV-2024-001",
"labels": {
"orderId": "ORD-2024-001",
"channel": "mobile-app"
}
}
Response¶
Success — 200 OK¶
Returns the Initiate Payment response.
| Field | Type | Description |
|---|---|---|
status |
string | Always "pending" |
gatewayReference |
string | Unique transaction ID (ULID format) |
merchantReference |
string | Echo of your request |
reconciliationReference |
string | Your reconciliation reference, or merchantReference if not provided |
createdAt |
string | ISO 8601 timestamp |
Example Success Response¶
{
"status": "pending",
"gatewayReference": "b2p01j3abcdef0000000000000000a1b2",
"merchantReference": "dep-20240601-001",
"reconciliationReference": "INV-2024-001",
"createdAt": "2024-06-01T12:34:56+00:00"
}
Error Responses¶
| HTTP Status | errorCode |
Specific code in type URL |
Scenario |
|---|---|---|---|
400 |
validation_failed |
validation_failed |
A required field is missing or invalid. |
400 |
validation_failed |
config_unsupported_country / config_unsupported_currency / config_unsupported_payment_method / config_method_transaction_min_limit / config_method_transaction_max_limit |
Country, currency, payment method, or amount is not allowed by your brand configuration. |
400 |
validation_failed |
merchant_disabled |
Your brand has been disabled. |
400 |
bad_request |
bad_request |
Request body is malformed or unreadable. |
401 |
unauthorized |
unauthorized |
API key is missing or invalid. |
404 |
not_found |
not_found |
Resource not found. |
422 |
merchant_transactionid_duplicate |
merchant_transactionid_duplicate |
Duplicate merchantReference. |
500 |
internal_server_error |
internal_server_error |
Unexpected server error. |
See Error Handling for the full error response structure and error code reference.
Example Error Response — 400 Bad Request¶
{
"type": "https://docs.payalo.com/errors/validation_failed",
"title": "Validation failed",
"status": 400,
"detail": "Payer Msisdn is required.",
"errorCode": "validation_failed"
}
Example Error Response — 422 Unprocessable Entity¶
{
"type": "https://docs.payalo.com/errors/merchant_transactionid_duplicate",
"title": "Business logic error",
"status": 422,
"detail": "Duplicate merchant transaction ID.",
"errorCode": "merchant_transactionid_duplicate"
}
Callback¶
When the transaction reaches a terminal state (success or failed), the gateway sends a webhook to your resultUrl. See Callback Documentation for payload format, signature verification, and retry policy.
Status Flow¶
graph LR
pending --> success
pending --> failed
The transaction enters pending on creation. After asynchronous processing it moves to either success or failed. See Transaction Lifecycle for full details.