API reference
Base URL: https://developers.ecocash.co.zw/sandbox/payment/v1
Headers on every request: Authorization: Basic <encoded> and
Content-Type: application/json
Keep the trailing slashes exactly as shown.
/transactions/amount/and/transactions/refund/end with/; the lookup path does not. Some gateways treat/xand/x/as different routes.
5.1 Charge request
POST /transactions/amount/
Asks EcoCash to charge a customer’s wallet. The customer gets a USSD PIN prompt to approve.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
clientCorrelator |
string | ✅ | Your unique ID for this transaction. Never reuse it. You need it for lookups. |
referenceCode |
string | ✅ | Your own reference, e.g. an order or invoice number. It appears in the customer’s SMS. |
tranType |
string | ✅ | MER for a merchant charge |
endUserId |
string | ✅ | Customer’s EcoCash number (MSISDN), e.g. 263771234567 |
paymentAmount.charginginformation.amount |
decimal | ✅ | Amount to charge, positive, at most 2 decimal places |
paymentAmount.charginginformation.currency |
string | ✅ | USD or ZWG |
paymentAmount.charginginformation.description |
string | ✅ | What the payment is for |
paymentAmount.chargeMetaData.channel |
string | ✅ | Sales channel, e.g. WEB or POS |
merchantCode |
string | ✅ | Your EcoCash merchant code |
merchantPin |
string | ✅ | Your merchant PIN (a secret: redact it in logs) |
merchantNumber |
string | ✅ | Your merchant’s registered MSISDN |
terminalID |
string | ✅ | Terminal identifier, e.g. TERM001 |
countryCode |
string | ✅ | ZW |
location |
string | ✅ | Merchant location, e.g. Harare |
superMerchantName |
string | ✅ | Parent merchant name |
merchantName |
string | ✅ | Merchant name shown to the customer in the SMS |
remarks |
string | ✅ | Free-text remarks |
transactionOperationStatus |
string | ✅ | Always "Charged" |
notifyUrl |
string | optional | HTTPS URL for status callbacks ("" if none) |
The “Required” column reflects the documented request body, where every field is present. The portal only marks a subset as “key” fields.
⚠️ Watch the unusual spelling. Copy these exactly:
charginginformation(all lowercase),chargeMetaData(capital M and D),terminalID(capital ID). Serialisers that “fix” casing break the request.
Request body
{
"clientCorrelator": "1774252612",
"notifyUrl": "",
"referenceCode": "TEST_1774252612",
"tranType": "MER",
"endUserId": "773047653",
"remarks": "EcoCash Sandbox",
"transactionOperationStatus": "Charged",
"paymentAmount": {
"charginginformation": {
"amount": 2,
"currency": "USD",
"description": "UAT STORE 3"
},
"chargeMetaData": {
"channel": "POS"
}
},
"merchantCode": "001535",
"merchantPin": "1234",
"merchantNumber": "788732685",
"countryCode": "ZW",
"terminalID": "UAT00003",
"location": "Harare",
"superMerchantName": "ECOCASH",
"merchantName": "UAT STORE 3"
}
Response
{
"transactionId": "MP230422.1145.T0123456",
"clientCorrelator": "1774252612",
"status": "PENDING",
"statusCode": "200",
"statusMessage": "Transaction Successful",
"amount": 2,
"currency": "USD",
"endUserId": "773047653",
"merchantCode": "001535",
"timestamp": "2024-04-22T11:45:30Z"
}
| Field | Meaning |
|---|---|
transactionId |
EcoCash’s reference for this transaction. Store it: refunds need it as originalEcocashReference. |
status |
PENDING right after a charge. Branch on this, not on statusMessage. |
statusCode |
A string, e.g. "200" |
statusMessage |
Human-readable text. In the documented example it says “Transaction Successful” even while status is PENDING, so don’t trust it on its own. |
HTTP status codes
| Code | Meaning |
|---|---|
200 |
Accepted. Check status for the outcome. |
400 |
Invalid request parameters |
401 |
Unauthorized. Check your Basic Auth credentials. |
422 |
Business rule violation (e.g. barred number) |
500 |
Internal server error |
Also handle 403, 404, 409 and 503. See Error codes.
5.2 Transaction lookup
GET /{endUserId}/transactions/amount/{clientCorrelator}
Returns the current state of a charge. Use it to poll for the outcome, or to confirm a callback before acting on it.
Path parameters
| Parameter | Description |
|---|---|
endUserId |
The customer MSISDN you sent in the charge |
clientCorrelator |
The clientCorrelator you sent in the charge (the portal’s Overview calls it {correlator}; it is the same value) |
Response
{
"transactionId": "MP230422.1145.T0123456",
"clientCorrelator": "1774252612",
"status": "SUCCESS",
"statusCode": "200",
"endUserId": "773047653",
"amount": 2,
"currency": "USD",
"merchantCode": "001535",
"merchantName": "UAT STORE 3",
"referenceCode": "TEST_1774252612",
"timestamp": "2024-04-22T11:45:30Z",
"description": "UAT STORE 3"
}
HTTP status codes
| Code | Meaning |
|---|---|
200 |
Transaction details returned |
401 |
Unauthorized |
404 |
No transaction for this endUserId + clientCorrelator |
5.3 Refund or reversal
POST /transactions/refund/
Returns money for a completed (SUCCESS) payment. Use tranType REF for a customer
refund or REV for a merchant reversal.
Request fields
The body has the same shape as a charge, plus originalEcocashReference:
| Field | Type | Required | Description |
|---|---|---|---|
clientCorrelator |
string | ✅ | A new unique ID for the refund, never the original charge’s |
originalEcocashReference |
string | ✅ | The original charge’s EcoCash reference (its transactionId) |
tranType |
string | ✅ | REF (refund) or REV (reversal). See 4.5. |
paymentAmount.charginginformation.amount |
decimal | ✅ | Must not exceed the original amount |
| other fields | ✅ | referenceCode, endUserId, paymentAmount…, merchant fields, as in 5.1 |
The Documentation tab’s example refund body leaves out
originalEcocashReference, but the field table and the Playground both make it required. Always send it.
Response
{
"transactionId": "RF230422.1200.R0123456",
"clientCorrelator": "1774252613",
"status": "SUCCESS",
"statusCode": "200",
"statusMessage": "Refund processed successfully",
"originalReference": "MP230422.1145.T0123456",
"amount": 2,
"currency": "USD",
"timestamp": "2024-04-22T12:00:15Z"
}
In the response the original reference comes back as originalReference, not
originalEcocashReference.
HTTP status codes
| Code | Meaning |
|---|---|
200 |
Refund/reversal accepted |
400 |
Invalid request |
404 |
Original transaction not found |
409 |
Transaction not eligible (e.g. already refunded, or not SUCCESS) |
422 |
Refund amount exceeds the original payment |
5.4 Callbacks (notifyUrl)
Put an HTTPS URL in notifyUrl on a charge or refund to receive callbacks when the
transaction changes state. The portal doesn’t publish the callback payload or its retry
policy, so handle callbacks defensively:
- Verify before acting. Treat a callback as a hint. Confirm the status with a lookup before you fulfil an order.
- Validate the signature. The portal’s Terms of Use require you to validate the HMAC signature included with each webhook. Ask EcoCash for the header name and secret.
- Be idempotent. Delivery order and timing aren’t guaranteed, and duplicates can arrive.
Process each
clientCorrelatoronce. - Respond fast with
200, then do the work in a background job.
This page is generated from section 5 of the README in README.md. Spotted something wrong? Open an issue.