This page lists the most frequent errors seen during integration and production, based on real-world feedback from LigdiCash merchants.Documentation Index
Fetch the complete documentation index at: https://developers.ligdicash.com/llms.txt
Use this file to discover all available pages before exploring further.
Sub-codes (
Echec (CodeXX)) are specific to each endpoint. See the sub-codes reference for the full mapping. To decode a sub-code in production, use the wiki field returned in the response.Authentication failure
Symptom:response_code: "01", response_text: "Echec (Code00)" on every request.
Likely causes:
- The
Apikeyheader is missing or wrong - The
Authorizationheader does not follow theBearer {AUTH_TOKEN}format - The authorization token has expired or been revoked
- The keys you are using belong to a different API project
cURL
Payin or payout not enabled on the account
Symptom:response_code: "01", response_text: "Echec (Code01)" right at transaction creation.
Cause: The payin or payout feature is not enabled on your LigdiCash API project.
Solution:
Contact the LigdiCash team to enable the relevant feature: developper@ligdicash.com or via your Partner Manager. Provide your API project identifier.
Wrong payout route
Symptom:response_code: "01", response_text: "Echec (Code02)" on the withdrawal/create endpoint, with description “Customer not registered on the platform”.
Cause: The POST /pay/v01/withdrawal/create endpoint performs a payout to the customer’s LigdiCash wallet. It therefore requires the customer to have an account on the LigdiCash platform. If you want to send funds directly to a mobile money number without a pre-existing LigdiCash account, you must use the other endpoint.
See Payout to LigdiCash wallet and Payout to mobile money to pick the right route for your use case.
IP not whitelisted
Symptom:response_code: "01", response_text: "Echec (Code03)" (createInvoice) or "Echec (Code06)" (createWithdrawal / createStraightWithdrawal) — “IP Denied”.
Cause: Payout endpoints require the calling server’s IP address to be whitelisted on your LigdiCash project. If your server uses a dynamic IP (one that changes on every restart or reconnection), you will be blocked as soon as the IP changes.
Important constraint: LigdiCash limits the number of whitelisted IPs to 3 addresses maximum per project.
Solution:
- Identify the static IP address of your production server.
- Send it to LigdiCash technical support (developper@ligdicash.com) so they can add it to your project’s whitelist — this cannot be done from the merchant dashboard.
- If your infrastructure uses dynamic IPs (shared hosting, VPS without static IP, CI/CD), you must either:
- Route all calls to LigdiCash through an outbound proxy with a static IP
- Migrate to hosting with a dedicated static IP
The 3-IP cap matters if you have multiple environments (development, staging, production). Reserve the 3 slots for your production servers and test in staging from the same IP if possible. Anticipate this request before going live — the configuration delay depends on LigdiCash support.
Merchant balance too low on a specific operator
Symptom:response_code: "01", response_text: "Echec (Code04)" (createWithdrawal) or "Echec (Code08)" (createStraightWithdrawal) — “Merchant balance low” or “Merchant operator account low balance”.
Cause: Your LigdiCash merchant account holds a separate balance per operator. A payout to Orange Money Burkina debits your Orange Burkina balance, not your global balance. If that operator-level balance is too low, the payout fails even when your global balance is positive.
Solution:
Top up the balance for the relevant operator via the LigdiCash dashboard. Monitor balances per operator independently and set up low-balance alerts for every operator you use.
Amount out of range
Symptom:response_code: "01", response_text: "Echec (Code02)" on createInvoice — “Wrong amount”.
Likely causes:
- Amount below 9 CFA francs or above 2,000,000 CFA francs (LigdiCash global limits)
- Non-integer amount (
500.5instead of500or501) - Customer’s daily mobile money limit reached on the operator side
Node.js
Transaction stuck in pending despite a valid OTP
Symptom: The transaction stays instatus: "pending" indefinitely even though the customer says they generated the OTP correctly.
Cause: For operators in USSD OTP mode (Orange Money Burkina Faso, etc.), the customer generates an OTP from their USSD menu by entering the exact transaction amount. If you configured your integration so that fees are charged to the customer, the amount the customer must enter in the USSD is the base amount plus the fees. If the customer only enters the base amount, the OTP is valid but the expected amount does not match — LigdiCash cannot validate the transaction and leaves it in pending.
Example:
- Transaction amount: 10,000 CFA francs
- Fees charged to the customer: 200 CFA francs
- Amount to enter in the USSD: 10,200 CFA francs
- If the customer enters 10,000 CFA francs → OTP valid but wrong amount → indefinite
pending
Misunderstanding the pending status
Symptom: You expect a callback withstatus: "notcompleted" after an invalid or expired OTP, but no callback arrives — the transaction stays in pending indefinitely.
Cause: LigdiCash does not automatically consider a transaction failed because the OTP was wrong. From LigdiCash’s point of view, the transaction can still succeed if the customer provides the right OTP — the waiting window is undefined. LigdiCash only sends a notcompleted callback when the operator itself signals a definitive failure. Until that signal arrives, the transaction stays in pending, whether 5 minutes or several hours pass.
Solution:
Define a merchant-side timeout (for example 15 minutes after creation) past which you flip the transaction to timeout in your database and notify the customer to start over:
Node.js
Double callback not deduplicated
Symptom: A single transaction triggers two actions in your system (double delivery, double credit, etc.). Cause: LigdiCash systematically sends two POST requests for each callback event: one asapplication/x-www-form-urlencoded and one as application/json. This behavior is normal and documented. If your callback handler does not deduplicate, it will process both requests.
Solution:
Check your database to see if the transaction has already been processed before running any business logic:
Node.js
Callback received but transaction not found in database
Symptom: You receive a valid callback but your system can’t find the matching transaction, or callingconfirm returns Echec (Code02) — Invoice not found.
Likely causes:
- You’re looking up the transaction with an identifier other than the
transaction_idyou stored at creation (internal ID, order number, callback token, etc.) - You’re using the
tokenfrom the callback payload to callconfirm, when you should use thetokenfrom creation
transaction_id you sent in custom_data at creation, and look up the transaction with that same transaction_id in the callback:
Node.js
Related pages
- The wiki field — decode
Echec (CodeXX)into a human-readable message - Sub-codes reference — full list by endpoint
- Idempotency and deduplication — handle double callbacks
- Callback security — re-verification via confirm
- transaction_id pattern — identify your transactions reliably
