# `PaperTiger.Resources.Invoice`
[🔗](https://github.com/EnaiaInc/paper_tiger/blob/v1.2.2/lib/paper_tiger/resources/invoice.ex#L1)

Handles Invoice resource endpoints.

## Endpoints

- POST   /v1/invoices      - Create invoice
- GET    /v1/invoices/:id  - Retrieve invoice
- POST   /v1/invoices/:id  - Update invoice
- DELETE /v1/invoices/:id  - Delete invoice (draft only)
- GET    /v1/invoices      - List invoices

## Invoice Object

    %{
      id: "in_...",
      object: "invoice",
      created: 1234567890,
      status: "draft",
      customer: "cus_...",
      amount_due: 2000,
      amount_paid: 0,
      currency: "usd",
      lines: %{
        data: [%{amount: 2000, description: "Premium Plan"}]
      },
      # ... other fields
    }

## Invoice Statuses

- draft - Not yet finalized
- open - Sent to customer, awaiting payment
- paid - Payment successful
- uncollectible - Payment attempts failed
- void - Invoice voided

# `attach_payment`

```elixir
@spec attach_payment(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Attaches a payment to an invoice.

POST /v1/invoices/:id/attach_payment

# `create`

```elixir
@spec create(Plug.Conn.t()) :: Plug.Conn.t()
```

Creates a new invoice.

## Required Parameters

- customer - Customer ID

## Optional Parameters

- id - Custom ID (must start with "in_"). Useful for seeding deterministic data.
- auto_advance - Auto-finalize invoice (default: true)
- collection_method - charge_automatically or send_invoice
- currency - Three-letter ISO currency code (default: "usd")
- description - Invoice description
- metadata - Key-value metadata
- subscription - Subscription ID (if subscription invoice)

# `create_preview`

```elixir
@spec create_preview(Plug.Conn.t()) :: Plug.Conn.t()
```

Creates a preview invoice for proposed subscription changes.

POST /v1/invoices/create_preview

Reads `subscription` and `subscription_details[items]` from params,
merges proposed changes with existing items, and returns a synthetic invoice.
Not persisted to ETS.

# `delete`

```elixir
@spec delete(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Deletes an invoice.

Note: Only draft invoices can be deleted.

# `finalize`

```elixir
@spec finalize(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Finalizes a draft invoice.

POST /v1/invoices/:id/finalize

Transitions the invoice from draft to open status.
Only draft invoices can be finalized.

# `list`

```elixir
@spec list(Plug.Conn.t()) :: Plug.Conn.t()
```

Lists all invoices with pagination.

## Parameters

- limit - Number of items (default: 10, max: 100)
- starting_after - Cursor for pagination
- ending_before - Reverse cursor
- customer - Filter by customer
- status - Filter by status
- subscription - Filter by subscription

# `mark_uncollectible`

```elixir
@spec mark_uncollectible(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Marks an invoice as uncollectible.

POST /v1/invoices/:id/mark_uncollectible

# `pay`

```elixir
@spec pay(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Marks an invoice as paid.

POST /v1/invoices/:id/pay

Transitions the invoice to paid status.

# `retrieve`

```elixir
@spec retrieve(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Retrieves an invoice by ID.

# `search`

```elixir
@spec search(Plug.Conn.t()) :: Plug.Conn.t()
```

Searches invoices with Stripe-style search query syntax.

# `send_invoice`

```elixir
@spec send_invoice(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Sends an invoice to the customer.

POST /v1/invoices/:id/send

Emits invoice.sent and returns the invoice. The invoice remains open.

# `upcoming`

```elixir
@spec upcoming(Plug.Conn.t()) :: Plug.Conn.t()
```

Retrieves an upcoming invoice preview for a subscription.

GET /v1/invoices/upcoming

Builds a synthetic invoice from the subscription's current items (or from
`subscription_items` if provided for proration preview).
Not persisted to ETS.

# `update`

```elixir
@spec update(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Updates an invoice.

## Updatable Fields

- description
- metadata
- auto_advance
- collection_method
- due_date

# `void_invoice`

```elixir
@spec void_invoice(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Voids an invoice.

POST /v1/invoices/:id/void

Transitions the invoice to void status.
Open invoices can be voided.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
