Online checkout
Take payment on your website or in your app — through a page we host and keep accessible, or against the API if you would rather build it yourself.
A supermarket in Kampala, a school collecting fees, a payroll of four thousand, or a software company in Nairobi, Lagos or London selling to Ugandans. If your customers are here, JCREDO connects you to MTN Mobile Money, Airtel Money and partner banks through one contract.
The same rails and the same ledger underneath. What changes is the shape of the problem you brought.
Take payment on your website or in your app — through a page we host and keep accessible, or against the API if you would rather build it yourself.
A code at the counter, the payment on the customer’s own phone, and the sale on your dashboard before they have put it back in their pocket. One code for the counter, paused or revoked from the console the moment you need to.
Send a link over WhatsApp or SMS and get paid. Fixed amount or open, single use or reusable, and no website required to start.
Thousands of recipients from one file, validated before a shilling moves. Prepared by one person, approved by another, with the funding reserved first.
Fees collected per student and per term, each payment carrying the reference you gave it — so the bursar’s list and the ledger agree.
Issue an invoice with a due date, send the link, and match the payment to the invoice that caused it.
Every transaction carries the branch it belongs to, so head office sees each branch’s takings and the whole, without anyone re-keying a figure.
Give your own product a payments layer through the API and signed webhooks, and pay any other business on JCREDO instantly, settled on our ledger.
Our own online school system runs its fee collection on JCREDO — term invoices per student, mobile money from the parent’s own phone, and a reconciliation that names the pupil rather than the transaction. It is the proof that the school-fees path is a product and not a slide.
A payment has five independent lifecycles. Collapse them into one status and the screen will eventually tell someone the money arrived when it did not. JCREDO renders all five separately — and each one shaped and labelled differently, so colour is never the only thing carrying meaning.
Did the payer actually get debited on the rail.
Whether the double-entry journal for it exists yet.
Whether your systems have been told, and succeeded.
Whether the money has reached your own bank account.
Whether our record and the operator's record agree.
A payment that has SUCCEEDED on the rail and is UNMATCHED in reconciliation is a real and common situation. One number cannot say both. So we never make it try.
Collections, payouts, settlement, reconciliation and a developer platform — one account, one ledger, one place to look when someone asks what happened to a payment.
Push a prompt to a payer's handset, or send them somewhere to pay. Every collection lands in the account you choose and posts to the ledger the moment it is real.

Salaries, supplier payments, grant disbursements, refunds. Prepared by one person and approved by another, with funding reserved before anything leaves.

Available now, pending settlement, and reserved against payouts you have already approved — three different numbers, shown as three different numbers.

