International Money Transfer
Programmatically send money, quote fees, track transfers, and reconcile statements through the Whish Money network.
This reference describes the HTTP request and response models used to integrate with Whish Money, and the operations available to move funds across the network.
Introduction
This document illustrates the HTTP request models used to call the API and the response models returned to your account. It also describes the operations you can perform to make a transfer through Whish Money.
All requests and responses use JSON over HTTPS. Every endpoint returns HTTP 200 with a consistent response envelope; the outcome of the operation is carried by the status field inside the body rather than by the HTTP status code. See Response conventions.
Version history
| Version | Author | Date | Comment |
|---|---|---|---|
6.4.4 | TecFrac | 2026-01-28 | DeductFees was renamed to deductFees, and deductFromAmount was replaced by deductFees. |
6.4.5 | TecFrac | 2026-02-02 | Minor updates and improvements applied. |
6.4.6 | TecFrac | 2026-02-09 | Minor updates and improvements applied. |
6.4.7 | TecFrac | 2026-02-16 | Added additional error codes. |
Authentication
Every request (unless otherwise noted) is authenticated with two credentials issued by Whish Money, sent as HTTP headers:
| Header | Description |
|---|---|
username | Account username provided by Whish Money. |
key | Secret API key provided by Whish Money. |
Keep credentials secret. Your key authorizes live money movement. Send it only over HTTPS, store it in a secure secrets manager, and never expose it in client-side code, logs, or version control. Rotate it immediately if you suspect it has been leaked.
Environments
Whish Money provides two isolated environments. Validate your full integration in Sandbox before requesting Production access.
| Environment | Base URL | Purpose |
|---|---|---|
| Sandbox | https://sandbox.woocash.money/api | Testing, QA, and integration verification. |
| Production | https://api.woocash.money | Live environment for real users and transactions. |
Building a request URL
Each endpoint path in this reference begins with /api/woo/…. Append the endpoint path to the environment base URL. Note that the Sandbox base URL already ends in /api, so the full Sandbox URL contains /api/api/….
For the example endpoint POST /api/woo/send/money:
| Environment | Full URL |
|---|---|
| Sandbox | https://sandbox.woocash.money/api/api/woo/send/money |
| Production | https://api.woocash.money/api/woo/send/money |
The two environments use different base-URL conventions. Sandbox includes a trailing /api segment while Production does not. Construct URLs by concatenating the base URL and the endpoint path exactly as shown above, rather than assuming both environments share the same prefix. Endpoint sections below list the path only.
Request headers
Unless an endpoint states otherwise, all requests must include the following headers:
| Header | Value | Description |
|---|---|---|
username | - | Account username, provided by Whish Money. |
key | - | Secret API key, provided by Whish Money. |
Accept | application/json | Response media type. |
Content-Type | application/json | Required for requests that send a JSON body. |
Request-id | - | Unique request identifier generated by your account. See the note below. |
Request-id must be unique for every Send Money transfer. Reusing an id can cause the transfer to be rejected or treated as a duplicate. Use a fresh, idempotent value (for example a UUID or your own transaction reference) per send request. You may reuse the same Request-id later when querying status via Get Transfer Status (it maps to requestId).
Response conventions
All endpoints return HTTP 200 with Content-Type: application/json and a shared envelope. Always branch on the status field in the body, not on the HTTP status code.
| Field | Type | Description |
|---|---|---|
status | Boolean | true = success · false = failure. |
code | String | Error code when status = false; null on success. See Error codes. |
data | Object | Payload of the operation on success; null on failure. Shape varies per endpoint. |
dialog | Object | User-friendly message for display; null on success. |
dialog.title | String | Title of the message (e.g. "Sorry!"). |
dialog.message | String | Human-readable description of the error. |
extra | Object | Reserved for additional context; typically null. |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": { }
}{
"status": false,
"code": "api.account.invalid_request",
"dialog": {
"title": "Sorry!",
"message": "api.account.invalid_request"
},
"extra": null,
"data": null
}Recommended handling: read status first. On true, process data. On false, switch on code for programmatic logic and surface dialog.message to end users. Specialized rules apply to Get Transfer Status and the Send Money / Mobile Wallet responses.
Transaction status & handling
Interpret every Send Money outcome using the rule below. It applies to both payment modes and lets you resolve most cases automatically, without escalating to Whish Money.
Transaction status interpretation
| Outcome | Condition | How to treat it |
|---|---|---|
| Successful | status: true | Consider the transaction successful. |
| Failed | status: false and code is not 500 | Consider it failed. Handle it automatically based on the returned error code. No escalation to Whish Money is required. |
| Pending | status: false and code is 500 (Internal Server Error) | Consider it pending. Escalate and follow up with Whish Money to determine the final outcome. |
Receipt issuance
Issue a receipt to the customer only in these cases:
| Case | Issue receipt? |
|---|---|
Successful (status: true) | Yes |
Pending (status: false, code: 500) | Yes (pending investigation) |
| Failed (business-validation error) | No |
Do not issue receipts for failed transactions. Any transaction returned as failed because of one of the final-failure error codes below must not produce a customer receipt.
Handling timeouts & network issues
If you do not receive a response from POST /api/woo/send/money because of a timeout, network interruption, or any communication issue, resend the same request using the exact same Request-id. This is safe:
- If the original request never reached Whish Money, the payment is initiated.
- If the original request was already received and processed, the system returns the original response for that
Request-id, so no duplicate transaction is created.
Resend before you check status. Confirm the original POST /api/woo/send/money was received before relying on Get Transfer Status. If you query the status of a transfer that was never received, the status endpoint returns sending.transfer.invalid.info, which means the referenced transaction does not exist in Whish Money's records (most likely the original request never arrived). Resend the original request with the same Request-id first, then check status only after the transfer is registered.
Error codes to treat as final failures
Automate the following as failed transactions and resolve them on your side. None of these require contacting Whish Money.
| Error code | Description |
|---|---|
api.account.invalid_request | Invalid account request. |
receiver.empty | Receiver information is missing. |
receiver.invalid.phone_number | Receiver phone number is invalid. |
receiver.customer.invalid_name | Receiver name is invalid. |
receiver.customer.info_invalid | Receiver information is invalid. |
receiver.customer.name_enlgish | Receiver name must be in English. |
sender.invalid.phone_number | Sender phone number is invalid. |
sender.customer.invalid_name | Sender name is invalid. |
sender.customer.info_invalid | Sender information is invalid. |
sender.customer.name_enlgish | Sender name must be in English. |
transfer.already.done | Transfer already completed. |
sender.missing_info | Sender information is missing. |
currency.not_supported | Currency not supported. |
transfer.invalid_amount | Amount is negative or sending amount not found in price list. |
transfer.reason_empty | Reason not provided in the request. |
transfer.from_country_not_allowed | Transfers from this country are not allowed. |
transfer.sourceOfFunds_empty | Source of funds not provided in the request. |
transfer.not_allowed_countries | Transfer to these countries is not allowed. |
transfer.account_reach_balance_limit | Reached balance limit or insufficient funds. |
transfer.exceeds_account_transaction_limit | Sending amount exceeds the allowed transaction limit. |
service.inactive | Service is inactive. |
service.price_not_active | Service price is not active. |
transfer.miss_config | Transfer configuration is missing. |
service.transaction_status_unknown | Transaction status is unknown. |
service.transaction_failed | Transaction failed. |
sender.invalid.date.of.birth | Invalid date of birth. |
transfer.exceeds_account_daily_limit | Reached daily sending limit. |
receiver.whish.account.not.exists | Whish account does not exist (Mobile Wallet mode). |
sender.kyc.needed | Sender's KYC is required. |
receiver.kyc.needed | Receiver's KYC is required. |
sender.interview.needed | Additional information required for the sender. |
receiver.interview.needed | Additional information required for the receiver. |
Implementing this logic avoids unnecessary escalations, prevents status misinterpretation, and gives customers accurate transaction status information. The code: 500 pending case is the only outcome that warrants follow-up with Whish Money.
Request models
Request models form the JSON body of a request and carry the information the API needs to process the operation.
Sending Money Fees request
Used to quote the fees for an amount to be sent.
| Field | Type | Description | Required |
|---|---|---|---|
fromCountry | Long | Sending country (currently Lebanon only, id = 1). | Required |
toCountry | Long | Receiving country (currently Lebanon only, id = 1). | Required |
currencyId | Long | Currency id (USD = 2, LBP = 1). | Required |
paymentMode | String | Enum: CASH_COLLECTION, MOBILE_WALLET. | Required |
amount | double | Sending amount in the chosen currency. | Required |
deductFees | Boolean | If true, fees are deducted from the sending amount. | Optional |
phoneNumber | String | Recipient phone number the fees are quoted for. | Optional |
{
"fromCountry": 1,
"toCountry": 1,
"currencyId": 2,
"amount": 1,
"deductFees": false,
"paymentMode": "CASH_COLLECTION",
"phoneNumber": "9613888999"
}Customer model (sender / receiver)
Represents a party to the transfer. Carries the basic information needed to identify a sender or receiver.
| Field | Type | Description | Required |
|---|---|---|---|
firstName | String | First name. | Required |
middleName | String | Middle name. | Optional |
lastName | String | Last name. | Required |
phone | String | Phone number. | Required |
extraInformation | String | Additional information about the customer. | Optional |
identity | Identity | Identity details about the customer. | Required |
The source spec lists this field as xextraInformation in the model table but uses extraInformation in every JSON sample. Use extraInformation, as shown in the examples.
"receiver": {
"firstName": "Alex",
"middleName": "something",
"lastName": "hunter",
"phone": "96170852258",
"extraInformation": "useful info",
"identity": {
"dateBirth": "01-01-1990",
"nationality": "lebanese"
}
}Identity model
Provides additional detail about a customer's identity.
| Field | Type | Description | Required |
|---|---|---|---|
nationality | String | Nationality. | Optional |
dateBirth | String | Date of birth. Format: dd-MM-yyyy. | Required |
"identity": {
"dateBirth": "01-01-1990",
"nationality": "lebanese"
}Send Money request
Body of the Send Money endpoint.
| Field | Type | Description | Required |
|---|---|---|---|
paymentMode | String | Enum: CASH_COLLECTION, MOBILE_WALLET. | Required |
fromCountry | Long | Sending country (currently Lebanon only, id = 1). | Required |
toCountry | Long | Receiving country (currently Lebanon only, id = 1). | Required |
currencyId | Long | Currency id (USD = 2, LBP = 1). | Required |
amount | double | Sending amount in the chosen currency. | Required |
sender | Customer | Information about the sender. | Required |
receiver | Customer | Information about the receiver. | Required |
deductFees | Boolean | If true, fees are deducted from the sending amount. | Optional |
reason | String | Reason for the transfer. See Reason values. | Required |
sourceOfFunds | String | Source of funds (e.g. Salary, Sale of Property or Goods). See Source of Funds. | Required |
callbackUrl | String | Cash Collection only. URL Whish Money calls when the transaction changes from SENT to RECEIVED. Not used for Mobile Wallet. See Callbacks. | Optional |
The Customer model marks identity (and its dateBirth) as required, but the sample Send Money bodies in the source spec omit it. Include identity details where your account configuration requires them; a missing or invalid date of birth returns sender.invalid.date.of.birth.
{
"fromCountry": 1,
"toCountry": 1,
"currencyId": 1,
"amount": 1000,
"receiver": {
"firstName": "person",
"middleName": "m",
"lastName": "personLastName",
"extraInformation": "useful info"
},
"reason": "GIFT",
"sourceOfFunds": "BUSSINESS",
"deductFees": false,
"callbackUrl": "http://test.com/callback"
}Cancel Transfer request
Body of the Cancel Transfer endpoint.
| Field | Type | Description | Required |
|---|---|---|---|
transferId | String | Id of the transfer. | Required |
ltnNumber | String | LTN number of the transfer. | Required |
reason | String | Reason for cancellation. | Optional |
{
"transferId": 202000001,
"ltnNumber": "5405-6838-5079",
"reason": "test"
}Get Transfer Status request
Body of the Get Transfer Status endpoint. Provide at least one identifier.
| Field | Type | Description | Required |
|---|---|---|---|
transferId | String | Id of the transfer. | Optional |
ltnNumber | String | LTN number of the transfer. | Optional |
requestId | Long | The Request-id header value you sent with the original Send Money request. You can pass it here to look up any transaction by your own reference, for either payment mode. For Cash Collection, sending it also re-triggers the callback if the status has changed. | Optional |
All three fields are individually optional, but you must supply at least one identifier so the transfer can be located.
{
"transferId": 202000001,
"ltnNumber": "5405-6838-5079"
}Statement / Activity request
Used for the Get Activity and Get Statement endpoints.
| Field | Type | Description | Required |
|---|---|---|---|
fromDate | String | Start date. Format: yyyy-MM-dd HH:mm:ss. | Required |
toDate | String | End date. Format: yyyy-MM-dd HH:mm:ss. | Required |
currencyId | Long | Currency id (USD = 2, LBP = 1). Send null to include both. | Optional |
{
"fromDate": "2020-01-01 00:00:00",
"toDate": "2022-01-01 00:00:00",
"currencyId": 1
}Response models
Response models are returned in the data object of the envelope. Fields listed below are nested inside data unless stated otherwise.
Send Money Fees response
The cost the user will pay to send the amount.
Field (in data) | Type | Description |
|---|---|---|
fees | Double | Fees in the sending currency. |
amount | Double | Amount to be sent. |
totalAmount | Double | Sum of amount and fees. |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"fees": 5,
"amount": 400,
"totalAmount": 405
}
}{
"status": false,
"code": "transfer.invalid_amount",
"dialog": {
"title": "Sorry!",
"message": "Transfer Amount Outside Range"
},
"extra": null,
"data": null
}Send Money response
Returned when the transfer was successfully created.
Field (in data) | Type | Description |
|---|---|---|
ltnNumber | String | LTN number the receiver uses to collect the transfer from Whish Money cash agents. |
transferId | String | Reference of the transfer. |
charges | Double | Fees applied to the transfer. |
Mobile Wallet responses may additionally include collectionAmount, balance, transactionId, and currency. See below.
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"ltnNumber": "9262-6531-4941",
"transferId": "2020125708",
"charges": 250
}
}{
"status": false,
"code": "api.account.invalid_request",
"dialog": {
"title": "Sorry!",
"message": "api.account.invalid_request"
},
"extra": null,
"data": null
}Mobile Wallet response interpretation
| Case | Condition | Treat as |
|---|---|---|
| Success | status = true | Success |
| Pending | status = false and code = 500 | Pending |
| Failure | status = false and code ≠ 500 | Failure |
For Mobile Wallet outcomes, code is compared against the value 500. Elsewhere in the API code holds a string error identifier; handle this comparison specifically for Mobile Wallet sends.
{
"status": true,
"code": null,
"dialog": {
"title": "Success",
"message": "Your Account Has Been Successfully Topup"
},
"extra": null,
"data": {
"ltnNumber": "MW223871662783",
"transferId": "AA 2500000104",
"currency": null,
"charges": 250.0,
"collectionAmount": 30000.0,
"balance": 0.0,
"transactionId": 130482
}
}Cancel Transfer response
Field (in data) | Type | Description |
|---|---|---|
ltnNumber | String | LTN number of the transfer. |
transferId | String | Reference of the transfer. |
status | String | Resulting status of the transfer (e.g. CANCELED_FULL). |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"ltnNumber": "9262-6531-4941",
"transferId": "2020125708",
"status": "CANCELED_FULL"
}
}Get Transfer Status response
Field (in data) | Type | Description |
|---|---|---|
ltnNumber | String | LTN number of the transfer. |
transferId | String | Reference of the transfer. |
status | String | Status of the transfer (e.g. SENT, RECEIVED, CANCELED_FULL). |
receiverIdentity | Object | Receiver identity details (see nested fields). |
receiverIdentity.number | String | Identity number. |
receiverIdentity.type | String | Identity type (e.g. Lebanese ID). |
receiverIdentity.frontImage | String | URL of the identity front image. |
receiverIdentity.backImage | String | URL of the identity back image. |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"ltnNumber": "9262-6531-4941",
"transferId": "2020125708",
"status": "CANCELED_FULL",
"receiverIdentity": {
"number": "000042902600",
"type": "Lebanese ID",
"frontImage": "url",
"backImage": "url"
}
}
}Get Country response
Field (in data.list[]) | Type | Description |
|---|---|---|
id | Long | Country id. |
name | String | Country name. |
code | String | ISO country code (e.g. LB). |
defaultCurrencyId | Long | Default currency id for the country, or null. |
dateCreation | Long | Creation timestamp (epoch milliseconds). |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"list": [
{
"id": 1,
"name": "LEBANON",
"code": "LB",
"defaultCurrencyId": 2,
"dateCreation": 1570457810000
},
{
"id": 2,
"name": "Afghanistan",
"code": "AF",
"defaultCurrencyId": null,
"dateCreation": 1587573801000
}
]
}
}Get Activity response
Field (in data.list[]) | Type | Description |
|---|---|---|
id | String | Transfer id. |
status | String | Status of the transfer. |
amount | Double | Amount of the transfer. |
fee | Double | Fee of the transfer. |
total | Double | Total charges of the transfer. |
currency | String | Currency code. |
date | Long | Timestamp (epoch milliseconds). |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"list": [
{
"id": "2200000001",
"status": "",
"amount": 1000,
"fee": 20,
"total": 1020,
"currency": "USD",
"date": 1649173044000
},
{
"id": "2200000001",
"status": "",
"amount": 1000,
"fee": 0,
"total": 1000,
"currency": "USD",
"date": 1649174292000
}
]
}
}Get Statement response
Returns the statement grouped per currency.
| Field | Type | Description |
|---|---|---|
data.list[] | Array | One entry per currency. |
…transactions[] | Array | Transactions for the currency. |
…transactions[].id | String | Transaction id. |
…transactions[].type | String | Transaction type: TRANSFER or CANCELLATION. |
…transactions[].debit | Double | Debit amount. |
…transactions[].credit | Double | Credit amount. |
…transactions[].balance | Double | Balance after the transaction. |
…transactions[].currency | String | Currency code. |
…transactions[].date | String | Transaction date. Format: yyyy-MM-dd HH:mm:ss. |
…currentBalance | Object | Current balance for the currency. |
…currentBalance.currency | String | Currency code. |
…currentBalance.balance | Double | Balance amount. |
…currentBalance.date | String | Format: yyyy-MM-dd HH:mm:ss. |
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"list": [
{
"transactions": [
{
"id": "MIC2 2200000011",
"type": "TRANSFER",
"debit": 0,
"credit": 45522.75,
"balance": -2040695.5,
"currency": "LBP",
"date": "2022-04-06 11:30:20"
}
],
"currentBalance": {
"currency": "LBP",
"balance": -2040695.5,
"date": "2022-04-06 12:37:57"
}
},
{
"transactions": [
{
"id": "ARCADOUS 2200000001",
"type": "TRANSFER",
"debit": 0,
"credit": 1020,
"balance": -1690,
"currency": "USD",
"date": "2022-04-05 18:37:24"
}
],
"currentBalance": {
"currency": "USD",
"balance": -1690,
"date": "2022-04-06 12:37:57"
}
}
]
}
}Operations summary
| Operation | Method & path | Request body |
|---|---|---|
| Get Send Money Fees | POST /api/woo/send/money/fees | Sending Money Fees request |
| Send Money | POST /api/woo/send/money | Send Money request |
| Cancel Transfer | POST /api/woo/cancel/send/money | Cancel Transfer request |
| Get Transfer Status | POST /api/woo/send/money/status | Get Transfer Status request |
| Get Sending Countries | GET /api/woo/sending/countries | None |
| Get Activity | POST /api/woo/activity | Statement / Activity request |
| Get Statement | POST /api/woo/statement | Statement / Activity request |
| Get Payment Modes | GET /api/woo/send/money/modes | None |
Get send-money fees
Retrieve the fees for an amount to be sent, given the amount, currency, and payment mode.
Request body: Sending Money Fees request.
{
"fromCountry": 1,
"toCountry": 1,
"currencyId": 2,
"amount": 1,
"deductFees": false,
"paymentMode": "CASH_COLLECTION",
"phoneNumber": "9613888999"
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"fees": 5,
"amount": 400,
"totalAmount": 405
}
}{
"status": false,
"code": "transfer.invalid_amount",
"dialog": {
"title": "Sorry!",
"message": "Transfer Amount Outside Range"
},
"extra": null,
"data": null
}Error codes
| Code | Description |
|---|---|
transfer.invalid_amount | The amount is not within the price list. |
amount.not_allowed | The amount is less than the price or is negative. |
Send money
Create a transfer through Whish Money, specifying the amount, currency, countries, and parties.
Request-id must be unique for each transfer. See Request headers.
Request body: Send Money request.
{
"fromCountry": 1,
"toCountry": 1,
"currencyId": 1,
"amount": 1000,
"sender": {
"firstName": "personName",
"middleName": "m",
"lastName": "LastName",
"phone": "96170852258",
"extraInformation": "extraInformation"
},
"receiver": {
"firstName": "personName",
"middleName": "m",
"lastName": "LastName",
"phone": "96170852258",
"extraInformation": "extraInformation"
},
"reason": "GIFT",
"sourceOfFunds": "BUSSINESS",
"callbackUrl": "http://test.com"
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"ltnNumber": "9262-6531-4941",
"transferId": "2020125708",
"charges": 250
}
}{
"status": false,
"code": "transfer.reason_empty",
"dialog": {
"title": "Sorry!",
"message": "Transfer Reason is Missing"
},
"extra": null,
"data": null
}Error codes
| Code | Description |
|---|---|
api.account.invalid_request | Invalid account request. |
receiver.empty | Receiver information is missing. |
receiver.invalid.phone_number | Receiver phone number is invalid. |
receiver.customer.invalid_name | Receiver name is invalid. |
receiver.customer.info_invalid | Receiver information is invalid. |
receiver.customer.name_enlgish | Receiver name must be in English. |
sender.invalid.phone_number | Sender phone number is invalid. |
sender.customer.invalid_name | Sender name is invalid. |
sender.customer.info_invalid | Sender information is invalid. |
sender.customer.name_enlgish | Sender name must be in English. |
transfer.already.done | Transfer already completed. |
sender.missing_info | Sender information is missing. |
currency.not_supported | Currency not supported. |
transfer.invalid_amount | Amount is negative, or the sending amount is not found in the price list. |
transfer.reason_empty | Reason not provided in the request. |
transfer.from_country_not_allowed | Transfers from this country are not allowed. |
transfer.sourceOfFunds_empty | Source of funds not provided in the request. |
transfer.not_allowed_countries | Transfer to these countries is not allowed. |
transfer.account_reach_balance_limit | Reached balance limit, or insufficient funds. |
transfer.exceeds_account_transaction_limit | Sending amount exceeds the allowed transaction amount per transfer. |
service.inactive | Service is inactive. |
service.price_not_active | Service price is not active. |
transfer.miss_config | Transfer configuration is missing. |
service.transaction_status_unknown | Transaction status is unknown. |
service.transaction_failed | Transaction failed. |
sender.invalid.date.of.birth | Invalid date of birth. |
transfer.exceeds_account_daily_limit | Reached daily sending limit. |
receiver.whish.account.not.exists | Whish account does not exist (Mobile Wallet mode). |
receiver.customer.under_age | Receiver is underage. (Source description reads “>18”; interpret per your account rules.) |
sender.kyc.needed | Sender's KYC is required. |
receiver.kyc.needed | Receiver's KYC is required. |
sender.interview.needed | Additional information required for the sender. |
receiver.interview.needed | Additional information required for the receiver. |
Cancel transfer
Cancel a transfer that has already been sent, by transfer id and LTN number.
Request body: Cancel Transfer request.
{
"transferId": 202000001,
"ltnNumber": "5405-6838-5079",
"reason": "test"
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"ltnNumber": "9262-6531-4941",
"transferId": "2020125708",
"status": "CANCELED_FULL"
}
}{
"status": false,
"code": "transfer.not_exists",
"dialog": {
"title": "Sorry!",
"message": "Transfer Not Found"
},
"extra": null,
"data": null
}Error codes
| Code | Description |
|---|---|
transfer.not_exists | Transfer id not found. |
transfer.cannot_be_canceled | The transfer is already canceled or received. |
Get transfer status
Retrieve the current status of a transfer.
Request body: Get Transfer Status request.
{
"transferId": 202000001,
"ltnNumber": "5405-6838-5079"
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"ltnNumber": "9262-6531-4941",
"transferId": "2020125708",
"status": "CANCELED_FULL"
}
}{
"status": false,
"code": "transfer.not_exists",
"dialog": {
"title": "Sorry!",
"message": "Transfer Not Found"
},
"extra": null,
"data": null
}Error codes
| Code | Description |
|---|---|
sending.transfer.invalid.info | Sending transfer info is invalid. |
transfer.not_exists | Transfer does not exist. |
Response handling
If status = true → treat the request as successful and read data.status for the actual transaction status (e.g. SENT, RECEIVED, CANCELED_FULL).
If status = false → branch on the error code:
• sending.transfer.invalid.info → the referenced transfer does not exist in Whish Money's records. Usually this means the original Send Money request never arrived. Resend it with the same Request-id before checking status again. See Handling timeouts & network issues.
• transfer.not_exists → treat as Failed.
• Any other code → apply the transaction status interpretation (code: 500 is Pending and warrants follow-up; other codes are final failures).
Callback (Cash Collection only): if you send the original requestId in the body, this call re-evaluates the transfer and triggers your configured callbackUrl when the status has changed (for example from SENT to RECEIVED). Mobile Wallet has no callback; its outcome is final at send time.
Get sending countries
Retrieve the list of countries allowed to send from.
Request body: None.
In the source spec the section heading reads POST /api/woo/sending/countires, while the request line specifies GET /api/woo/sending/countries with no body. Both the method and the spelling are inconsistent in the source; this reference documents it as GET …/countries. Confirm the exact method with Whish Money if your call fails.
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"list": [
{
"id": 1,
"name": "LEBANON",
"code": "LB"
},
{
"id": 2,
"name": "Afghanistan",
"code": "AF"
}
]
}
}Get activity
Retrieve transfers sent or received within a given period.
Request body: Statement / Activity request.
{
"fromDate": "2020-01-01 00:00:00",
"toDate": "2022-01-01 00:00:00",
"currencyId": 1
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"list": [
{
"id": "2200000001",
"status": "",
"amount": 1000,
"fee": 20,
"total": 1020,
"currency": "USD",
"date": 1649173044000
},
{
"id": "2200000001",
"status": "",
"amount": 1000,
"fee": 0,
"total": 1000,
"currency": "USD",
"date": 1649174292000
}
]
}
}{
"status": false,
"code": "transfer.invalid_amount",
"dialog": {
"title": "Sorry!",
"message": "Error"
},
"extra": null,
"data": null
}Get statement
Retrieve the account statement within a given period, grouped per currency.
Request body: Statement / Activity request.
{
"fromDate": "2020-01-01 00:00:00",
"toDate": "2022-01-01 00:00:00",
"currencyId": 1
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"list": [
{
"transactions": [
{
"id": "MIC2 2200000011",
"type": "TRANSFER",
"debit": 0,
"credit": 45522.75,
"balance": -2040695.5,
"currency": "LBP",
"date": "2022-04-06 11:30:20"
}
],
"currentBalance": {
"currency": "LBP",
"balance": -2040695.5,
"date": "2022-04-06 12:37:57"
}
},
{
"transactions": [
{
"id": "ARCADOUS 2200000001",
"type": "TRANSFER",
"debit": 0,
"credit": 1020,
"balance": -1690,
"currency": "USD",
"date": "2022-04-05 18:37:24"
}
],
"currentBalance": {
"currency": "USD",
"balance": -1690,
"date": "2022-04-06 12:37:57"
}
}
]
}
}{
"status": false,
"code": "error",
"dialog": {
"title": "Sorry!",
"message": "Error"
},
"extra": null,
"data": null
}Get payment modes
Retrieve the payment modes supported by your account.
Request body: None.
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": ["CASH_COLLECTION", "MOBILE_WALLET"]
}{
"status": false,
"code": "error",
"dialog": {
"title": "Sorry!",
"message": "Error"
},
"extra": null,
"data": null
}Callbacks & status updates
callbackUrl applies to Cash Collection mode only. Mobile Wallet does not use callbacks, because its outcome is known instantly at send time (see Mobile Wallet below).
In Cash Collection mode a transfer moves through several statuses (SENT, RECEIVED, CANCELED_FULL), so Whish Money needs a way to tell you when the transaction changes. When you provide a callbackUrl in the Send Money request, Whish Money calls it when the transaction status changes from SENT to RECEIVED.
Cash Collection transfer statuses
| Status | Meaning |
|---|---|
SENT | The transfer has been sent and is available for collection. |
RECEIVED | The receiver has collected the transfer. The callback fires on this transition from SENT. |
CANCELED_FULL | The transfer has been fully cancelled. |
Triggering the callback manually
You can also trigger the callback on demand by calling Get Transfer Status with the same requestId in the request body (the Request-id you sent with the original transfer). This re-evaluates the transaction and fires your callbackUrl if the status has changed.
Pass the original Request-id as requestId in the Get Transfer Status body to reference the transfer and re-trigger its callback. See Get Transfer Status.
Mobile Wallet
Mobile Wallet does not support callbackUrl. The outcome is determined instantly by the Send Money response: the transaction either succeeds or fails, with no intermediate statuses to track. There is nothing to notify later, so no callback is sent. See Mobile Wallet response interpretation.
Reference data
Currencies
| Currency | Id |
|---|---|
| LBP | 1 |
| USD | 2 |
Countries
Currently only Lebanon (id = 1, code LB) is supported for sending and receiving. Use Get Sending Countries for the live list.
Payment modes
| Value | Description |
|---|---|
CASH_COLLECTION | Receiver collects cash from a Whish Money agent using the ltnNumber. |
MOBILE_WALLET | Funds are credited directly to a Whish mobile wallet account. |
Source of Funds (SoF)
| Value | Description |
|---|---|
| Salary | Income earned from employment, wages, or regular payroll. |
| Income from Own Business | Revenue generated from operating a personal or self-owned business. |
| Income from Investments | Returns or profits from investments such as stocks, bonds, dividends, or interest. |
| Rent | Income received from renting out property, land, or other assets. |
| Inheritance | Funds received from the estate of a deceased individual. |
| Savings | Money accumulated and withdrawn from personal savings or bank accounts. |
| Sale of Property or Goods | Proceeds from selling physical property, assets, or personal goods. |
| Loan | Money borrowed from financial institutions, individuals, or other entities. |
| Lottery / Gambling | Funds from lottery winnings, betting, or other gambling activities. |
| Other | Any source of funds not covered by the categories above. |
Reason
| Value | Description |
|---|---|
| Donations & Gifts | Voluntary donations or personal gifts to individuals or organizations. |
| Education | Educational expenses such as tuition, fees, books, or training programs. |
| Family Support | Financial assistance to family members for living or personal needs. |
| Medical Treatment | Healthcare services, treatments, medication, or hospital fees. |
| Purchase of Goods | Buying goods, products, or merchandise. |
| Travel Expenses | Costs associated with travel spending. |
| Insurance Plan / Claim | Insurance premiums, or funds received/used as part of an insurance claim. |
| Retirement / Pension | Contributions to or withdrawals from retirement or pension funds. |
| Other | Any reason not covered by the categories above. |
The sample requests use short enum-style tokens (e.g. reason: "GIFT", sourceOfFunds: "BUSSINESS"). Confirm with Whish Money whether your account expects the display values above or coded tokens, and use the exact strings your account is provisioned with.
Consolidated error codes
When status = false, the code field carries one of the identifiers below. Surface dialog.message to end users and branch your logic on code. Error codes are literal API values and are reproduced exactly, including their original spelling.
| Code | Description | Endpoint(s) |
|---|---|---|
api.account.invalid_request | Invalid account request. | All |
amount.not_allowed | The amount is less than the price or is negative. | Fees |
transfer.invalid_amount | Amount not within the price list / negative. | Fees, Send, Activity |
receiver.empty | Receiver information is missing. | Send |
receiver.invalid.phone_number | Receiver phone number is invalid. | Send |
receiver.customer.invalid_name | Receiver name is invalid. | Send |
receiver.customer.info_invalid | Receiver information is invalid. | Send |
receiver.customer.name_enlgish | Receiver name must be in English. | Send |
receiver.customer.under_age | Receiver is underage. | Send |
receiver.whish.account.not.exists | Whish account does not exist (Mobile Wallet). | Send |
sender.invalid.phone_number | Sender phone number is invalid. | Send |
sender.customer.invalid_name | Sender name is invalid. | Send |
sender.customer.info_invalid | Sender information is invalid. | Send |
sender.customer.name_enlgish | Sender name must be in English. | Send |
sender.missing_info | Sender information is missing. | Send |
sender.invalid.date.of.birth | Invalid date of birth. | Send |
sender.kyc.needed | Sender's KYC is required. | Send |
receiver.kyc.needed | Receiver's KYC is required. | Send |
sender.interview.needed | Additional information required for the sender. | Send |
receiver.interview.needed | Additional information required for the receiver. | Send |
currency.not_supported | Currency not supported. | Send |
transfer.reason_empty | Reason not provided. | Send |
transfer.sourceOfFunds_empty | Source of funds not provided. | Send |
transfer.from_country_not_allowed | Transfers from this country are not allowed. | Send |
transfer.not_allowed_countries | Transfer to these countries is not allowed. | Send |
transfer.account_reach_balance_limit | Reached balance limit / insufficient funds. | Send |
transfer.exceeds_account_transaction_limit | Amount exceeds per-transfer limit. | Send |
transfer.exceeds_account_daily_limit | Reached daily sending limit. | Send |
transfer.already.done | Transfer already completed. | Send |
transfer.miss_config | Transfer configuration is missing. | Send |
service.inactive | Service is inactive. | Send |
service.price_not_active | Service price is not active. | Send |
service.transaction_status_unknown | Transaction status is unknown. | Send |
service.transaction_failed | Transaction failed. | Send |
transfer.not_exists | Transfer does not exist / id not found. | Cancel, Status |
transfer.cannot_be_canceled | Transfer already canceled or received. | Cancel |
sending.transfer.invalid.info | Sending transfer info is invalid. | Status |
error | Generic error. | Statement, Modes |
For Mobile Wallet sends only, code may carry the numeric value 500 to indicate a Pending transaction. See Mobile Wallet response interpretation.
Integration best practices
- Test in Sandbox first. Verify every flow against
sandbox.woocash.moneybefore requesting Production access, and remember the differing base-URL conventions between environments. - Quote before you send. Call Get Send Money Fees to confirm fees and total, then send with the same amount and currency.
- Use a unique
Request-idper transfer. Generate an idempotent value (e.g. a UUID) for each send to avoid duplicates, and store it so you can later query byrequestId. - Branch on
status, not HTTP code. All responses return HTTP200; the outcome lives in the body. - Mobile Wallet is instant. Its outcome is final in the Send Money response (no callback). Map
status = false+code = 500to Pending and reconcile later. - Callbacks are Cash Collection only. Configure
callbackUrlfor Cash Collection and update state when the transfer moves fromSENTtoRECEIVED. You can re-trigger it by calling Get Transfer Status with the originalrequestId. - Escalate unknown status codes. On Get Transfer Status, any code other than
sending.transfer.invalid.infoortransfer.not_existsshould be escalated to Whish Money rather than assumed failed. - Use English names. Sender and receiver names must be in English, or the send is rejected (
*.name_enlgish). - Store references. Persist
transferIdandltnNumberfrom every send; both are needed for cancel and status lookups. - Secure your credentials. Keep
username/keyserver-side and out of logs and version control. - Respect limits. Design for per-transfer, daily, and balance limits, and surface
dialog.messageto end users when they are hit. - Reconcile regularly. Use Get Activity and Get Statement to reconcile your ledger against Whish Money.
Sandbox test cases
Cash Collection
| Scenario | Input | Expected result |
|---|---|---|
| English name | Valid | PASS |
| Arabic name | Invalid | FAIL |
Mobile Wallet
| Scenario | Input | Expected result |
|---|---|---|
| Payment to wallet | 96170123456 | PASS |
| Payment to wallet | 96170123123 | FAIL |
Postman & tools
Import the ready-made Postman collection for this API, set your username and key as collection variables (or attach a Sandbox / Production environment), and call every endpoint without writing code. Request-id auto-generates a unique GUID per send.
⤓ Download collection All downloads & environments
In Postman: Import → select the file → choose the Sandbox or Production environment → fill in your credentials. Requests use {{baseUrl}} and the credential variables provided.