Pewang PaymentsHTTPS API · Paystack KES · M-Pesa payouts
Integrators

Payments API — for your backend

Call this host over HTTPS from your server (e.g. loan core, wallet service). Collect repayments with Paystack Checkout, disburse to M-Pesa, verify charges, and read transfer status. Paystack secrets never go in your mobile app — they stay on this API host. Official Paystack field reference: paystack.com/docs.

Start here
  • Integration guide (/payments/developers) — flows, HTTP codes, webhooks.
  • GET /api/payments — JSON index of routes and request shapes (same on any host that serves this API).
  • /payments/test — browser playground (Checkout + sample disburse).
  • Markdown in the repo: docs/LOAN-APP-PAYMENTS-INTEGRATION.md, docs/PAYMENTS-API.md (curl).

What you implement

Repayment: POST /api/payments/initialize → redirect the borrower to authorization_url → on return, GET /api/payments/verify?reference=… (and/or handle charge.success via webhook — extend the webhook handler with your ledger logic).

M-Pesa payout: POST /api/payments/disburse. Amounts under KES 2000 complete in one step (mode: "automatic"). Amounts ≥ KES 2000 return an approval_token; your product calls POST /api/payments/disburse/approve with the OTP policy the API owner documents for you.

Transfer status / SMS text: GET /api/payments/transfer?reference=… or ?transfer_code=TRF_…

Authentication you will see

  • No Bearer (default): you only send JSON bodies / query params. The host calls Paystack using its own server keys.
  • Bearer (when the API owner enables it): send Authorization: Bearer <key-they-issue-you> on /api/payments/* routes (not on Paystack's webhook callback — that uses x-paystack-signature).

Webhook URL (for Paystack Dashboard)

Whoever owns the Paystack account registers one URL per mode (test / live). It must hit this codebase on the host you integrate against:

https://payment.pewang.company/api/paystack/webhook

Path is always /api/paystack/webhook on the same origin as your API calls (e.g. if your base URL is https://pewang.company, the webhook is https://pewang.company/api/paystack/webhook).

Endpoints (summary)

GET /api/payments — full machine-readable list.

POST /api/payments/initialize — start Checkout; returns authorization_url, reference.

GET /api/payments/verify?reference=… — confirm a charge.

GET /api/payments/transfer?… — transfer status + confirmation_message.

POST /api/payments/disburse — M-Pesa payout; see settlement / message for pending vs success. 400 if the host's Paystack balance cannot cover the amount.

POST /api/payments/disburse/approve — large-amount approval step.

Sandbox / demos

When testing against a host the operator configured for demos, you may use Safaricom 0711164069 / 254711164069 in recipient_phone (local 07… is normalized to 2547…).

Deployment operators only — server configuration

Integrators do not set these; the team that deploys this project does (e.g. Vercel). Listed so operators can match GET /api/payments and support tickets.

  • PAYSTACK_SECRET_KEY — Paystack secret on the server.
  • PAYSTACK_PUBLIC_KEY — optional client Checkout.
  • PAYSTACK_WEBHOOK_SECRET — optional; webhook HMAC (defaults to secret key).
  • PAYMENT_APPROVAL_OTP — server PIN for /disburse/approve when amount ≥ KES 2000.
  • PAYMENTS_REQUIRE_BEARER / PAYMENTS_API_KEYS — optional integrator gate.
  • PAYSTACK_KES_MOBILE_BANK_CODE — optional (default MPESA).
  • PAYMENTS_TRANSFER_NOTIFY_URL / PAYMENTS_TRANSFER_NOTIFY_SECRET — optional fan-out after transfer webhooks.

CLI / hosting: docs/VERCEL-CLI.md