Skip to content
REST API

Whish Pay API

v1.4.3

Collect payments from your customers through their Whish balance. Generate a hosted payment page, track status, and issue refunds. REST over HTTPS with JSON requests and responses, for authorized distributors.

JSON over HTTPSUSD · LBPBuilt by TecFrac

Base URL

api.whish.money/itel-service/api

Getting started

Overview

Authentication is by channel + secret + websiteUrl, issued by Whish. Payments settle in USD · LBP. This is API v1.4.3; breaking changes are released under a new version.

Note

Flow. Call Create a payment to get a collectUrl, then redirect the payer there. To confirm the outcome, rely on your successCallbackUrl and failureCallbackUrl as the primary signal. Whish calls these when the payment settles. Use Get payment status only as a fallback, for example if a callback did not arrive.

Getting started

Authentication & headers

Every request must include the headers below, plus Content-Type: application/json on requests that send a body.

HeaderDescription
channelValue provided by Whish.
secretValue provided by Whish.
websiteUrlSite URL or app name. Use the exact value Whish issued with your keys.
User-AgentIdentifies your app. Use your own details, not Whish's. Format: AppName/version (website; contact-email). Example: AcmeStore/2.1 (https://acme.example; dev@acme.example).

Important

Keep credentials server-side. channel and secret are server-side credentials. Never expose them in browser code, mobile apps, or public repositories. Call the API only from a secure backend, and contact Whish to rotate credentials if they are exposed.

Getting started

Environments

EnvironmentBase URLPurpose
Sandboxhttps://api.sandbox.whish.money/itel-service/apiTesting, QA, integration verification.
Productionhttps://api.whish.money/itel-service/apiLive environment for real transactions.

Getting started

Response format

All endpoints return HTTP 200 with Content-Type: application/json and a shared envelope. Always branch on the status and code fields in the body, never on the HTTP status code.

FieldTypeDescription
statusBooleantrue when the call succeeded. false when it did not; read code to tell a definitive failure apart from a pending result.
codeStringnull on success. When status is false, an operation-specific code; the value 500 is special (see below).
dialogObjectOptional title / message to display to the user.
dataObjectResponse payload for the operation; shape varies per endpoint, and may be a scalar or null for some operations.
actions / extraObjectReserved; typically null.
retrievedBooleanPresent on idempotent operations. true means this response replays an already-processed request (the original was not run again); false or absent means it ran now.

Interpret the outcome from status and code:

ResponseTreat as
status: trueCall succeeded
status: false and code: 500Pending (outcome unknown; escalate to Whish and do not mark it failed)
status: false and any other codeFailed; read code (and any dialog message) to see why.

Getting started

Integration flow

The happy path from a checkout to a confirmed order. Each step links to its endpoint below.

  1. 1

    Create a payment

    Call Create a payment with the amount, currency, your numeric externalId, and your callback URLs. You receive a collectUrl.

  2. 2

    Redirect the payer

    Send the customer to the collectUrl. They pay from their Whish balance and authorize the charge by entering the OTP delivered to their Whish app. This happens entirely on the hosted page; your integration is not involved in it.

  3. 3

    Receive the callback

    When the payment settles, Whish calls your successCallbackUrl or failureCallbackUrl by GET.

  4. 4

    Confirm before fulfilling

    Call Get payment status to verify the outcome, then release the order. Poll it as a fallback if no callback arrived.

  5. 5

    Refund if needed

    Use Refund a payment with the original externalId.

Endpoint

Get account balance

GET/payment/account/balance?currency={currency}

Returns the real balance of the account. Pass currency as a query-string parameter on the request URL to choose which balance to return.

Query parameters

FieldTypeDescription
currencyRequiredStringCurrency to return the balance for: USD or LBP. Sent in the query string, for example ?currency=USD.
200 · application/json (USD)
{
  "status": true,
  "code": null,
  "dialog": null,
  "actions": null,
  "extra": null,
  "data": {
    "balance": 10439.0
  }
}

