# Sale from an external system

> Full scenario of making a sale, including discounts, gift cards and held receipts.

The basic path is described in [first sale](/en/start/first-sale/).

## Receipt discount

```bash
curl -X POST 'https://api-admin.billz.ai/v2/order-manual-discount/SALE_ID' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Billz-Response-Channel: HTTP' \
  -d '{ "discount_unit": "PERCENTAGE", "discount_value": 10 }'
```

`discount_unit` accepts `PERCENTAGE` or `CURRENCY`. The optional `product_id` field applies the discount to a single line item; without it, the discount applies to the whole cart.

The current receipt after changing the contents or discounts is returned by the synchronous `POST /v1/recalculate-order-bill/:order_id`.

> **Receipt recalculation and cart recalculation are different operations**
>
> The “cart recalculated” flag checked by the payment is set only by the **cart recalculation**, which is triggered by `POST /v2/order-product/:order_id`, `POST /v2/order-manual-discount/:order_id` and `PUT /v2/order-customer-new/:order_id`. `recalculate-order-bill` recalculates the amounts. See [sale lifecycle](/en/concepts/sale-lifecycle/).

## Payment with several methods

```json
{
  "payments": [
    { "company_payment_type_id": "CASH_ID", "paid_amount": 100000 },
    { "company_payment_type_id": "CARD_ID", "paid_amount": 900000 }
  ]
}
```

To redeem the customer’s bonus points, fill in the `with_cashback` field.

## Gift cards

1. Find the card: `GET /v1/gift-card/search` — synchronous
2. Add to the sale: `PUT /v1/order-gift-card/:id` — **asynchronous**
3. Remove: `POST /v1/order-gift-card-remove/:id` — **asynchronous**
4. Pay with the gift card: `POST /v2/order-payment/:order_id`

> **`:id` is the sale ID, `gift_card_id` is an integer**
>
> The gift card is specified in the body as an integer:
>
> ```json
> { "gift_card_id": 10472 }
> ```

## Hold and resume

A held receipt is a way to reserve products in a sale.

* Hold: `POST /v2/order/create_postpone` (asynchronous) — the body contains `order_id`, `time` and an optional `comment`; the `time` field is required and has a strict format (`2024-07-16 06:47:30`)
* Resume: `POST /v2/order/return-postpone` (asynchronous)
* Change a line item quantity: `POST /v2/order-product/:order_id`, the `sold_measurement_value` field; the value `0` **removes** the line item together with the manual discount assigned to it

## Lists and details

| Task                          | Method                                                                                                                       |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Sales for a period            | reports `GET /v1/general-report-table` and `GET /v1/transaction-report-table` — see [sales export](/en/guides/sales-export/) |
| Details of one sale           | `GET /v2/order/:id`                                                                                                          |
| List of drafts and held sales | `GET /v2/order-notes`                                                                                                        |

## Headers

The methods that change the receipt contents, the customer and discounts are asynchronous. They require `Billz-Response-Channel: HTTP`, otherwise only a `correlation_id` is returned. The payment `POST /v2/order-payment/:order_id` and the recalculation `POST /v1/recalculate-order-bill/:order_id` are synchronous — they do not need the header.

> **The response channel is set by a header or a query parameter**
>
> `Billz-Response-Channel` is read from the header, and if it is absent — from the query parameter with the same name (`?Billz-Response-Channel=HTTP`).
>
> The exception is `POST /v2/order-product/:order_id`: it also accepts the `response_type: "HTTP"` field in the body. Other methods do not have this field.