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 Python SDK exposes three main objects — Invoice, Withdrawal, and get_transaction — covering every payment flow. Unlike the other SDKs, initialization uses module-level globals, not a class instance.
Installation
Requirements: Python ≥ 3.0. The requests dependency is installed automatically.
Initialization
import ligdicash
ligdicash.api_key = "{API_KEY}"
ligdicash.auth_token = "{AUTH_TOKEN}"
ligdicash.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 LigdiCash-hosted payment page. This is the recommended flow for online stores.
import ligdicash
# 1. Describe the invoice
invoice = ligdicash.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.add_item(name="Kente shirt", description="Size M", quantity=2, unit_price=15000)
invoice.add_item(name="Shipping fee", description="", quantity=1, unit_price=1500)
# 3. Start the payment
response = invoice.pay_with_redirection(
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
payment_url = response.response_text
redirect_user(payment_url)
Never open payment_url in an iframe — LigdiCash blocks it. Redirect in the same tab, a new tab, or a popup. On native mobile, use a WebView.
Always leave customer empty in hosted payin (this is the default). 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.
import ligdicash
# 1. Describe the invoice (same as hosted payin)
invoice = ligdicash.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.add_item(name="Kente shirt", description="Size M", quantity=2, unit_price=15000)
# 2. Start the payment (with OTP provided by the customer)
response = invoice.pay_without_redirection(
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
import ligdicash
withdrawal = ligdicash.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 the POST /pay/v01/withdrawal/create endpoint (via the LigdiCash wallet). type="merchant" uses POST /pay/v01/straight/payout (direct mobile money, slower). See Payout — Introduction.
Status verification
Call get_transaction with the token stored at creation (not the callback token, which is different).
import ligdicash
token = "eyJ0eXAiOiJ..." # Token returned at creation
# Payin
transaction = ligdicash.get_transaction(token, "payin")
# Client payout (withdrawal/create)
# transaction = ligdicash.get_transaction(token, "client_payout")
# Merchant payout (straight/payout)
# transaction = ligdicash.get_transaction(token, "merchant_payout")
if transaction.status == "completed":
# Deliver the order / validate the payment
pass
elif transaction.status == "pending":
# Payment in progress — retry in a few seconds
pass
else:
# Payment failed or cancelled
pass
Fields available on transaction:
| Attribute | Type | Description |
|---|
status | str | "completed", "pending", "cancelled" |
response_code | str | "00" success, "01" failure |
amount | int | Transaction amount |
operator_id | str | Operator identifier |
operator_name | str | Operator name |
customer | str | Customer phone number |
token | str | Transaction token |
custom_data | dict | Custom data sent at creation |
wiki | list | Links to the endpoint’s error codes |
Never deliver an order solely based on an incoming callback. Always call get_transaction with the token stored at creation to confirm the status on the LigdiCash server side. See Callback security.
Error handling
Every error inherits from ligdicash.LigdicashError and exposes .code and .message.
import ligdicash
try:
response = invoice.pay_with_redirection(
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"},
)
except ligdicash.AuthenticationError as e:
# Invalid API key or authentication token
print(e.message)
except ligdicash.MerchantPayinDisabledError as e:
# Payin not enabled for this project
print(e.message)
except ligdicash.InvalidAmountError as e:
# Amount outside the [20; 1,000,000] CFA francs range
print(e.message)
except ligdicash.LigdicashError as e:
# Any other LigdiCash error
print(f"{e.code}: {e.message}")
Available error classes:
| Class | Raised when |
|---|
AuthenticationError | api_key or auth_token invalid |
ApplicationAuthenticationError | Application not authenticated |
MerchantPayinDisabledError | Payin not enabled on the project |
MerchantPayoutDisabledError | Payout not enabled on the project |
MerchantBalanceLowError | Merchant balance too low |
CustomerDoesNotExistError | Customer not registered on the platform |
InvalidAmountError | Amount outside the [20; 1,000,000] range |
InvalidTokenError | Invalid or missing token |
InvoiceNotFoundError | Invoice not found |
TransactionAlreadyExistError | Transaction already created |
RecipientOperatorNotIdentifiedError | Recipient’s operator not identified |
FeatureNotTestableError | Feature unavailable in "test" mode |
Useful links