Skip to main content
Invoices are the core billing document in Hyparrow. You create an invoice with line items, dates, tax and discount, then collect payment either by sharing a hosted checkout URL with your customer or by recording payment yourself. All endpoints on this page are merchant endpoints under the base URL https://api.hyparrow.cloud/api/v1 and require your API key credentials on every request:
Amounts are in kobo (the minor unit). ₦1,000.00 is 100000. Line-item unitPrice and the persisted totals all follow this convention.

Lifecycle

An invoice moves through a small set of statuses: A new invoice starts as draft. Calling POST /invoices/{invoiceId}/send-email auto-publishes a draft to pending so the customer can reach it. Once a payment settles (via the hosted checkout or POST /invoices/{invoiceId}/pay), the invoice becomes paid and can no longer be edited.

End-to-end flow

1

Create the invoice

POST /invoices/ with a title, currency, customer details and at least one line item. Hyparrow assigns an invoiceNumber and computes the totals.
2

Share the checkout URL

The checkout URL is CHECKOUT_BASE_URL/pay/{invoiceId}. Send it to your customer directly, or call send-email to email the invoice PDF with the link embedded. (Optionally generate a virtual account up front with generate-va.)
3

Customer pays

On the hosted checkout page the customer picks a payment method (bank transfer / virtual account, USSD, card, OPay or crypto). See the Checkout guide for the public API the page uses.
4

Status becomes paid

Poll the invoice (or the public checkout status endpoint) until status is paid. A receipt is generated automatically.
5

Callback fires

If you set checkoutCallbackUrl on the invoice, Hyparrow POSTs a checkout.payment.completed event to it when the payment settles. See the callback.

Create an invoice

POST /invoices/ Creates an invoice with line items, optional invoice-level tax, discount, shipping and customer details.

Body

Each line item:
If a line item links a productId whose currency differs from the invoice currency, you must send an explicit (converted) unitPrice. Hyparrow refuses to silently reuse a price under a different currency label.

Response 201

The checkout URL for this invoice is CHECKOUT_BASE_URL/pay/8f1c2e34-.... Note that a freshly created invoice is draft — share it via send-email (which publishes it) or publish it explicitly before sending the link.

List invoices

GET /invoices/ Paginated list of your account’s invoices.

Search invoices

GET /invoices/search

Get an invoice

GET /invoices/{invoiceId} Returns a single invoice (with totals and line items) for your account. Returns 404 if not found.

Update an invoice

PUT /invoices/{invoiceId} Updates editable fields — customer details, currency, dates, tax/discount, status, notes, metadata. Send only the fields you want to change.
Paid invoices cannot be edited. Updating an invoice whose status is paid returns 400 with "paid invoices cannot be edited".

Delete an invoice

DELETE /invoices/{invoiceId}

Record a payment

POST /invoices/{invoiceId}/pay Marks an invoice paid using a payment you collected yourself (e.g. cash, or a transfer in your own wallet system). For customer-driven payments, use the hosted checkout instead.

Line items

Manage line items on an existing invoice. Totals are recalculated on every change. Add a line item:
The body matches the create-invoice line item shape: provide either a productId (auto-fills description/unitPrice) or a freeform description + unitPrice (> 0).

Generate a virtual account

POST /invoices/{invoiceId}/generate-va Creates a temporary virtual account (a dedicated bank account number) the customer can transfer the exact invoice amount to. A transfer that matches the amount settles the invoice automatically.
Virtual accounts are an NGN-only rail. They are not available for non-NGN invoices.

Get the active virtual account

GET /invoices/{invoiceId}/va Returns the current active, non-expired virtual account for the invoice, or 404 if none exists.

Receipt & PDFs

Once an invoice is paid, a receipt becomes available. The PDF endpoints stream a file with a Content-Disposition: attachment header — request them with your API key headers and save the binary body.

Email an invoice

POST /invoices/{invoiceId}/send-email Generates the invoice PDF and emails it to the customer, with the hosted checkout link embedded. This is the usual way to “send” an invoice.
  • A draft invoice is auto-published to pending so the checkout link works.
  • For a paid invoice this sends the receipt instead.
  • A duplicate send is rejected ("Invoice has already been mailed" / "Receipt has already been mailed").
  • Fails with 400 if the invoice has no customerEmail.

Next steps

  • Checkout guide — the public API the hosted payment page uses, and the callback webhook.
  • Sandbox — test the full flow with simulated money.