> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.paymentkit.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paymentkit.com/_mcp/server.

# Pending invoice items

Pending invoice items (also called floating items) let you add one-off charges to a subscription. By default, these charges are collected on the next renewal invoice. You can also [bill them immediately](#bill-pending-items-on-demand) without waiting for renewal. This is useful for usage-based charges, setup fees, or any ad-hoc billing.

# How it works

When you create an invoice item with a `subscription_id`, the item is stored as a "floating" item:

1. The item is created with `invoice_id = null` (not yet attached to an invoice)
2. The item is linked to the subscription via `subscription_id`
3. At the next renewal, PaymentKit automatically sweeps all floating items into the renewal invoice
4. The customer is charged for the subscription's recurring items plus all pending one-off charges

# Create a pending invoice item

Add a one-off charge to a subscription using the invoice items endpoint.

## With a catalog price

Use a catalog price when you want consistent product naming and reporting:

#### API

```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/invoice-items \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
  "customer_id": "cus_abc123",
  "subscription_id": "sub_xyz789",
  "price_id": "price_sms_usage",
  "quantity": 150,
  "description": "SMS charges - July 2026 (150 messages)"
}'
```

#### Python SDK

```python
item = client.invoice_items.create(
    account_id="acc_xxx",
    customer_id="cus_abc123",
    subscription_id="sub_xyz789",
    price_id="price_sms_usage",
    quantity=150,
    description="SMS charges - July 2026 (150 messages)"
)
```

## With a custom amount

Create an amount-only item when you don't need a catalog price. The currency is automatically derived from the subscription:

#### API

```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/invoice-items \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
  "customer_id": "cus_abc123",
  "subscription_id": "sub_xyz789",
  "amount": 75.00,
  "description": "Custom setup fee"
}'
```

#### Python SDK

```python
item = client.invoice_items.create(
    account_id="acc_xxx",
    customer_id="cus_abc123",
    subscription_id="sub_xyz789",
    amount=75.00,
    description="Custom setup fee"
)
```

**Currency handling:** When creating an amount-only item (no `price_id`), the currency is automatically set to match the subscription's currency. When using a `price_id`, the price's currency must match the subscription's currency.

# View pending charges

## Preview the upcoming invoice

Use the subscription preview endpoint to see all pending charges that will be collected at renewal:

```bash
curl -X GET https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/preview \
-H "Authorization: Bearer sk_live_..."
```

Each pending (floating) item is returned as its own line item in the `upcoming_invoice.items` array, listed alongside the subscription's recurring items — so you can see exactly what will be charged, not just the aggregate total. Every pending item includes its `description`, `quantity`, and `amount`, is denominated in the subscription's currency, and carries a `proration` flag indicating whether it was generated by a mid-cycle change.

Itemizing pending charges in the preview does not change any totals: `upcoming_invoice.subtotal`, `total`, and related amounts already account for these items exactly once.

```json
{
  "upcoming_invoice": {
    "items": [
      {
        "description": "Pro plan",
        "quantity": 1,
        "amount": 4900,
        "currency": "usd",
        "proration": false
      },
      {
        "description": "SMS charges - July 2026 (150 messages)",
        "quantity": 150,
        "amount": 1500,
        "currency": "usd",
        "proration": false
      }
    ]
  }
}
```

## List pending items for a subscription

Use the invoice items list endpoint with `status=floating` to get all pending (unbilled) charges for a subscription. Floating items are those not yet swept onto an invoice:

#### API

```bash
curl -X GET "https://app.paymentkit.com/api/{account_id}/invoice-items?subscription_id=sub_xyz789&status=floating" \
-H "Authorization: Bearer sk_live_..."
```

#### Python SDK

```python
result = client.invoice_items.list(
    account_id="acc_xxx",
    subscription_id="sub_xyz789",
    status="floating",
)
```

The response is paginated — matching items are returned in the `items` array alongside `total` and `has_more`. You can also filter by `customer_id`, or pass `status=attached` to list items already swept onto an invoice. Omit `status` to return both.

**Global search** now indexes invoice items. Paste an item's `ii_` id into the dashboard search bar (or scope a search with the `ii` prefix) to jump straight to a pending item.

# Validation rules

| Rule                   | Description                                                                                                |
| ---------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Subscription state** | Must be `active` or `trialing`. Cannot add pending items to cancelled, paused, or past\_due subscriptions. |
| **Customer match**     | The `customer_id` must match the subscription's customer.                                                  |
| **Currency match**     | If `price_id` is provided, the price's currency must match the subscription's currency.                    |
| **Positive amount**    | Amount-only items (no `price_id`) must have a positive `amount` or `unit_amount`.                          |

# Renewal behavior

When a subscription renews:

1. PaymentKit creates a draft renewal invoice
2. All floating items for the subscription are attached to this invoice
3. The invoice is finalized and payment is collected
4. The floating items now have `invoice_id` set to the renewal invoice

If the renewal invoice is voided (e.g., due to mid-cycle changes), floating items return to their unbilled state (`invoice_id = null`) and will be swept into the replacement invoice.

# Bill pending items on demand

Bill accumulated charges immediately without waiting for the next renewal. The bill-pending-items endpoint sweeps all floating items for a customer into standalone invoices, finalizes them, and attempts collection.

```mermaid
flowchart LR
    A[Floating items] --> B[Create invoice per currency]
    B --> C[Finalize]
    C --> D{Payment}
    D -->|Success| E[Invoice paid]
    D -->|Failure| F[Invoice open for dunning]
```

## Create an off-cycle invoice

#### API

```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/invoices/bill-pending-items \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: bill-cus123-july-usage" \
-d '{
  "customer_id": "cus_abc123"
}'
```

#### Python SDK

```python
result = client.invoices.bill_pending_items(
    account_id="acc_xxx",
    customer_id="cus_abc123"
)

for invoice in result.invoices:
    print(f"{invoice.currency}: {invoice.total_amount_atom} atoms, {invoice.items_swept} items")
```

**Response:**

```json
{
  "invoices": [
    {
      "id": "inv_abc123",
      "currency": "usd",
      "status": "paid",
      "total_amount_atom": 1500,
      "items_swept": 3
    }
  ]
}
```

The response contains one invoice per currency. If the customer has no pending items, the `invoices` array is empty.

## Filter which items to bill

By default, all floating items for the customer are swept. Use filters to narrow the scope.

### Bill specific items

Pass `item_ids` to sweep only specific floating items:

```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/invoices/bill-pending-items \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
  "customer_id": "cus_abc123",
  "item_ids": ["ii_item1", "ii_item2"]
}'
```

When `item_ids` is provided, other filters (`subscription_id`, `currency`) are ignored.

### Bill items from a specific subscription

```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/invoices/bill-pending-items \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
  "customer_id": "cus_abc123",
  "subscription_id": "sub_xyz789"
}'
```

### Bill items in a specific currency

```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/invoices/bill-pending-items \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
  "customer_id": "cus_abc123",
  "currency": "EUR"
}'
```

## Request fields

| Field               | Type    | Required | Description                                                                |
| ------------------- | ------- | -------- | -------------------------------------------------------------------------- |
| `customer_id`       | string  | Yes      | Customer whose pending items to bill                                       |
| `item_ids`          | array   | No       | Specific item IDs to sweep. Overrides other filters.                       |
| `subscription_id`   | string  | No       | Narrow to a single subscription                                            |
| `currency`          | string  | No       | Narrow to a single currency. If omitted, creates one invoice per currency. |
| `tax_amount_atom`   | integer | No       | Tax amount in smallest currency unit (default: 0)                          |
| `discount_id`       | string  | No       | Discount to apply to the invoice                                           |
| `collection_method` | string  | No       | `charge_automatically` or `send_invoice`. Defaults to customer's setting.  |
| `description`       | string  | No       | Invoice memo                                                               |

## Response fields

| Field                          | Type    | Description                         |
| ------------------------------ | ------- | ----------------------------------- |
| `invoices`                     | array   | Invoices created (one per currency) |
| `invoices[].id`                | string  | Invoice external ID                 |
| `invoices[].currency`          | string  | Invoice currency code               |
| `invoices[].status`            | string  | `paid`, `open`, etc.                |
| `invoices[].total_amount_atom` | integer | Total in smallest currency unit     |
| `invoices[].items_swept`       | integer | Number of floating items attached   |

## Behavior

| Scenario                 | Behavior                                                                                       |
| ------------------------ | ---------------------------------------------------------------------------------------------- |
| **Multi-currency**       | Creates one invoice per currency. A customer with USD and EUR pending items gets two invoices. |
| **Payment success**      | Invoice status is `paid`.                                                                      |
| **Payment failure**      | Invoice remains `open` and enters the dunning flow.                                            |
| **No pending items**     | Returns empty `invoices` array (200 OK).                                                       |
| **Paused subscriptions** | Items from paused subscriptions are excluded.                                                  |
| **Race with renewal**    | Row-level locking prevents double-billing. If a renewal is in progress, returns 409 Conflict.  |

**Idempotency:** Without an `Idempotency-Key` header, duplicate requests create duplicate invoices. Always include an idempotency key for production use.

# Use cases

| Use case                         | Implementation                                                                                            |
| -------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **Usage-based billing**          | Track usage throughout the billing period, then create a pending item with the total usage before renewal |
| **One-time setup fees**          | Add a setup fee when the subscription is created or upgraded                                              |
| **Ad-hoc professional services** | Bill consulting or implementation hours as they occur                                                     |
| **Overage charges**              | Add charges when customers exceed plan limits                                                             |
| **On-demand usage billing**      | Accumulate charges mid-cycle (e.g., SMS), then call `/invoices/bill-pending-items` to collect immediately |

**Pending items do not affect subscription state.** Pending charges are passive — they don't trigger pause, cancel, or dunning logic. They are simply swept into the renewal invoice when it's created.