Invoices & Billing API
Create, retrieve, list, finalize, and void invoices, and manage client billing lifecycles.
Invoices & Billing API
Invoices represent itemized bills sent to customers for products or services. Invoices are compiled automatically for recurring subscriptions at the start of each billing period, or they can be created manually via the API or Xtopay Dashboard to bill clients for custom work.
Invoice Lifecycle & States
An invoice progresses through several statuses during its billing lifecycle:
| Status | Description |
|---|---|
DRAFT | The invoice is being compiled. It is not visible to the customer and can still be edited. |
OPEN | The invoice is finalized, has a unique invoice number, and is sent to the customer for payment. |
PAID | The invoice total has been fully paid by the customer. |
VOID | The invoice was canceled or marked as voided. |
UNCOLLECTIBLE | The customer failed to pay after multiple retry attempts, and the invoice is written off. |
Create an Invoice
Create a new draft invoice to bill a customer. You can add one or more line items.
| Detail | Description |
|---|---|
| API Endpoint | https://api.xtopay.co/v1/invoices |
| Request Type | POST |
| Content Type | application/json |
| Authentication | Basic Base64(clientId:clientSecret) |
| Required Scope | payments:write |
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId | String | Yes | Unique Customer ID to bill (e.g. cust_cl8z2lh82...). |
currency | String | No | ISO 4217 currency code (e.g. "GHS"). |
taxPercent | Float | No | Optional tax percentage to apply to the subtotal (e.g. 12.5 for 12.5%). |
discountAmount | Integer | No | Flat discount value to subtract from the subtotal in minor units (e.g. 500 = GHS 5.00). |
items | Array | Yes | List of invoice line items to bill. Structure detailed below. |
items[].description | String | Yes | Description narration of the billed item. |
items[].quantity | Integer | Yes | Billed quantity of the item. |
items[].unitAmount | Integer | Yes | Unit price of the item in minor units (e.g. 2000 = GHS 20.00). |
metadata | Object | No | Flat key-value object containing invoice metadata. |
Code Examples
curl https://api.xtopay.co/v1/invoices \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{
"customerId": "cust_cl8z2lh820000a",
"currency": "GHS",
"items": [
{
"description": "Enterprise Development Support",
"quantity": 1,
"unitAmount": 150000
}
]
}'Sample Response
201 Created
{
"success": true,
"data": {
"id": "inv_cl9a1b2c30000y",
"invoiceNumber": "INV-2026-0042",
"customerId": "cust_cl8z2lh820000a",
"status": "DRAFT",
"subtotal": 150000,
"tax": 0,
"discount": 0,
"total": 150000,
"amountDue": 150000,
"amountPaid": 0,
"currency": "GHS",
"paymentUrl": null,
"createdAt": "2026-06-05T12:00:00Z"
}
}Retrieve an Invoice
Retrieve the details of an existing invoice.
| Detail | Description |
|---|---|
| API Endpoint | https://api.xtopay.co/v1/invoices/:id |
| Request Type | GET |
| Authentication | Basic Base64(clientId:clientSecret) |
| Required Scope | payments:read |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
:id | String | Yes | Unique Invoice ID to retrieve. |
Code Examples
curl https://api.xtopay.co/v1/invoices/inv_cl9a1b2c30000y \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET"Finalize an Invoice
Transitions a draft invoice status to OPEN and generates a payment link.
| Detail | Description |
|---|---|
| API Endpoint | https://api.xtopay.co/v1/invoices/:id/finalize |
| Request Type | POST |
| Authentication | Basic Base64(clientId:clientSecret) |
| Required Scope | payments:write |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
:id | String | Yes | Unique ID of the draft invoice to finalize. |
Code Examples
curl -X POST https://api.xtopay.co/v1/invoices/inv_cl9a1b2c30000y/finalize \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET"Sample Response
200 OK
{
"success": true,
"data": {
"id": "inv_cl9a1b2c30000y",
"invoiceNumber": "INV-2026-0042",
"status": "OPEN",
"total": 150000,
"paymentUrl": "https://checkout.xtopay.co/invoice/inv_cl9a1b2c30000y",
"createdAt": "2026-06-05T12:00:00Z"
}
}Void an Invoice
Void an open invoice to cancel billing collections.
| Detail | Description |
|---|---|
| API Endpoint | https://api.xtopay.co/v1/invoices/:id/void |
| Request Type | POST |
| Authentication | Basic Base64(clientId:clientSecret) |
| Required Scope | payments:write |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
:id | String | Yes | Unique ID of the open invoice to void. |
List Invoices
List invoices with status and customer filters.
| Detail | Description |
|---|---|
| API Endpoint | https://api.xtopay.co/v1/invoices |
| Request Type | GET |
| Authentication | Basic Base64(clientId:clientSecret) |
| Required Scope | payments:read |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId | String | No | Filter by customer ID. |
status | String | No | Filter by status: DRAFT, OPEN, PAID, VOID, UNCOLLECTIBLE. |
limit | Integer | No | Limit the results per page (default 20). |
cursor | String | No | Pagination cursor. |
How is this guide?