# Invoice

Create programmable invoices via API and let your customers pay through the standard checkout gateway. Invoices support partial payments, tax calculations, line items, and automated status tracking.

**Required permission:** `invoices`

## How it works

1. **Create** an invoice via API with customer details, line items, and due date
2. **Send** the invoice (transitions from draft to sent)
3. **Share** the `payment_url` with your customer
4. Customer opens the payment URL and pays via bank transfer or PayID
5. Invoice status updates automatically: `partial` → `paid`
6. You receive webhook events for each status change

---

## Create Invoice

```
POST /v1/checkout/invoice
```

Creates a new invoice in `draft` status. You must [send](#send-invoice) the invoice before customers can pay.

### Authentication

Requires a **secret key** (`sk_*`).

### Request body

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `customer_name` | string | Yes | Customer's full name (max 255 characters) |
| `customer_email` | string | Yes | Customer's email address |
| `customer_address` | string | No | Customer's street address |
| `customer_city` | string | No | Customer's city (max 100) |
| `customer_state` | string | No | Customer's state/region (max 100) |
| `customer_country` | string | No | Customer's country (max 100) |
| `line_items` | array | Yes | Array of line item objects (at least one) |
| `line_items[].description` | string | Yes | Description of the item (max 500) |
| `line_items[].quantity` | number | Yes | Quantity (supports decimals, min 0.01) |
| `line_items[].unit_price` | integer | Yes | Unit price in **kobo** |
| `tax_rate` | number | No | Tax rate as percentage (0–100, e.g., `7.5` for 7.5%). Default: `0` |
| `due_date` | string | Yes | Due date in ISO 8601 format |
| `invoice_number` | string | No | Custom invoice number (max 64). Auto-generated if omitted (e.g., `INV-202603-001`) |
| `reference` | string | No | Your unique reference for reconciliation (max 255) |
| `note` | string | No | Note to display on the invoice payment page (max 2000) |
| `metadata` | object | No | Custom key-value data stored with the invoice |

### Example request

::: code-group

```bash [cURL]
curl -X POST https://api.zevpaycheckout.com/v1/checkout/invoice \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_test_your_secret_key" \
  -d '{
    "customer_name": "Chidi Okonkwo",
    "customer_email": "chidi@example.com",
    "customer_address": "15 Admiralty Way, Lekki Phase 1",
    "customer_city": "Lagos",
    "customer_state": "Lagos",
    "customer_country": "Nigeria",
    "line_items": [
      {
        "description": "Website Development",
        "quantity": 1,
        "unit_price": 35000000
      },
      {
        "description": "Monthly Hosting (12 months)",
        "quantity": 12,
        "unit_price": 500000
      }
    ],
    "tax_rate": 7.5,
    "due_date": "2026-03-31T00:00:00Z",
    "reference": "PROJECT-2026-001",
    "note": "Thank you for your business!",
    "metadata": {
      "project_id": "PRJ-123"
    }
  }'
```

```javascript [Node.js]
const response = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer sk_test_your_secret_key",
    },
    body: JSON.stringify({
      customer_name: "Chidi Okonkwo",
      customer_email: "chidi@example.com",
      customer_address: "15 Admiralty Way, Lekki Phase 1",
      customer_city: "Lagos",
      customer_state: "Lagos",
      customer_country: "Nigeria",
      line_items: [
        { description: "Website Development", quantity: 1, unit_price: 35000000 },
        { description: "Monthly Hosting (12 months)", quantity: 12, unit_price: 500000 },
      ],
      tax_rate: 7.5,
      due_date: "2026-03-31T00:00:00Z",
      reference: "PROJECT-2026-001",
      note: "Thank you for your business!",
      metadata: { project_id: "PRJ-123" },
    }),
  }
);
const data = await response.json();
```

```python [Python]
import requests

response = requests.post(
    "https://api.zevpaycheckout.com/v1/checkout/invoice",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer sk_test_your_secret_key",
    },
    json={
        "customer_name": "Chidi Okonkwo",
        "customer_email": "chidi@example.com",
        "customer_address": "15 Admiralty Way, Lekki Phase 1",
        "customer_city": "Lagos",
        "customer_state": "Lagos",
        "customer_country": "Nigeria",
        "line_items": [
            {"description": "Website Development", "quantity": 1, "unit_price": 35000000},
            {"description": "Monthly Hosting (12 months)", "quantity": 12, "unit_price": 500000},
        ],
        "tax_rate": 7.5,
        "due_date": "2026-03-31T00:00:00Z",
        "reference": "PROJECT-2026-001",
        "note": "Thank you for your business!",
        "metadata": {"project_id": "PRJ-123"},
    },
)
data = response.json()
```

:::

### Response

```json
{
  "success": true,
  "data": {
    "public_id": "abc123def456ghi78",
    "invoice_number": "INV-202603-001",
    "status": "draft",
    "customer_name": "Chidi Okonkwo",
    "customer_email": "chidi@example.com",
    "customer_address": "15 Admiralty Way, Lekki Phase 1",
    "customer_city": "Lagos",
    "customer_state": "Lagos",
    "customer_country": "Nigeria",
    "subtotal": 41000000,
    "tax_rate": 7.5,
    "tax_amount": 3075000,
    "total": 44075000,
    "amount_paid": 0,
    "currency": "NGN",
    "due_date": "2026-03-31T00:00:00.000Z",
    "issued_at": null,
    "paid_at": null,
    "cancelled_at": null,
    "merchant_reference": "PROJECT-2026-001",
    "metadata": { "project_id": "PRJ-123" },
    "note": "Thank you for your business!",
    "payment_url": "https://invoice.zevpaycheckout.com/pay/abc123def456ghi78?token=...",
    "created_at": "2026-03-08T10:00:00.000Z"
  }
}
```

### Response fields

| Field | Type | Description |
|-------|------|-------------|
| `public_id` | string | Unique public identifier for the invoice |
| `invoice_number` | string | Human-readable invoice number (auto-generated or custom) |
| `status` | string | Current status: `draft`, `sent`, `partial`, `paid`, `overdue`, `cancelled` |
| `customer_name` | string | Customer's full name |
| `customer_email` | string | Customer's email address |
| `customer_address` | string \| null | Customer's street address |
| `customer_city` | string \| null | Customer's city |
| `customer_state` | string \| null | Customer's state/region |
| `customer_country` | string \| null | Customer's country |
| `subtotal` | integer | Subtotal in kobo (sum of line items, before tax) |
| `tax_rate` | number | Tax rate as a percentage (e.g., `7.5`) |
| `tax_amount` | integer | Tax amount in kobo |
| `total` | integer | Total amount in kobo (subtotal + tax) |
| `amount_paid` | integer | Cumulative amount paid so far, in kobo |
| `currency` | string | Currency code. Always `"NGN"` |
| `due_date` | string | Due date in ISO 8601 format |
| `issued_at` | string \| null | Timestamp when invoice was sent (ISO 8601). `null` for drafts |
| `paid_at` | string \| null | Timestamp when invoice was fully paid. `null` until paid |
| `cancelled_at` | string \| null | Timestamp when invoice was cancelled. `null` unless cancelled |
| `merchant_reference` | string \| null | Your custom reference, if provided |
| `metadata` | object \| null | Your custom key-value data, if provided |
| `note` | string \| null | Invoice note, if provided |
| `payment_url` | string | URL for the customer to view and pay the invoice |
| `created_at` | string | Invoice creation timestamp (ISO 8601) |

::: tip Amounts
All monetary amounts in the API are in **kobo** (1 NGN = 100 kobo). For example, `35000000` kobo = ₦350,000.00.
:::

::: tip Payment URL
Store the `public_id` (and optionally the `payment_url`) in your database. The `payment_url` resolves to the payment page when the invoice is payable, or shows a receipt when paid.
:::

---

## Update Invoice

```
PATCH /v1/checkout/invoice/:publicId
```

Updates a **draft** invoice. Only invoices with `status: "draft"` can be updated — once sent, an invoice cannot be modified.

### Authentication

Requires a **secret key** (`sk_*`).

### Path parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `publicId` | string | The invoice's `public_id` |

### Request body

All fields are optional. Only include the fields you want to change.

| Parameter | Type | Description |
|-----------|------|-------------|
| `customer_name` | string | Customer's full name |
| `customer_email` | string | Customer's email address |
| `customer_address` | string | Customer's street address |
| `customer_city` | string | Customer's city |
| `customer_state` | string | Customer's state/region |
| `customer_country` | string | Customer's country |
| `line_items` | array | Replacement line items (replaces all existing items) |
| `line_items[].description` | string | Item description |
| `line_items[].quantity` | number | Quantity |
| `line_items[].unit_price` | integer | Unit price in kobo |
| `tax_rate` | number | Tax rate as percentage (0–100) |
| `due_date` | string | Due date in ISO 8601 format |
| `invoice_number` | string | Custom invoice number |
| `note` | string | Invoice note |
| `metadata` | object | Custom key-value data |

::: warning Line items replacement
When you include `line_items` in an update, all existing line items are **replaced** — not merged. Always send the complete list of line items you want on the invoice.
:::

### Example request

::: code-group

```bash [cURL]
curl -X PATCH https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_test_your_secret_key" \
  -d '{
    "note": "Updated: payment due by end of month",
    "due_date": "2026-04-15T00:00:00Z"
  }'
```

```javascript [Node.js]
const response = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78",
  {
    method: "PATCH",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer sk_test_your_secret_key",
    },
    body: JSON.stringify({
      note: "Updated: payment due by end of month",
      due_date: "2026-04-15T00:00:00Z",
    }),
  }
);
const data = await response.json();
```

```python [Python]
import requests

response = requests.patch(
    "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer sk_test_your_secret_key",
    },
    json={
        "note": "Updated: payment due by end of month",
        "due_date": "2026-04-15T00:00:00Z",
    },
)
data = response.json()
```

:::

### Response

Returns the updated invoice object (same shape as [Create Invoice](#create-invoice) response).

### Errors

| Status | Message | Cause |
|--------|---------|-------|
| 404 | Invoice not found | Invoice does not exist or does not belong to your account |
| 400 | Only draft invoices can be edited | Invoice has already been sent, paid, or cancelled |
| 400 | Invoice total must be greater than zero | Updated line items result in zero or negative total |

---

## List Invoices

```
GET /v1/checkout/invoice
```

Returns a paginated list of your invoices, ordered by creation date (newest first).

### Authentication

Requires a **secret key** (`sk_*`).

### Query parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number (min 1). Default: `1` |
| `page_size` | integer | No | Items per page (1–100). Default: `20` |
| `status` | string | No | Filter by status: `draft`, `sent`, `partial`, `paid`, `overdue`, `cancelled` |
| `customer_email` | string | No | Filter by exact customer email address |
| `search` | string | No | Search by invoice number, customer name, or customer email (partial match) |

::: info customer_email vs search
`customer_email` performs an **exact match** on the email field. `search` performs a **partial match** (contains) across invoice number, customer name, and email. Use `customer_email` when you know the exact email; use `search` for flexible lookups.
:::

### Example request

::: code-group

```bash [cURL]
# List all sent invoices
curl "https://api.zevpaycheckout.com/v1/checkout/invoice?status=sent&page=1&page_size=20" \
  -H "Authorization: Bearer sk_test_your_secret_key"

# Filter by customer email
curl "https://api.zevpaycheckout.com/v1/checkout/invoice?customer_email=chidi@example.com" \
  -H "Authorization: Bearer sk_test_your_secret_key"
```

```javascript [Node.js]
// List all sent invoices
const response = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice?status=sent&page=1",
  {
    headers: { "Authorization": "Bearer sk_test_your_secret_key" },
  }
);
const data = await response.json();

// Filter by customer email
const byEmail = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice?customer_email=chidi@example.com",
  {
    headers: { "Authorization": "Bearer sk_test_your_secret_key" },
  }
);
```

```python [Python]
import requests

# List all sent invoices
response = requests.get(
    "https://api.zevpaycheckout.com/v1/checkout/invoice",
    headers={"Authorization": "Bearer sk_test_your_secret_key"},
    params={"status": "sent", "page": 1, "page_size": 20},
)
data = response.json()

# Filter by customer email
by_email = requests.get(
    "https://api.zevpaycheckout.com/v1/checkout/invoice",
    headers={"Authorization": "Bearer sk_test_your_secret_key"},
    params={"customer_email": "chidi@example.com"},
)
```

:::

### Response

```json
{
  "success": true,
  "data": {
    "items": [
      {
        "public_id": "abc123def456ghi78",
        "invoice_number": "INV-202603-001",
        "status": "sent",
        "customer_name": "Chidi Okonkwo",
        "customer_email": "chidi@example.com",
        "customer_address": "15 Admiralty Way, Lekki Phase 1",
        "customer_city": "Lagos",
        "customer_state": "Lagos",
        "customer_country": "Nigeria",
        "subtotal": 41000000,
        "tax_rate": 7.5,
        "tax_amount": 3075000,
        "total": 44075000,
        "amount_paid": 0,
        "currency": "NGN",
        "due_date": "2026-03-31T00:00:00.000Z",
        "issued_at": "2026-03-08T10:05:00.000Z",
        "paid_at": null,
        "cancelled_at": null,
        "merchant_reference": "PROJECT-2026-001",
        "metadata": { "project_id": "PRJ-123" },
        "note": "Thank you for your business!",
        "payment_url": "https://invoice.zevpaycheckout.com/pay/abc123def456ghi78?token=...",
        "created_at": "2026-03-08T10:00:00.000Z"
      }
    ],
    "total": 1,
    "page": 1,
    "page_size": 20,
    "total_pages": 1
  }
}
```

### Pagination fields

| Field | Type | Description |
|-------|------|-------------|
| `items` | array | Array of invoice objects (same fields as Create response) |
| `total` | integer | Total number of invoices matching the filters |
| `page` | integer | Current page number |
| `page_size` | integer | Number of items per page |
| `total_pages` | integer | Total number of pages |

---

## Get Invoice

```
GET /v1/checkout/invoice/:publicId
```

Returns a single invoice with its **line items** and **payment history**.

### Authentication

Requires a **secret key** (`sk_*`).

### Path parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `publicId` | string | The invoice's `public_id` |

### Example request

::: code-group

```bash [cURL]
curl https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78 \
  -H "Authorization: Bearer sk_test_your_secret_key"
```

```javascript [Node.js]
const response = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78",
  {
    headers: { "Authorization": "Bearer sk_test_your_secret_key" },
  }
);
const data = await response.json();
```

```python [Python]
import requests

response = requests.get(
    "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78",
    headers={"Authorization": "Bearer sk_test_your_secret_key"},
)
data = response.json()
```

:::

### Response

```json
{
  "success": true,
  "data": {
    "public_id": "abc123def456ghi78",
    "invoice_number": "INV-202603-001",
    "status": "partial",
    "customer_name": "Chidi Okonkwo",
    "customer_email": "chidi@example.com",
    "customer_address": "15 Admiralty Way, Lekki Phase 1",
    "customer_city": "Lagos",
    "customer_state": "Lagos",
    "customer_country": "Nigeria",
    "subtotal": 41000000,
    "tax_rate": 7.5,
    "tax_amount": 3075000,
    "total": 44075000,
    "amount_paid": 20000000,
    "currency": "NGN",
    "due_date": "2026-03-31T00:00:00.000Z",
    "issued_at": "2026-03-08T10:05:00.000Z",
    "paid_at": null,
    "cancelled_at": null,
    "merchant_reference": "PROJECT-2026-001",
    "metadata": { "project_id": "PRJ-123" },
    "note": "Thank you for your business!",
    "payment_url": "https://invoice.zevpaycheckout.com/pay/abc123def456ghi78?token=...",
    "created_at": "2026-03-08T10:00:00.000Z",
    "line_items": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440001",
        "description": "Website Development",
        "quantity": 1,
        "unit_price": 35000000
      },
      {
        "id": "550e8400-e29b-41d4-a716-446655440002",
        "description": "Monthly Hosting (12 months)",
        "quantity": 12,
        "unit_price": 500000
      }
    ],
    "payments": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440003",
        "amount": 20000000,
        "paid_at": "2026-03-10T14:30:00.000Z",
        "payer_name": "CHIDI OKONKWO",
        "payment_channel": "bank_transfer"
      }
    ]
  }
}
```

### Line item fields

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Line item UUID |
| `description` | string | Item description |
| `quantity` | number | Quantity |
| `unit_price` | integer | Unit price in kobo |

### Payment fields

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Payment record UUID |
| `amount` | integer | Payment amount in kobo |
| `paid_at` | string | Payment timestamp (ISO 8601) |
| `payer_name` | string \| null | Name of the person who made the payment |
| `payment_channel` | string \| null | Payment channel: `"bank_transfer"` or `"payid"` |

---

## Send Invoice

Transitions an invoice from `draft` to `sent`. Sets the `issued_at` timestamp and makes the `payment_url` active.

```
POST /v1/checkout/invoice/:publicId/send
```

### Authentication

Requires a **secret key** (`sk_*`).

### Path parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `publicId` | string | The invoice's `public_id` |

### Example request

::: code-group

```bash [cURL]
curl -X POST https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78/send \
  -H "Authorization: Bearer sk_test_your_secret_key"
```

```javascript [Node.js]
const response = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78/send",
  {
    method: "POST",
    headers: { "Authorization": "Bearer sk_test_your_secret_key" },
  }
);
const data = await response.json();
```

```python [Python]
import requests

response = requests.post(
    "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78/send",
    headers={"Authorization": "Bearer sk_test_your_secret_key"},
)
data = response.json()
```

:::

### Response

Returns the updated invoice object with `status: "sent"` and `issued_at` populated.

### Errors

| Status | Message | Cause |
|--------|---------|-------|
| 404 | Invoice not found | Invoice does not exist or does not belong to your account |
| 400 | Only draft invoices can be sent | Invoice is not in draft status |

---

## Cancel Invoice

Cancels an invoice. Only invoices with status `draft`, `sent`, `partial`, or `overdue` can be cancelled.

```
POST /v1/checkout/invoice/:publicId/cancel
```

### Authentication

Requires a **secret key** (`sk_*`).

### Path parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `publicId` | string | The invoice's `public_id` |

### Example request

::: code-group

```bash [cURL]
curl -X POST https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78/cancel \
  -H "Authorization: Bearer sk_test_your_secret_key"
```

```javascript [Node.js]
const response = await fetch(
  "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78/cancel",
  {
    method: "POST",
    headers: { "Authorization": "Bearer sk_test_your_secret_key" },
  }
);
const data = await response.json();
```

```python [Python]
import requests

response = requests.post(
    "https://api.zevpaycheckout.com/v1/checkout/invoice/abc123def456ghi78/cancel",
    headers={"Authorization": "Bearer sk_test_your_secret_key"},
)
data = response.json()
```

:::

### Response

Returns the updated invoice object with `status: "cancelled"` and `cancelled_at` populated.

### Errors

| Status | Message | Cause |
|--------|---------|-------|
| 404 | Invoice not found | Invoice does not exist or does not belong to your account |
| 400 | Cannot cancel an invoice with status "paid" | Invoice is already fully paid |

---

## Invoice Status Lifecycle

```
draft → sent → partial → paid
  ↓       ↓       ↓
  └───────┴───────┴──→ cancelled

sent/partial → overdue (automatic, when past due date)
overdue → paid (if payment received after due date)
overdue → cancelled
```

| Status | Description |
|--------|-------------|
| `draft` | Invoice created but not yet sent to customer. Payment URL is not usable |
| `sent` | Invoice sent, awaiting payment. Payment URL is active |
| `partial` | Customer has made a partial payment |
| `paid` | Invoice fully paid |
| `overdue` | Past due date, not fully paid (set automatically by hourly check) |
| `cancelled` | Invoice cancelled by merchant |

---

## Webhook Events

Subscribe to these events via your [webhook configuration](https://business.zevpay.ng):

| Event | Description |
|-------|-------------|
| `invoice.created` | Invoice created via API |
| `invoice.sent` | Invoice status changed to `sent` |
| `invoice.payment_received` | Payment received (partial or full) |
| `invoice.paid` | Invoice fully paid |
| `invoice.overdue` | Invoice past due date, not fully paid |
| `invoice.cancelled` | Invoice cancelled |

See the full [Webhook Events Reference](/webhooks/events) for complete payload documentation.

### Example webhook payload

```json
{
  "event": "invoice.payment_received",
  "data": {
    "public_id": "abc123def456ghi78",
    "invoice_number": "INV-202603-001",
    "status": "partial",
    "customer_name": "Chidi Okonkwo",
    "customer_email": "chidi@example.com",
    "subtotal": 41000000,
    "tax_rate": 7.5,
    "tax_amount": 3075000,
    "total": 44075000,
    "amount_paid": 20000000,
    "currency": "NGN",
    "due_date": "2026-03-31T00:00:00.000Z",
    "issued_at": "2026-03-08T10:05:00.000Z",
    "paid_at": null,
    "merchant_reference": "PROJECT-2026-001",
    "metadata": { "project_id": "PRJ-123" },
    "payment_url": "https://invoice.zevpaycheckout.com/pay/abc123def456ghi78?token=...",
    "payment_amount": 20000000,
    "amount_remaining": 24075000,
    "payer_name": "CHIDI OKONKWO",
    "payment_channel": "bank_transfer"
  }
}
```

---

## Error Responses

All error responses follow this format:

```json
{
  "statusCode": 400,
  "message": "Only draft invoices can be edited.",
  "error": "Bad Request"
}
```

### Common errors

| Status | Message | Endpoint |
|--------|---------|----------|
| 401 | API key is required | All — missing or invalid API key |
| 403 | This endpoint requires a secret key | All — using a public key instead of secret key |
| 403 | Invoices are only available for business accounts | Create — personal account trying to create invoices |
| 400 | At least one line item is required | Create — empty line_items array |
| 400 | Invoice total must be greater than zero | Create/Update — calculated total is zero or negative |
| 400 | Invalid due date format | Create/Update — invalid ISO date string |
| 400 | Only draft invoices can be edited | Update — invoice is not in draft status |
| 400 | Only draft invoices can be sent | Send — invoice is not in draft status |
| 404 | Invoice not found | Get/Update/Send/Cancel — invalid public_id or not your invoice |

## Try it — Create Invoice

<ApiPlayground
  method="POST"
  endpoint="/v1/checkout/invoice"
  authType="bearer"
  :bodyFields="[
    { name: 'customer_name', type: 'string', required: true, placeholder: 'Chidi Okonkwo' },
    { name: 'customer_email', type: 'string', required: true, placeholder: 'chidi@example.com' },
    { name: 'line_items', type: 'object', required: true, placeholder: '[{ &quot;description&quot;: &quot;Web Development&quot;, &quot;quantity&quot;: 1, &quot;unit_price&quot;: 35000000 }]' },
    { name: 'tax_rate', type: 'integer', placeholder: '7.5', description: 'Percentage (0-100)' },
    { name: 'due_date', type: 'string', required: true, placeholder: '2026-03-31T00:00:00Z' },
    { name: 'note', type: 'string', placeholder: 'Thank you for your business!' },
    { name: 'reference', type: 'string', placeholder: 'PROJECT-2026-001' },
    { name: 'metadata', type: 'object', placeholder: '{ &quot;project_id&quot;: &quot;PRJ-123&quot; }' },
  ]"
/>

## Try it — List Invoices

<ApiPlayground
  method="GET"
  endpoint="/v1/checkout/invoice"
  authType="bearer"
  :queryParams="[
    { name: 'page', type: 'integer', placeholder: '1', default: '1' },
    { name: 'page_size', type: 'integer', placeholder: '20' },
    { name: 'status', type: 'select', options: [{ label: 'Draft', value: 'draft' }, { label: 'Sent', value: 'sent' }, { label: 'Partial', value: 'partial' }, { label: 'Paid', value: 'paid' }, { label: 'Overdue', value: 'overdue' }, { label: 'Cancelled', value: 'cancelled' }] },
    { name: 'search', type: 'string', placeholder: 'Search by customer or invoice number' },
  ]"
/>
