Developers
Guides
Three common shapes of integration. Each uses only the endpoints and events in these docs; pick the one closest to your system and adapt it.
A school system (like OCAkademia)
The school's system keeps its fee ledger. Wellth gives each learner a permanent payment number, collects from parents at home and abroad, and tells the system at once. Neither side reads the other's database.
Set up once
- The director makes the key and saves the webhook address on Connect. Store the key and signing secret in your secret store.
- Call
GET /api/org/v1/pingfrom your settings screen as “Test connection”, and show the error words if it fails.
Keep each learner's balance on Wellth
- Send every learner with PUT /learners/:externalRef, using your own learner id as externalRef (never the admission number) and initials plus class as the label.
- Send it again after every change to the learner's fees, with the wellthRefs you have booked in includesWellthRefs.
- Print
payNumberDisplayand a QR ofpayUrlon each fee statement. Parents can also type the number at the school's poster or in the Wellth app.
// After every change to a learner's fee ledger (a bill, a payment, a discount, a reversal):
async function syncLearnerToWellth(learner) {
const res = await fetch(`${process.env.WELLTH_URL}/api/org/v1/learners/${encodeURIComponent(learner.id)}`, {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.WELLTH_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
learnerLabel: learner.label, // "N. K., S.2": initials and class only
currency: "UGX",
balanceMinor: String(learner.balance), // whole shillings, as a string; "0" when nothing is owed
termLabel: learner.termLabel, // "Term 3, 2026"
includesWellthRefs: learner.wellthRefsBooked.slice(0, 50), // newest first
}),
});
if (!res.ok) throw new Error((await res.json()).error);
const w = await res.json();
await saveWellthNumber(learner.id, w.payNumber, w.payUrl); // print these on the fee statement
}Book payments from the webhook
async function handleWellthEvent(event) {
if (await alreadyHandled(event.id)) return; // the same event twice: act once
if (event.type === "learner.payment_succeeded") {
const d = event.data;
await bookFeePayment({
learnerId: d.externalRef, amount: BigInt(d.amountMinor), receipt: d.wellthRef,
method: d.method, paidAt: new Date(d.paidAt), payer: d.payer,
}); // unique on wellthRef
await syncLearnerToWellth(await loadLearner(d.externalRef)); // lists d.wellthRef now
}
await markHandled(event.id);
}- A learner leaves:
DELETE /learners/:externalRef. Comes back: PUT again, same number. - A one-off charge outside the fee ledger (a trip): a collection with its own link and pay code.
An education agency taking family payments (like Jovannotti)
An agency bills families for its services (an application, exam preparation, a placement), and often an uncle in London or a sister in Dubai pays. Let Wellth keep each family's balance with bills.
- Tall Grass adds the agency as an organisation; its type sets the bill descriptions it may use (for most agencies
Services,Goods,Account). The data-processing agreement is recorded before any key works. - One payer per family account: PUT /payers/:externalRef with your family id and the parent's initials as
payerLabel. Never the student's name, school or exam. - One bill per invoice: POST /bills with your invoice id as
externalRefand adueAt, so the earliest due is paid first. - Send the family the payment number or
payUrlby email or WhatsApp. They pay by mobile money at home or from abroad by card or bank; the fee is theirs, on top, and you receive the full amount. - Several relatives sharing one invoice: your staff split the bill into family shares in the portal, each with its own link. You still get a
bill.payment_succeededfor every part. - Book money from
bill.payment_succeeded, keyed onwellthRefplusbillId, and mark the invoice paid whenstatusisPAID.
A clinic or business system
A clinic, hospital, petrol station, shop, SACCO or church runs its own system for visits, invoices or accounts. Wellth takes the money at every site and tells the system which bill it paid.
- Make a payer for each patient, customer or member who will pay over time: initials as the label, your own id as externalRef, and the
siteCodeof their branch. - Make a bill per visit, admission or invoice, with a description from your type's list. A clinic's are generic on purpose (
Clinic services,Medicines,Deposit): Wellth never holds a diagnosis, a ward or a department. - The payer, or family anywhere, pays by number; Wellth pays the oldest bill first. Your system books each
bill.payment_succeeded. - Walk-in customers who pay at the counter use the site's counter number on its poster. It is made in the portal, not through the API. Its payments still reach you as
learner.payment_succeeded, with anexternalRefstartingcounter:. - A fuel or trade account: one payer per account, a bill per delivery or per month (
Fuel account). - Payments taken in cash at the desk are recorded in the Wellth portal's cash desk, not through the API.