Wocart
Wocart runs the whole cash-on-delivery business for Algerian stores: an Arabic-first checkout, phone verification, Yalidine, ZR Express, NOEST, Guepex and 82 EcoTrack couriers, your own drivers, and M
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Event ticketing & payments SaaS for Kenya: M-Pesa STK/B2C/B2B, QR gate check-in (offline), payouts, WhatsApp. Next.js + TypeScript + Prisma.
翻訳待ち
Loading the full README.
Read the full README ↗Event ticketing and payments platform for Kenya. Organisers sell tickets through M-Pesa and card, check people in at the gate (even offline), and withdraw their earnings to M-Pesa or a bank, with every shilling reconciled.
Live: tixflow-pxml.onrender.com
src/lib/pricing.ts, src/lib/checkoutQuote.ts), so the total shown is the total charged, whatever the client sends.Next.js (pages + API routes, TypeScript)
├─ src/lib/ domain logic: checkout, pricing, payouts, refunds, gate, promoters ...
├─ src/pages/api/ REST endpoints: checkout, mpesa, intasend, tickets, staff, platform-admin
├─ src/pages/api/cron reconcile + scheduled jobs (reminders, expiries, surveys)
└─ prisma/ 30 models on MongoDB
Integrations: Safaricom Daraja (STK, B2C, B2B), IntaSend, WhatsApp, Africa's Talking SMS, Resend, Cloudinary
Hosting: one long-running Node service on Render, health-checked, cron every 5 minutes
npm install
# create .env with the variables listed in render.yaml (DATABASE_URL at minimum)
npx prisma db push
npm run dev # http://localhost:3000
The sections below are the operator's guide: payments setup, secrets, jobs and deployment.
All buyer payments go through M-Pesa STK Push (Daraja) into your one platform shortcode — configured via MPESA_* env vars. Tenants request payouts to their own M-Pesa or bank (via the bank's M-Pesa paybill); a platform admin reviews and approves each request from /platform-admin, which triggers the actual Daraja B2C (M-Pesa) or B2B (bank) transfer.
Before payouts work end-to-end you'll need to:
MPESA_B2C_INITIATOR_NAME and MPESA_B2C_INITIATOR_PASSWORD (used for both B2C and B2B) in .env.certs/sandbox_cert.cer (or certs/production_cert.cer) — see src/lib/mpesaB2C.ts for the download links.PLATFORM_FEE_PERCENT to whatever cut the platform takes per withdrawal (default 3, i.e. 3%) — this one value controls every future payout's fee.NEXT_PUBLIC_APP_URL to a publicly reachable URL (e.g. via ngrok in development) so Safaricom's STK, B2C, and B2B callbacks can reach /api/mpesa/*.MPESA_B2C_RESULT_URL / MPESA_B2B_RESULT_URL (and the _TIMEOUT_URL pair) are now optional — they default to ${NEXT_PUBLIC_APP_URL}/api/mpesa/b2c-result / b2b-result.In production the app refuses to run a route that needs a missing secret (there are no hardcoded fallbacks any more). Generate each with openssl rand -base64 32:
| Variable | Used for |
|---|---|
JWT_SECRET | Tenant login sessions (also the fallback for the two below) |
PLATFORM_ADMIN_JWT_SECRET | Platform-admin sessions — separate on purpose, no fallback |
TICKET_LOOKUP_JWT_SECRET | "Find my tickets" magic links (optional, falls back to JWT_SECRET) |
LINK_SIGNING_SECRET | Personal feedback-survey and certificate links (optional, falls back to JWT_SECRET) |
OTP_SECRET | Hashing emailed confirmation codes (optional, falls back to JWT_SECRET) |
MPESA_CALLBACK_SECRET | Appended to every Daraja callback URL; callbacks without it are rejected |
CRON_SECRET | Authorises /api/cron/reconcile and /api/cron/scheduled |
ASSISTANT_API_KEY | Authorises the website assistant's tools at /api/assistant/* (see docs/assistant/README.md) |
PLATFORM_ADMIN_USERNAME / PLATFORM_ADMIN_PASSWORD | Platform-admin login |
Daraja callbacks aren't guaranteed to arrive. /api/cron/reconcile asks Safaricom directly about any order still pending after ~45s (issuing tickets or failing it), expires orders that never resolve, and logs payouts stuck in processing for 30+ minutes. Run it every few minutes:
This is the beginning of the README. Read the rest at the original. Read the full README ↗