# Invoices (/docs/guides/invoices)

This guide shows you how to bill a customer for an agreed amount. You create an invoice with products or custom items, publish it, get it to the customer with a payment link, and take the payment yourself if you need to. When the invoice is paid in full it becomes an order.

## Draft and published [#draft-and-published]

A new invoice is a **draft** unless you send `draft: false`.

| | Draft | Published |
|---|---|---|
| Change items, customer, currency | Yes | Items and currency yes, until a payment is applied. Not the customer. |
| Customer can see and pay it | No | Yes |
| Back to the other state | Publish it with `draft: false` | Never back to draft |

Publishing fires [`invoice:published`](/api/webhooks/invoice-published) and emails the customer a payment link, unless you send `suppress_customer_notification: true`.

## Create an invoice [#create-an-invoice]

Call [Create an invoice](/api/invoices/create-invoice) with a secret or trusted token. Items can be products from your catalog (`product_id`) or **custom items**: a `name`, a `type` (`digital`, `physical` or `service`) and a `reference_price`. Custom items exist only on invoices and subscriptions, never in carts.

```bash title="Request"
curl https://api.comecero.com/api/v1/invoices \
  -H "Authorization: Bearer $COMECERO_TEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "USD",
    "date_due": "2026-11-30",
    "customer": {
      "name": "John Doe",
      "email": "john@example.com",
      "billing_address": { "country": "US", "postal_code": "62701" }
    },
    "items": [
      { "name": "Website setup, 10 hours", "type": "service", "quantity": 10, "reference_price": 95 },
      { "product_id": "pdf-pro.test", "quantity": 1 }
    ]
  }'
```

```json title="Response"
{
  "object": "invoice",
  "invoice_id": "8417-QZPLD-215",
  "draft": true,
  "open": true,
  "payment_status": "unpaid",
  "currency": "USD",
  "total": 1049.95,
  "total_remaining": 1049.95
}
```

Tax, shipping and promotions are worked out as on a cart. Physical items need a shipping address. To make a custom item a subscription, give it a `subscription_plan_id`: paying the invoice starts the subscription.

While the invoice is open and unpaid, change it with [Update an invoice](/api/invoices/update-invoice) (sending `items` replaces every item), or one item at a time with [Add an invoice item](/api/invoices/create-invoice-item) and [Update an invoice item](/api/invoices/update-invoice-item).

## Publish it [#publish-it]

Send `draft: false` with [Update an invoice](/api/invoices/update-invoice), or create the invoice with `draft: false` to publish it at once.

```bash title="Request"
curl https://api.comecero.com/api/v1/invoices/8417-QZPLD-215 \
  -H "Authorization: Bearer $COMECERO_TEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "draft": false }'
```

To charge the customer's saved payment method by itself on the due date, also send `autopay: true`. The customer must have a payment method on file, and `payment_status` becomes `scheduled`.

## Get it to the customer [#get-it-to-the-customer]

You have three ways:

- **Let Comecero email it.** Publishing emails the customer a payment link through your notification subscription for invoice links. Call [Send an invoice](/api/invoices/send-invoice) to email a new link later, for example as a reminder.
- **Send the link yourself.** Call [Create a payment link](/api/invoices/create-invoice-link) and put `link_url` in your own email or app. Each call makes a new link, and links expire after 30 days. Publish with `suppress_customer_notification: true` so the customer does not get two emails.
- **Attach a PDF.** [Get the invoice](/api/invoices/get-invoice) with `Accept: application/pdf`.

```json
{
  "link_url": "https://shop.example.com/link?id=in-7f3c2a91b04e4d6c9a1e"
}
```

The link is built on the host of the app installed for invoice payments, or the first app host in your technical settings. Sending and links answer `422` when the invoice is closed or there is no host (and sending, when you have no notification subscription for invoice links).

## Take a payment by API [#take-a-payment-by-api]

Call [Pay an invoice](/api/invoices/create-invoice-payment) with a `payment_method` or a saved `payment_method_id`. Do not send `currency`: it comes from the invoice. Leave out `total` to pay what is left, or send a smaller `total` to pay part of it.

```bash title="Request"
curl https://api.comecero.com/api/v1/invoices/8417-QZPLD-215/payments \
  -H "Authorization: Bearer $COMECERO_TEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_method": {
      "type": "credit_card",
      "data": { "number": "4444555566661111", "exp_month": 12, "exp_year": 2030, "cvv": "123" }
    }
  }'
```

The payment results are the same as for a cart: `completed`, `pending`, `initiated` (for example PayPal: commit it while it is still `initiated`), or a `402` decline. See [Accept payments](/docs/guides/accept-payments#handle-the-result).

When the invoice is paid in full it closes (`open: false`) and becomes an order with the same id as the invoice.

## What fires [#what-fires]

| When | Event |
|---|---|
| The invoice is created | [`invoice:created`](/api/webhooks/invoice-created) |
| It leaves draft | [`invoice:published`](/api/webhooks/invoice-published) |
| It is paid in full and the order is made (the payment may still be only authorized) | [`invoice:paid`](/api/webhooks/invoice-paid) and [`order:created`](/api/webhooks/order-created) |
| The completed payments on its order cover the total and none is pending, so the money is taken | [`invoice:payment_completed`](/api/webhooks/invoice-payment-completed) |

Each payment attempt also fires the payment events. See [Webhooks](/docs/guides/webhooks).

## Delete an invoice [#delete-an-invoice]

[Delete an invoice](/api/invoices/delete-invoice) removes an open invoice for good. You cannot delete a closed invoice, a subscription renewal invoice, or one with a completed or pending payment. No event fires.

<Cards>
  <Card title="Subscriptions" href="/docs/guides/subscriptions" />
  <Card title="Refunds" href="/docs/guides/refunds" />
</Cards>