Note

Each channel supports two currencies (USD and LBP). Use currency to pick which balance to return.

Endpoint

Create a payment

POST/payment/whish

Returns the hosted URL where the client is redirected to pay the merchant through their Whish balance.

Request body

FieldTypeDescription
amountStringAmount to be paid, sent as a JSON string (double-quoted). USD allows up to 2 decimals (minimum 1.00); LBP takes no decimals (minimum 1000).
currencyStringCurrency: USD or LBP.
invoiceStringDescription/details of the payment.
externalIdLongYour unique reference for the payment, and the idempotency key. Reusing an externalId within your channel returns the original response and does not charge again.
successCallbackUrlStringGET callback URL for a successful transaction.
failureCallbackUrlStringGET callback URL for a failed transaction.
successRedirectUrlStringRedirect URL after a successful payment.
failureRedirectUrlStringRedirect URL after a failed payment.
Request body
{
  "amount": "1",
  "currency": "USD",
  "invoice": "Order #1",
  "externalId": 1,
  "successCallbackUrl": "https://example.com/api/payment/success",
  "failureCallbackUrl": "https://example.com/api/payment/failure",
  "successRedirectUrl": "https://example.com/thank-you",
  "failureRedirectUrl": "https://example.com/payment-error"
}
200 · application/json
{
  "status": true,
  "code": null,
  "dialog": null,
  "extra": null,
  "data": {
    "collectUrl": "https://whish.money/pay/8nQS2mL"
  }
}

Note

status: true here means the request succeeded and a collectUrl was generated. It does not mean the customer has paid. The payment outcome is separate: it is delivered to your callback URLs and can be checked with Get payment status.

Note

The callback URLs are your primary confirmation. Whish calls them via GET when the payment settles, so treat them as the source of truth and update the order from them. The redirect URLs only send the client's browser onward. You may append custom query params (order reference, timestamp), and Whish forwards them unchanged. No OTP is delivered in sandbox.

Note

Sandbox test: use phone 96170902894 with OTP 111111 for a successful payment; any other phone number or OTP produces a failure. Sandbox credentials are separate from Production.

Endpoint

Get payment status

POST/payment/collect/status

Returns the collect status of a Whish Pay transaction. Use this endpoint as a fallback to reconcile when a callback did not arrive; the callback URLs remain the primary confirmation.

Request body

FieldTypeDescription
currencyStringCurrency: USD or LBP.
externalIdLongID provided by the third party.
Request body
{
  "currency": "USD",
  "externalId": 1
}
200 · application/json
{
  "status": true,
  "code": null,
  "dialog": null,
  "extra": null,
  "data": {
    "collectStatus": "success",
    "payerPhoneNumber": "96170902894"
  }
}

Response fields

FieldTypeDescription
collectStatusStringpending, success, failed, refunded (after a refund), or unknown (final state could not be determined).
payerPhoneNumberStringPhone number that performed the payment.

Endpoint

Refund a payment

POST/payment/whish/refund

Initiates a full refund for a Whish Pay transaction (partial refunds are not supported). Requires IP whitelisting: it only accepts requests from source IPs that Whish has registered for your account. Send Whish the public egress IP(s) your servers call from, for both Sandbox and Production; otherwise refund requests are rejected. See IP whitelisting below.

Request body

FieldTypeDescription
currencyStringCurrency: USD or LBP.
externalIdLongID of the original transaction to refund.
refundReasonStringReason for the refund.
Request body
{
  "currency": "USD",
  "externalId": 1,
  "refundReason": "Customer canceled order"
}
200 · success
{
  "status": true,
  "code": null,
  "dialog": null,
  "actions": null,
  "extra": null,
  "retrieved": false,
  "data": null
}
200 · already processed (duplicate externalId)
{
  "status": true,
  "code": null,
  "dialog": null,
  "actions": null,
  "extra": null,
  "retrieved": true,
  "data": null
}
failure
{
  "status": false,
  "code": "external_id.not_exists",
  "dialog": null,
  "actions": null,
  "extra": null,
  "data": null
}

