Skip to main content

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 Dart SDK is built for Flutter. It uses Dart conventions — named parameters, enums, Future<> — and fits naturally into your widgets and services.

Installation

Add the dependency to your pubspec.yaml:
pubspec.yaml
dependencies:
  ligdicash: ^1.0.2
Then install:
flutter pub get
Requirements: Dart SDK ≥ 3.4.1 / Flutter ≥ 3.x.

Initialization

Dart
import 'package:ligdicash/ligdicash.dart';

final client = Ligdicash(
  apikey: '{API_KEY}',
  authToken: '{AUTH_TOKEN}',
  platform: PlatformType.live,
);
Get your apikey and authToken from the LigdiCash dashboard by creating an API project. Store them in environment variables, never hardcoded in your Flutter code.

Hosted payin

The customer is redirected to the LigdiCash-hosted payment page inside a WebView. This is the recommended mobile flow.
Dart
// 1. Create the invoice
final invoice = client.Invoice(
  currency: 'xof',
  description: 'Order #ORD-20240512',
  customerFirstname: 'Amadou',
  customerLastname: 'Ouedraogo',
  customerEmail: 'amadou@example.com',
  storeName: 'MySuperStore',
  storeWebsiteUrl: 'https://mysuperstore.com',
);

// 2. Add items
invoice.addItem(
  name: 'Kente shirt',
  description: 'Size M',
  quantity: 2,
  unitPrice: 15000,
);
invoice.addItem(
  name: 'Shipping fee',
  description: '',
  quantity: 1,
  unitPrice: 1500,
);

// 3. Start the payment
final response = await invoice.payWithRedirection(
  returnUrl: 'https://mysuperstore.com/order/success',
  cancelUrl: 'https://mysuperstore.com/order/cancel',
  callbackUrl: 'https://backend.mysuperstore.com/ligdicash/callback',
  customData: {'transaction_id': 'ORD-20240512'},
);

// 4. Open the WebView with the payment URL
final paymentUrl = response.responseText;
On Flutter, open paymentUrl in a native WebView (webview_flutter package). Never display it in an HTML iframe-based WebView — LigdiCash blocks it.
Detect the return URL (returnUrl / cancelUrl) in the WebView’s onNavigationRequest callback to close it automatically and resume the app flow.
Always leave customer 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 Flutter interface. You must collect their phone number and, depending on the operator, their OTP code.
Dart
// 1. Create the invoice
final invoice = client.Invoice(
  currency: 'xof',
  description: 'Order #ORD-20240512',
  customerFirstname: 'Amadou',
  customerLastname: 'Ouedraogo',
  customerEmail: 'amadou@example.com',
  storeName: 'MySuperStore',
  storeWebsiteUrl: 'https://mysuperstore.com',
);
invoice.addItem(
  name: 'Kente shirt',
  description: 'Size M',
  quantity: 2,
  unitPrice: 15000,
);

// 2. Start the payment (with OTP provided by the customer)
final response = await invoice.payWithoutRedirection(
  otp: '123456',            // OTP code entered by the customer
  customer: '22670123456',  // Customer phone number, no + or spaces
  callbackUrl: 'https://backend.mysuperstore.com/ligdicash/callback',
  customData: {'transaction_id': 'ORD-20240512'},
);

// 3. Store the token for later verification
final 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, payout, salary.

To the customer’s LigdiCash wallet

Dart
final withdrawal = client.Withdrawal(
  amount: 5000,
  description: 'Refund for order ORD-20240510',
  customer: '22670123456',
);

final response = await withdrawal.send(
  type: WithdrawalType.client,
  toWallet: false,  // false = automatic transfer to the linked mobile money account
  callbackUrl: 'https://backend.mysuperstore.com/ligdicash/callback-payout',
  customData: {'transaction_id': 'REFUND-20240512'},
);

final token = response.token;

Directly to mobile money

Dart
final response = await withdrawal.send(
  type: WithdrawalType.merchant,  // Direct payout, no intermediate wallet
  callbackUrl: 'https://backend.mysuperstore.com/ligdicash/callback-payout',
  customData: {'transaction_id': 'PAY-20240512'},
);
WithdrawalType.client uses POST /pay/v01/withdrawal/create (via the LigdiCash wallet). WithdrawalType.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).
Dart
final token = 'eyJ0eXAiOiJ...';  // Token returned at creation

// Payin
final transaction = await client.getTransaction(
  token: token,
  type: TransactionType.payin,
);

// Client payout (withdrawal/create)
// final transaction = await client.getTransaction(
//   token: token,
//   type: TransactionType.clientPayout,
// );

if (transaction.status == 'completed') {
  // Deliver the order / validate the payment
} else if (transaction.status == 'pending') {
  // Payment in progress — retry in a few seconds
} else {
  // Payment failed or cancelled
}
TransactionType values:
ValueEndpoint checked
TransactionType.payinGET /redirect/checkout-invoice/confirm
TransactionType.clientPayoutGET /withdrawal/confirm
Fields available on transaction:
PropertyTypeDescription
statusString"completed", "pending", "cancelled"
responseCodeString"00" success, "01" failure
amountdoubleTransaction amount
operatorIdStringOperator identifier
operatorNameStringOperator name
customerStringCustomer phone number
tokenStringTransaction token
customDataMap<String, dynamic>Custom data sent at creation
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

Dart
try {
  final response = await invoice.payWithRedirection(
    returnUrl: 'https://mysuperstore.com/success',
    cancelUrl: 'https://mysuperstore.com/cancel',
    callbackUrl: 'https://backend.mysuperstore.com/callback',
    customData: {'transaction_id': 'ORD-20240512'},
  );

  if (response.responseCode != '00') {
    // Error returned by the API — read response.wiki
    debugPrint('API error: ${response.responseText}');
  }
} catch (e) {
  // Network error or unexpected exception
  debugPrint('Error: $e');
}
Check response.responseCode after every call: "00" indicates success, "01" an error. On error, read response.wiki to get the URL with sub-code details.