1. He posts the job (and the money moves)
1
He opens the dashboard
guild.com.ng/overview. He signed up last week, linked his Access Bank account through a direct-debit mandate, sent the ₦50 confirmation transfer OPay asked for, got the Mandate ready notification three minutes later. His bank is now a payment rail he can tap, once, with one finger.2
He fills the form
Five bricklayers. Bodija. Three days starting Thursday. ₦4,000 a day. Yoruba preferred. Total budget ₦60,000. Submit.
3
The escrow funds, immediately
The moment he hits submit, ₦60,000 is debited from his Access Bank account via OPay direct debit. It lands in an escrow balance tied to this exact job. A ₦500 posting fee is added on top. The money is committed before any worker even sees the job.This is the part most platforms skip 👀. We don’t wait until the job is done to find out the employer can’t pay. The money is on our side before the first WhatsApp ping fires.
4
The job goes live
Posted at 9:02 AM. Available across voice, WhatsApp, SMS, and the marketplace at
guild.com.ng/jobs.2. Our matching model ranks the candidates
The moment Adekunle’s job posts, our matching model runs over every Job Seeker who could plausibly do it. Four factors weigh in:Skill
Bricklayer matches bricklayer. The skill tags on a Job Seeker’s profile are exact; the trade category is a fallback. A tiler can apply, but they rank lower.
Location
Bodija is the centre of the search. We expand outward by area, by city, by state, with distance decay. Modakeke is forty minutes by danfo. Still in range.
Language
Adekunle asked for Yoruba. Musa speaks Yoruba and Pidgin. He’s a fit. A Hausa-only speaker drops down the list.
Economic context
Standing tier. On-time rate. Repayment streak. Employer feedback. Recent activity. A Job Seeker who shows up and finishes ranks above one who doesn’t.
3. Musa hears about it on WhatsApp
His phone vibrates at 9:04 AM. WhatsApp message:Adekunle dey hire 5 bricklayers for Bodija. ₦4,000/day, 3 days. Reply YES to apply.He replies YES. The intent engine recognises the affirmative, looks at the conversation state, posts the application. Done in under a second.
A Job Seeker who isn’t on WhatsApp would hear about the same job by SMS. Tola can also place an outbound voice call to a high-fit candidate (“You get one bricklayer job for Bodija, ₦4,000 daily, you want apply?”) — or the Job Seeker can dial Tola themselves and ask: “Wetin work dey for Bodija?” Same matching model. Different rails.Whether it arrives as a typed YES, a Pidgin voice note, or a spoken reply on a call, Google Gemini does the understanding underneath — one brain behind every rail.
4. Adekunle approves
His dashboard shows a notification: Musa Bello (bricklayer, Modakeke) applied. He taps the row, sees Musa’s profile — standing tier Emerging, twelve completed jobs in the last sixty days, average review 4.7. He taps Approve. Approval writes to the audit ledger. The matching model gets a positive signal. The next time Adekunle posts, candidates similar to Musa rank a notch higher.5. The work happens, releases fire automatically
Thursday morning, Musa shows up at the Bodija site at 7:30 AM. The foreman opens his dashboard and marks him present. Two more bricklayers show, two more, one more. All five present. Work starts. That evening, our scheduler reads the day’s attendance against the escrowed budget. For every Job Seeker marked present, one day’s wage releases from escrow to their wallet. Five releases of ₦4,000 each. Five SMS notifications. Five wallets crediting inside a few seconds of each other. Friday: same thing. Saturday: same thing. Each attendance entry is its own audit row. Each release is its own audit row. The foreman cannot retroactively edit attendance once it’s marked — the triggers reject everyUPDATE and DELETE on the audit tables. The history is structurally immutable.
By Saturday evening, Musa has ₦12,000 in his Guild wallet without Adekunle ever tapping a Pay button. The money was committed when the job posted; the releases flowed as the work happened.
6. The reconcile path (security in the background)
You might wonder: how do we know the OPay debit from step 1 actually settled? How do we know the per-shift releases are safe to fire? Hold on — this is the part most platforms skip 👀.1
The initial escrow debit triggers a OPay webhook
OPay fires
charge_successful to our webhook receiver. Our middleware verifies the HMAC-SHA512 signature against the raw body. crypto.timingSafeEqual for the comparison. We accept three signature schemes OPay uses; the right one is detected per request.2
The reconcile guard runs against OPay's authoritative endpoint
Before we mark the escrow as funded, we re-verify the transaction directly against OPay. Status must match success. Amount must match the webhook body to the kobo. Anything off, the escrow stays unfunded — and no shift releases can fire because there’s nothing in escrow to release from.
3
Per-shift release writes to the ledger atomically
The release is an internal ledger move (escrow row debited, Job Seeker wallet credited) with a ULID idempotency key. Postgres-durable + Redis fast-path replay protection. A replayed release is a no-op.
4
Notification fires through OPay SMS
“₦4,000 added by Adekunle Ogundimu. Balance: ₦4,000.” Sub-second delivery.
7. Musa withdraws to his bank
Saturday night, Musa taps the SMS link. WhatsApp opens. He sends withdraw. The intent engine routes him to the withdrawal flow. ₦10,000, Access Bank, the account he linked last month. Confirms. OPay’s payout API fires. Beneficiary name pre-validated by OPay’s name-enquiry service before the transfer goes out. OPay responds with approval and a NIP reference in the same call — we mark the payoutSUCCESS synchronously, no need to wait for a follow-up webhook. Seven seconds end to end.
His phone buzzes: “₦10,000 sent to Access Bank ••••3911.”
8. The standing score updates
That evening Musa opensguild.com.ng/overview. His standing tier sits at Emerging, but the chart shows the tick upward — completed jobs +1, on-time rate held at 100%, employer review pending.
Sunday morning Adekunle leaves a 5-star review. The standing model recomputes. Musa moves from Emerging to Trusted.
This is the moment the work compounds. Three months of jobs like this, and Musa has a transaction history a lender can verify. Not a vouching letter. Not a foreman’s word. OPay-backed receipts in an immutable ledger.
9. A lender reads the signal
Months later — let’s say Musa needs ₦25,000 for a new wheelbarrow. He applies through a partner lender who’s integrated with our Partner API. The lender asks Musa to grant consent in his Guild dashboard. He taps yes. Consent record written. The lender hitsGET /partner/v1/users/usr_01HMFB.../snapshot. We return a signed JSON document:
The three roles, one ledger
Job Seekers
Sign up by voice, WhatsApp, or web. Find work in their language. Get paid same-day. Build a standing score that compounds.
Traders
Open a OPay virtual account. Take customer transfers. Sales velocity unlocks inventory advance offers.
Employers
Link a bank by direct debit. Post jobs. See attendance proof, day by day. Pay per-shift without middlemen.
Read the architecture
Eight services, sixteen shared packages, one Postgres cluster, one Redis. Built for a national footprint, in service of one informal job seeker at a time.