Your First Payout

Run one complete payout in the sandbox, end to end

This is the one payout test to run before any other. It sends a single mobile money payout all the way to COMPLETED and proves four things at once: your credentials work, you can reach the API, your request shape is accepted, and you can read a final status back.

The example uses Kenya as the country and M-Pesa as the mobile network operator, which appear in the request as currency KES and operator mpesa. Substitute your own market from Supported Destinations if you prefer; the steps do not change.

This page is a test procedure. For field-by-field reference, see Single Payouts and Mobile Wallet.

Before you start

Your sandbox payout balance starts at zero, and a payout fails with insufficient funds if the balance can’t cover it. Ask your solutions engineer to fund it in each currency you want to test. Every successful payout draws the balance down, as it would in production.

Step 1 — Get an access token

POST /v1/auth/oauth2/token — API reference

curl -X POST 'https://api.crisscross.money/v1/auth/oauth2/token' \
-H 'Content-Type: application/json' \
--data-raw '{
"client_id": "YOUR_SANDBOX_CLIENT_ID",
"client_secret": "YOUR_SANDBOX_CLIENT_SECRET"
}'
{
"access_token": "eyJhbGci...",
"token_type": "Bearer",
"expires_in": 86400
}

Pass: a 200 with an access_token. Tokens last 24 hours and there is no refresh token — request a new one when it expires.

If this fails: a 401 means the client_id or client_secret is wrong. A 400 usually means the body was form-encoded; it must be JSON. See Authentication.

Step 2 — Initiate the payout

POST /v1/payout/initiate — API reference

curl -X POST 'https://api.crisscross.money/v1/payout/initiate' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
--data-raw '{
"merchantId": "YOUR_SANDBOX_MERCHANT_ID",
"merchantReference": "SANDBOX-FIRST-PAYOUT-001",
"destinationValue": {
"minorAmount": 500000,
"currency": "KES"
},
"paymentMethodId": "mobilemoney",
"paymentLocation": "KEN",
"recipient": {
"type": "mobile_money",
"phoneNumber": "254712345678",
"country": "KEN",
"operator": "mpesa",
"name": "Test Recipient"
},
"sender": {
"fullName": "Jane Smith",
"phoneNumber": "27821234567",
"nationality": "ZAF",
"identity": "passport",
"identityNumber": "A12345678",
"dateOfBirth": "1990-01-15",
"purposeOfFunds": "salary",
"sourceOfFunds": "business income",
"relationship": "employer"
},
"attributes": {}
}'
{
"transactionId": "4b8e2f1a-6c3d-4e9a-b7f2-1d5c8a9e0f34",
"status": "PENDING",
"message": "Payout transaction initiated successfully",
"merchantReference": "SANDBOX-FIRST-PAYOUT-001",
"paymentMethodId": "mobilemoney"
}

Pass: a 201 with a transactionId and a status of PENDING. Keep the transactionId — the next call needs it.

A few things worth getting right the first time:

  • minorAmount is in minor units. 500000 KES is KSh 5,000.00, but UGX, XAF and XOF have no minor unit, so the same 500000 is 500,000 whole units.
  • The phone number isn’t a trigger. 254712345678 ends in 78, so this payout will succeed. Payout outcomes are picked by the last two digits of the destination — see Payout Trigger Endings.
  • Kenya needs the full sender object. Other markets need less. See Kenya.

If this fails: a 422 means a field is missing or invalid, most often on sender. Check the error message for the field. A 409 Conflict means you’ve used that merchantReference before. References can never be reused, so change it on every run.

Step 3 — Poll to a final status

GET /v1/payout/{transactionId} — API reference

curl -G 'https://api.crisscross.money/v1/payout/4b8e2f1a-6c3d-4e9a-b7f2-1d5c8a9e0f34' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'

You may see PENDING or PROCESSING first while CrissCross screens the payout and sends it. Poll every few seconds until it completes:

{
"transactionId": "4b8e2f1a-6c3d-4e9a-b7f2-1d5c8a9e0f34",
"status": "COMPLETED",
"merchantReference": "SANDBOX-FIRST-PAYOUT-001",
"paymentMethodId": "mobilemoney",
"processorReference": "sandbox-4b8e2f1a-6c3d-4e9a-b7f2-1d5c8a9e0f34"
}

Pass: status reaches COMPLETED and a processorReference is present.

Stop polling at COMPLETED, FAILED or CANCELLED. If it’s FAILED with an insufficient funds message, your sandbox balance is too low — see Before you start.

What you have just proved

CredentialsYour sandbox client_id and client_secret issue a working token
ConnectivityNothing between you and api.crisscross.money is blocking the calls
Request shapeThe payout body, including sender, is accepted as written
State handlingYou can read a payout through to COMPLETED

You’ve now proved the happy path. The rest of this section covers failures and account validation.

Next