Response fields

FieldTypeDescription
retrievedBooleantrue when you try to refund a transaction that was already refunded (a duplicate refund attempt).

Note

Refunds are instant and the customer is notified. The original transaction is not modified; a separate reversal entry is recorded, and the transaction cannot be refunded again. There is no refund time window.

Reference

Callbacks

When a payment settles, Whish sends an HTTP GET request to the successCallbackUrl or failureCallbackUrl you supplied in Create a payment, with your query parameters and nothing added by Whish. Which URL is called tells you the result. The callback is your primary confirmation; the browser redirect is not.

Important

Authenticate every callback. Whish does not sign callbacks, and IP allowlisting is only a network filter, not proof of authenticity. Add a per-payment secret token to your callback URLs and verify it on receipt with a constant-time comparison. This is exactly what the official WooCommerce plugin does.

Handle callbacks like this:

  • Whish sends the callback once and does not retry. If your endpoint is unavailable when it fires, you will not receive it again, so reconcile with Get payment status using the externalId.
  • Before you fulfil the order, confirm the outcome with Get payment status. Requests are idempotent by externalId, so re-checking is always safe.
  • Callback URLs must use HTTPS and be publicly reachable. localhost and private addresses will not receive callbacks.

Reference

Error codes

On failure, read code from the response body. Match on the exact literal value, including any unusual spelling. The documented code is below; code: 500 is a pending result, not a failure (see Response format).

CodeDescription
external_id.not_existsThe provided externalId does not exist.

Note

This list is not exhaustive. Other codes exist (for example around disabled channels and version requirements). Ask Whish for the complete error catalogue with each code's meaning, cause, whether it is retryable, and who must act.

Reference

IP whitelisting

Two kinds of IP allowlisting apply, in opposite directions. Set up whichever your integration needs.

1. Inbound: your IP, allowlisted by Whish (required for Refund)

The Refund endpoint only accepts requests from source IPs Whish has registered for your account. Register or update your public egress IP(s) by contacting Whish Money, per environment (Sandbox and Production); otherwise refund requests are rejected.

2. Outbound: Whish's IPs, allowlisted by you (for callbacks)

Whish calls your callback URLs from the fixed addresses below. If your infrastructure restricts inbound traffic, allow all of them so callbacks are not blocked. If these addresses change, they will be updated on this page.

EnvironmentOutbound callback IPs
Production18.213.222.4552.21.189.5152.21.55.64
Sandbox52.4.4.47

Reference

Troubleshooting

ProblemWhat to check
A request is rejected or credentials are not acceptedConfirm channel, secret, and websiteUrl exactly match the values Whish issued, and that you are calling the base URL for the same environment (Sandbox vs Production). Credentials are environment-specific.
status: false with code: 500This is a pending result, not a failure. Do not mark the order failed. Reconcile with Get payment status and retry later if it is still pending.
A refund is rejectedThe Refund endpoint requires IP whitelisting. Confirm your server's public egress IP for this environment is registered with Whish (see IP whitelisting).
external_id.not_exists on status or refundThe externalId does not match a transaction in this environment. Verify you are using the same externalId and the same environment as the original payment.
A callback never arrivesMake sure your callback URL is publicly reachable over HTTPS (not localhost or a private address) and not blocked by a firewall. Allowlist Whish's outbound IPs if you filter inbound traffic, and reconcile with Get payment status as a fallback.
The customer paid but the order is still pendingA browser redirect is not proof of payment. Rely on the callback and confirm with Get payment status using the externalId before fulfilling the order.

Reference

Postman & tools

Import the collection and one of the environment files, fill in your credentials, and call every endpoint without writing code. The {{baseUrl}} defaults to Sandbox so you cannot accidentally hit Production; switch to the Production environment for live traffic. Each request ships with an example response.

For credentials, Production access, or clarification, contact the Whish Pay team at whishpay@whish.money.