# Sale lifecycle

> Draft, held sale, payment, return — how a receipt moves through the system.

A sale in BILLZ is an object that passes through several states.

```plaintext
draft created
   ├── items added
   ├── customer attached        (optional)
   ├── discounts applied        (optional)
   ├── gift card added          (optional)
   │
   ├──> held     ──> resumed
   │
   └──> paid     ──> sale (fiscal receipt)
```

> **Some methods must be opened for the key separately**
>
> Issuing an integration key opens a basic set of methods; sensitive methods respond with `403` until the key’s access is extended.
>
> The basic list of routes: [what an integration key can do](/en/reference/permissions/).

## Draft

Created with `POST /v2/order` and the body `{"shop_id": "…"}`. This is an **asynchronous** method: with `Billz-Response-Channel: HTTP` the response comes in an envelope where the draft ID is in the `id` field and its short number is in `data.order_number`.

The draft is visible to the cashier in the shop and exists until it is paid or deleted (`DELETE /v2/order/:id` — asynchronous).

## Items

Added one at a time: `POST /v2/order-product/:order_id` (asynchronous), the quantity goes in the `sold_measurement_value` field.

The same method also removes an item: `sold_measurement_value: 0` deletes the line from the receipt together with the manual discount assigned to it.

> **Items are not added with the legacy `order.add_item`**

## Held sale

A separate state: the receipt is paused but not lost. To hold — `POST /v2/order/create_postpone` (asynchronous), with `order_id`, `time` and an optional `comment` in the body. To resume — `POST /v2/order/return-postpone`. The `time` field is required and needs a strict format: `2024-07-16 06:47:30`.

## Payment

`POST /v2/order-payment/:order_id` closes the receipt. This is a **synchronous** method: it does not need the `Billz-Response-Channel` header. The body is an array of payments: a receipt can be paid with several methods at once, as well as with the customer’s bonuses via `with_cashback`. After payment the draft becomes a sale and appears in reports.

Payment requires an **open shift** in the shop of sale when cash register shifts are in use. Payment errors are covered in [online order](/en/guides/ecommerce-order/).

## Discounts

A manual discount — `POST /v2/order-manual-discount/:order_id` (asynchronous): on the whole cart or on a specific product if `product_id` is passed.

Recalculation of the receipt total — `POST /v1/recalculate-order-bill/:order_id`, **synchronous**: the response contains the recalculated sale breakdown.

## What is synchronous and what is not

Each method has its own mode:

| Method                                      | How it works |
| ------------------------------------------- | ------------ |
| `POST /v1/recalculate-order-bill/:order_id` | synchronous  |
| `POST /v2/order-payment/:order_id`          | synchronous  |
| `GET /v2/order/:id`, `GET /v2/order-notes`  | synchronous  |
| `POST /v2/order` (sale creation)            | asynchronous |
| `POST /v2/order-product/:order_id`          | asynchronous |
| `POST /v2/order-manual-discount/:order_id`  | asynchronous |
| `PUT /v2/order-customer-new/:order_id`      | asynchronous |
| `DELETE /v2/order/:id`                      | asynchronous |
| `POST /v2/order/create_postpone`            | asynchronous |
| `POST /v2/order/return-postpone`            | asynchronous |

For asynchronous methods pass `Billz-Response-Channel: HTTP`, otherwise the response contains only the request identifier.