An independent, community-built SDK for the Lipila payments platform. Not affiliated with, or endorsed by, Lipila.
Lipila SDK

Getting started

From zero to your first verified Lipila payment, step by step.

This walks a server-side app from account setup to its first payment and webhook. Node.js 22 or newer is required.

Create your sandbox and production accounts

Lipila runs two separate dashboards. Onboard in both. Credentials do not cross environments, so a sandbox key never works against production.

Get your API key and webhook secret

In each dashboard, generate the environment's API key and copy its webhook signing secret. Keep both server-side.

terminal
LIPILA_API_KEY=Lsk_sandbox_xxx
LIPILA_WEBHOOK_SECRET=whsec_xxx
The API key gives direct account access. Never expose it in browser code.

Install the SDK

terminal
npm i @cozycodr/lipila

Configure one client

The client defaults to the sandbox. Production must be selected explicitly.

@cozycodr/lipila v0.1.0
import { lipila } from "@cozycodr/lipila";

export const client = lipila({
  apiKey: process.env.LIPILA_API_KEY!,
  environment: "sandbox",
  webhookSecret: process.env.LIPILA_WEBHOOK_SECRET,
});

Create your first mobile money payment

Give each attempt a unique referenceId you own. It stays safe to reconcile against later.

@cozycodr/lipila v0.1.0
const { payment } = await client.payments.mobileMoney.create({
  referenceId: order.id,
  amount: 125.5,
  accountNumber: "260971234567",
  narration: "Order #1024",
});

// payment.status: "Pending" | "Successful" | "Failed"

Pending means Lipila accepted the attempt and is still processing it.

Receive the final outcome by webhook

Completion is asynchronous. Verify the signature against the raw body, then act on the event.

@cozycodr/lipila v0.1.0
app.post("/webhooks/lipila", express.raw({ type: "application/json" }), (req, res) => {
  const event = client.webhooks.verify({ rawBody: req.body, headers: req.headers });
  if (event.shape === "transaction") fulfil(event.id, event.transaction);
  res.sendStatus(204);
});

For automatic fulfilment with dedupe and retries, see Verify and handle webhooks.

Reconcile anything uncertain

If a create is interrupted, never retry it blindly. Reconcile the original reference. Reads are safe to retry.

@cozycodr/lipila v0.1.0
const payment = await client.payments.retrieve(order.id, {
  retry: { maxAttempts: 3 },
});

Next: browse Common tasks for card payments, reconciliation, and lifecycle handlers.

On this page