Mobile money networks go quiet. When that happens, most platforms guess — and the usual guess is “failed”, which is how a customer gets asked to pay a second time for something they already paid for. Getting that money back takes days.
JCREDO treats UNKNOWN as a real state with its own colour, its own glyph and its own words. It is never styled as an error. And on an unknown payment, the retry button is not greyed out — it is absent, because a disabled button is still an invitation.
An unknown outcome means we do not yet know whether the payer was debited. Do not ask the payer to pay again.
MTN Mobile Money, Airtel Money and partner bank channels behind one contract and one API, with each operator’s own callbacks driving state. Direct operator agreements are being established, and nothing in your integration depends on which path a payment takes.
Collections and payouts to MTN Mobile Money accounts, with the operator's own callbacks driving state rather than a polling guess.
The same canonical contract as MTN. Your integration does not change when the rail does — that is the whole point of it.
Bank transfers for settlement and for payouts that belong on a bank account rather than a wallet.
Rail health is shown in the console as its own fact — operational, degraded, down, or unknown. A rail we cannot currently measure is never drawn as a healthy one.
Collect from customers, pay suppliers and staff, and settle to your Ugandan bank on the cycle you agree with us.
Your customers pay the way they already pay — their own wallet, their own phone — while you integrate once and read one API.
Give your own product a payments layer: one API, signed webhooks, and instant payments to any other business on JCREDO.
A REST API that speaks in canonical terms, never in an operator's vocabulary. Integer minor units with an ISO 4217 code — never a float. Idempotency on every mutating call, because a retried request must not become a second payment.
Every attempt, every response code, every retry — listed in the console, replayable, with secrets you rotate yourself.
Including the states nobody simulates: declines, expiries, reversals, and payments that go quiet.
A log of what you actually sent us, kept for the retention window shown in the console, so “it worked yesterday” is a question with an answer.
# Ask a payer on MTN or Airtel to approve a payment. curl -X POST https://jcredo.320tech.io/v1/collections \ -H "Authorization: Bearer $JCREDO_API_KEY" \ -H "Idempotency-Key: 8f2a1c40-3d5e-4b19-9c77-ae20f1d84b03" \ -H "Content-Type: application/json" \ -d '{ "merchantReference": "INV-20451", "money": { "amountMinor": "250000", "currency": "UGX" }, "method": "MOBILE_MONEY", "payer": { "phoneNumber": "+256700000000" } }' # 201 Created { "id": "col_01JK7Q1B4XD2", "merchantReference": "INV-20451", "money": { "amountMinor": "250000", "currency": "UGX" }, "status": "CREATED", "createdAt": "2026-10-31T09:24:11Z" } # CREATED is not SUCCEEDED. Wait for the webhook — # and if it ever says UNKNOWN, do not charge again.
Most of what a payment platform owes you only matters once — on the day a dispute, a mistake or an insider costs real money. These are the parts that are there for that day.
Maker-checker is domain logic, not a token claim. The person who prepared a payment cannot be the person who releases it, and the control cannot be turned off by one person acting alone.
Payouts above the threshold you choose ask the approver for a one-time code — sent to the address on their own record, never one the request names, and bound to that exact amount and destination.
Phone numbers and account numbers are masked everywhere, including in exports. Revealing one needs a permission, captures a purpose, is written to the audit log, and re-masks itself.
Who did what, when, from where — and just as importantly, who tried and was refused. Entries are append-only and carry the reference of the thing they acted on.
Owner, Finance, Operations viewer, Payout approver, Developer — with branch labelling, invitations, and a console that hides what a person may not do rather than offering it and refusing later.
There is no screen in JCREDO that lets anyone set a payment's status by hand or adjust a balance. Corrections are linked reversals that leave both entries standing.
Somebody with a shop to run, a payroll to make, or a term’s fees to reconcile — and the product manager two time zones away whose customers are all of them. These are the situations the console was designed around.
Most of Uganda’s commerce happens at a counter, and settles on a phone.
Collections · MTN and Airtel · one list
Checks on a Sunday whether Friday’s collections settled, from a phone, without having to call anybody.

Releases the payout run, and needs to see the funding reserved before she approves it rather than after.

Takes MTN and Airtel all day and wants one list of what came in, not two statements to add up by hand.

Sends a payment link over WhatsApp and knows within seconds whether it was actually paid.

Reads his branch’s takings in the console, because every transaction carries its branch.

Reconciles ten thousand fee payments a term against the students who actually paid them.
These photographs are stock images, chosen to show the situations JCREDO is built for. They are not customers and these are not testimonials. When real merchants agree to be named and quoted, their words and their faces will replace these together.
JCREDO accounts are opened by application rather than sign-up, because moving other people's money requires us to know who you are. It is a short form and a real person reads it.
What you do, roughly what you move each month, and which rails you need.
Credentials the same day, so your developers can start while compliance runs in parallel.
From the console, with a screen that always says where the application stands.
Same code, same contract, real money, once your live credentials are issued. The banner at the top of every screen changes.
We read every one of these ourselves. Expect a reply from a person, not an autoresponder, within one working day. If it is urgent, call the number in the footer.
Money questions do not wait for office hours and they do not suit a ticket queue. Pick whichever of these you already have open.
The console, the sandbox and the API reference are behind one login.