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.
The LigdiCash PHP SDK installs via Composer and works with any PHP backend. Network calls are synchronous. The SDK uses Guzzle as its HTTP client.
Installation
composer require ligdicash/ligdicash
Requirements: PHP ≥ 7.4. Guzzle is installed automatically as a dependency.
Initialization
require_once 'vendor/autoload.php';
$client = new \Ligdicash\Ligdicash([
"api_key" => "{API_KEY}",
"auth_token" => "{AUTH_TOKEN}",
"platform" => "live",
]);
Get your api_key and auth_token from the LigdiCash dashboard by creating an API project.
Hosted payin
The customer is redirected to the payment page hosted by LigdiCash. This is the recommended flow for online stores.
// 1. Create the invoice
$invoice = $client->Invoice([
"currency" => "xof",
"description" => "Order #ORD-20240512",
"customer_firstname" => "Amadou",
"customer_lastname" => "Ouedraogo",
"customer_email" => "amadou@example.com",
"store_name" => "MySuperStore",
"store_website_url" => "https://mysuperstore.com",
]);
// 2. Add items
$invoice->addItem([
"name" => "Kente shirt",
"description" => "Size M",
"quantity" => 2,
"unit_price" => 15000,
]);
$invoice->addItem([
"name" => "Shipping fee",
"description" => "",
"quantity" => 1,
"unit_price" => 1500,
]);
// 3. Start the payment
$response = $invoice->payWithRedirection([
"return_url" => "https://mysuperstore.com/order/success",
"cancel_url" => "https://mysuperstore.com/order/cancel",
"callback_url" => "https://backend.mysuperstore.com/ligdicash/callback",
"custom_data" => ["transaction_id" => "ORD-20240512"],
]);
// 4. Redirect the customer
$paymentUrl = $response->response_text;
header("Location: $paymentUrl");
exit;
Never open $paymentUrl in an iframe — LigdiCash blocks it. Redirect in the same tab, a new tab, or a popup.
Always leave customer empty (or absent) in hosted payin. If you pass a number, LigdiCash filters the payment page to show only the operators tied to that number.
Direct payin
The customer pays directly from your interface. You must collect their phone number and, depending on the operator, their OTP code.
// 1. Create the invoice
$invoice = $client->Invoice([
"currency" => "xof",
"description" => "Order #ORD-20240512",
"customer_firstname" => "Amadou",
"customer_lastname" => "Ouedraogo",
"customer_email" => "amadou@example.com",
"store_name" => "MySuperStore",
"store_website_url" => "https://mysuperstore.com",
]);
$invoice->addItem([
"name" => "Kente shirt", "description" => "Size M",
"quantity" => 2, "unit_price" => 15000,
]);
// 2. Start the payment (with OTP provided by the customer)
$response = $invoice->payWithoutRedirection([
"otp" => "123456", // OTP code entered by the customer
"customer" => "22670123456", // Customer phone number, no + or spaces
"callback_url" => "https://backend.mysuperstore.com/ligdicash/callback",
"custom_data" => ["transaction_id" => "ORD-20240512"],
]);
// 3. Store the token for later verification
$token = $response->token;
The OTP mode varies by operator. For example, with a USSD operator, the customer generates the OTP on their phone before you submit. For an approval-mode operator (e.g. Moov Africa), send "otp" => "" — the customer approves directly in their app. See the operator page for details.
Payout
Send money to a customer — refund, salary, payout.
To the customer’s LigdiCash wallet
$withdrawal = $client->Withdrawal([
"amount" => 5000,
"description" => "Refund for order ORD-20240510",
"customer" => "22670123456",
]);
$response = $withdrawal->send([
"type" => "client",
"to_wallet" => false, // false = automatic transfer to the linked mobile money account
"callback_url" => "https://backend.mysuperstore.com/ligdicash/callback-payout",
"custom_data" => ["transaction_id" => "REFUND-20240512"],
]);
$token = $response->token;
Directly to mobile money
$response = $withdrawal->send([
"type" => "merchant", // Direct payout, no intermediate wallet
"callback_url" => "https://backend.mysuperstore.com/ligdicash/callback-payout",
"custom_data" => ["transaction_id" => "PAY-20240512"],
]);
"type" => "client" uses POST /pay/v01/withdrawal/create (via the LigdiCash wallet). "type" => "merchant" uses POST /pay/v01/straight/payout (direct mobile money, slower). See Payout — Introduction.
Status verification
Call getTransaction with the token stored at creation (not the callback token, which is different).
$token = "eyJ0eXAiOiJ..."; // Token returned at creation
// Payin
$transaction = $client->getTransaction([
"token" => $token,
"type" => "payin", // "payin" or "payout"
]);
if ($transaction->status === "completed") {
// Deliver the order / validate the payment
} elseif ($transaction->status === "pending") {
// Payment in progress — retry in a few seconds
} else {
// Payment failed or cancelled
}
In PHP, the type parameter of getTransaction accepts "payin" or "payout" (not "client_payout" or "merchant_payout" as in the Python and JavaScript SDKs).
Fields available on $transaction:
| Property | Type | Description |
|---|
status | string | "completed", "pending", "cancelled" |
response_code | string | "00" success, "01" failure |
amount | int | Transaction amount |
operator_id | string | Operator identifier |
operator_name | string | Operator name |
customer | string | Customer phone number |
token | string | Transaction token |
custom_data | array | Custom data sent at creation |
wiki | array | Links to the endpoint’s error codes |
Never deliver an order solely based on an incoming callback. Always call getTransaction with the token stored at creation to confirm the status on the LigdiCash server side. See Callback security.
Error handling
try {
$response = $invoice->payWithRedirection([
"return_url" => "https://mysuperstore.com/success",
"cancel_url" => "https://mysuperstore.com/cancel",
"callback_url" => "https://backend.mysuperstore.com/callback",
"custom_data" => ["transaction_id" => "ORD-20240512"],
]);
} catch (\InvalidArgumentException $e) {
// Missing or invalid parameter (currency, type, etc.)
echo $e->getMessage();
} catch (\Exception $e) {
// Network error or error returned by the API
echo $e->getMessage();
}
Also check $response->response_code after every call: "00" indicates success, "01" an error. On error, read $response->wiki to get the URL with sub-code details.
Useful links