Skip to main content
Remita’s “Invoice Generation” API is a Remita Retrieval Reference (RRR) based collection flow, not a hosted checkout — createPayment generates an RRR that the payer completes through Remita’s own channels (bank transfer, USSD, card, agent), outside of this integration. There is no payment_url, no customer-object API, and no recurring/subscription API (Remita’s recurring billing is a separate Direct Debit product with its own auth/endpoints, out of scope here).

Setup

Required env vars:
REMITA_BASE_URL is required once REMITA_SANDBOX=false — Remita does not publish a fixed production base URL for this API; it’s issued per-merchant after KYC/go-live, from the Administration Menu → “API Keys and Webhooks” page.

How it works

payerName and payerPhone must be supplied in provider_metadata because PayKit’s customer object only carries an email/id, and Remita’s Invoice Generation API requires both. Remita’s status API (status.reg) returns only { amount, RRR, orderId, message, transactiontime, status, paymentDate? } — it does not echo back the payer’s email, item_id, or metadata. Those fields are only populated on the object returned synchronously from createPayment; a subsequent retrievePayment always returns customer: null, item_id: null, metadata: {}. Only status codes 00 and 01 mean the RRR has been paid (per Remita’s own docs) — everything else is treated as pending unless it matches one of Remita’s documented failure codes. sender/customer details and subscriptions aren’t supported — Remita has no customer-object API, so full payer data must be supplied per payment, and recurring billing is a separate Remita product (Direct Debit mandates) out of scope for this integration.

Canceling a payment

Cancels an unpaid RRR via Remita’s “Cancel Invoice” endpoint — the only post-creation mutation this API supports. There’s no way to amend payer details or partially update a payment reference.

Webhooks

Configure a “listening URL” in Remita’s dashboard (Administration Menu → API Keys and Webhooks). Remita POSTs a JSON array of notifications to it — there is no signature or shared secret on this payload, so webhookSecret is unused. Every notification is re-verified against the status API before a standardized event is emitted, since the payload itself can’t be authenticated:

Raw Remita events

Caveat: Remita’s docs ask your endpoint to reply with the literal text "Ok" (or "Not Ok"). webhook.handle() always sends its own response, so if strict compliance with that contract matters, send the literal text from your own route handler after calling webhook.handle().

Unsupported operations

createCheckout / retrieveCheckout / updateCheckout / deleteCheckout, all customer operations, all subscription operations, updatePayment, deletePayment, capturePayment, and createRefund throw ProviderNotSupportedError — Remita’s Invoice Generation API has no hosted checkout URL, no customer-object API, no subscription API, no amend/delete endpoint beyond cancellation, no manual capture step, and no refund endpoint. Use createPayment / cancelPayment directly instead.