Your first payment

Do this once by hand with cURL before writing any code. You’ll charge a test number, approve it on the phone, check the result and refund it.

Set these first. Use a verified test number from step 2.5:

export EIP=https://developers.ecocash.co.zw/sandbox/payment/v1
export EIP_AUTH="sbx_yourusername:yourpassword"
export MSISDN=263771234567        # your verified test number
export CORR=$(date +%s)            # a unique clientCorrelator

4.1 Step 1: Charge the customer

curl -sS -X POST "$EIP/transactions/amount/" \
  -u "$EIP_AUTH" \
  -H 'Content-Type: application/json' \
  -d '{
    "clientCorrelator": "'"$CORR"'",
    "notifyUrl": "",
    "referenceCode": "ORDER-'"$CORR"'",
    "tranType": "MER",
    "endUserId": "'"$MSISDN"'",
    "remarks": "Test payment",
    "transactionOperationStatus": "Charged",
    "paymentAmount": {
      "charginginformation": { "amount": "2.00", "currency": "USD", "description": "Test payment" },
      "chargeMetaData": { "channel": "WEB" }
    },
    "merchantCode": "287164",
    "merchantPin": "1234",
    "merchantNumber": "778503033",
    "countryCode": "ZW",
    "terminalID": "TERM001",
    "location": "Harare",
    "superMerchantName": "EcoCash Sandbox",
    "merchantName": "Test Merchant"
  }'

You get 200 OK with "status": "PENDING", which means the charge was accepted, not yet paid. (The responses in this section are the portal’s documented examples, so their values won’t match your request.)

{
  "transactionId": "MP230422.1145.T0123456",
  "clientCorrelator": "1774252612",
  "status": "PENDING",
  "statusCode": "200",
  "amount": 2,
  "currency": "USD",
  "endUserId": "773047653",
  "merchantCode": "001535",
  "timestamp": "2024-04-22T11:45:30Z"
}

Save the transactionId. You need it to refund this payment.

4.2 Step 2: Approve on the phone

The test phone gets a USSD prompt. Enter a sandbox test PIN to choose the outcome:

PIN Outcome
0000 ✅ Successful payment
1111 ⚠️ Insufficient balance
2222 ❌ Invalid PIN
9999 🚫 Transaction limit exceeded

Use 0000 now. The merchant PIN in the request body (1234) never changes.

4.3 Step 3: Check the status

curl -sS "$EIP/$MSISDN/transactions/amount/$CORR" -u "$EIP_AUTH"
{
  "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"
}

Repeat every few seconds until status is no longer PENDING. Sandbox transactions usually resolve within 12–30 seconds. The phone also gets an SMS starting SANDBOX TEST:.

4.4 Step 4: Refund it

Refunds need a new clientCorrelator and the original EcoCash reference (the transactionId from step 1). Only a SUCCESS payment can be refunded.

export REFUND_CORR=$(date +%s)
export ORIGINAL_REF=MP230422.1145.T0123456   # transactionId from step 1

curl -sS -X POST "$EIP/transactions/refund/" \
  -u "$EIP_AUTH" \
  -H 'Content-Type: application/json' \
  -d '{
    "clientCorrelator": "'"$REFUND_CORR"'",
    "referenceCode": "REFUND-'"$REFUND_CORR"'",
    "tranType": "REF",
    "endUserId": "'"$MSISDN"'",
    "originalEcocashReference": "'"$ORIGINAL_REF"'",
    "remarks": "Customer refund",
    "paymentAmount": {
      "charginginformation": { "amount": "2.00", "currency": "USD", "description": "Refund" },
      "chargeMetaData": { "channel": "WEB" }
    },
    "merchantCode": "287164",
    "merchantPin": "1234",
    "merchantNumber": "778503033",
    "countryCode": "ZW",
    "terminalID": "TERM001",
    "location": "Harare",
    "superMerchantName": "EcoCash Sandbox",
    "merchantName": "Test Merchant"
  }'
{
  "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"
}

Done. You’ve run the full payment lifecycle. Now confirm three details, then build it into your app with the code examples.

4.5 Confirm three details in your first run

The portal’s pages disagree on three details. Your first sandbox run settles them. Keep each one as a single config value in your code (the examples in section 8 do) so you can switch it without a rewrite.

Detail Try first If the sandbox rejects it
amount format String with two decimals, "2.00" (what the Playground and SDK samples send) A JSON number, 2 (what the Documentation examples show)
Refund tranType "REF" for a refund, "REV" for a reversal (the Documentation) "MER" plus a top-level "currencyCode" (what the Playground and SDK samples send)
Merchant values Your Authentication tab’s Credential Reference set The Documentation’s Test Data set (7.3)

Background on each is in Known portal inconsistencies.


This page is generated from section 4 of the README in README.md. Spotted something wrong? Open an issue.


Back to top

MIT licensed. Written and maintained by John Mugabe under 67even. Independent and community-maintained - not affiliated with or endorsed by EcoCash Holdings Zimbabwe. "EcoCash" and the EcoCash logo belong to their owner.