# 3. First sale

> Create a sale, add a product and make the payment.

A sale in BILLZ is assembled step by step: create a sale → add items → (attach a customer, apply discounts) → pay.

## 1. Create a sale

```bash
curl -X POST 'https://api-admin.billz.ai/v2/order?Billz-Response-Channel=HTTP' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "shop_id": "SHOP_ID",
    "cashbox_id": "CASHBOX_ID"
  }'
```

The `cashbox_id` parameter can be omitted. The method is asynchronous: `Billz-Response-Channel=HTTP` (here as a query parameter; the header of the same name also works) makes the API wait for the result and return it in an envelope.

```json
{
  "status_code": 200,
  "id": "38c3920a-ffdd-4233-a823-8af3266f5f4f",
  "data": {
    "id": "38c3920a-ffdd-4233-a823-8af3266f5f4f",
    "order_number": "5632631379",
    "order_type": "SALE"
  },
  "correlation_id": "3674f28e-7b96-4683-87c3-80892698f421"
}
```

The sale UUID is the `id` field (the same value is in `data.id`); it is needed in all subsequent steps. `order_number` is the short number shown in the BILLZ interface. The shop is set by the `shop_id` field, the cash register by `cashbox_id`; the list of shops is returned by `GET /v1/shop`.

## 2. Add a product

```bash
curl -X POST 'https://api-admin.billz.ai/v2/order-product/SALE_ID' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Billz-Response-Channel: HTTP' \
  -d '{
    "product_id": "PRODUCT_ID",
    "sold_measurement_value": 1
  }'
```

> **The field is called `sold_measurement_value`**
>
> `shop_id` is not passed to this method: the shop is set on the sale.

Only this method triggers the cart recalculation, without which the payment is rejected.

## 3. Attach a customer (optional)

```bash
curl -X PUT 'https://api-admin.billz.ai/v2/order-customer-new/SALE_ID' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Billz-Response-Channel: HTTP' \
  -d '{ "customer_id": "CUSTOMER_ID", "check_auth_code": false }'
```

## 4. Pay

The available payment methods are returned by [`GET /v1/company-payment-type`](/en/reference/api/operations/get_v1_company_payment_type/). A receipt can be closed with several payments at once.

```bash
curl -X POST 'https://api-admin.billz.ai/v2/order-payment/SALE_ID' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "payments": [
      { "company_payment_type_id": "PAYMENT_TYPE_ID", "paid_amount": 1000000, "returned_amount": 0 }
    ],
    "comment": "online store"
  }'
```

The response is `{"order_type": "SALE", "should_print_cheque": true}`.

## Common errors

| Symptom                             | Usual cause                                                                                           |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `401`                               | `access_token` has expired — [refreshing the token pair](/en/concepts/auth/)                          |
| `403`                               | the route is not in the list allowed for the key — [what the key can do](/en/reference/permissions/)  |
| `200` with a single `message` field | the `Billz-Response-Channel: HTTP` header is missing                                                  |
| `400`, `data.error_code` = `20084`  | products were added with the wrong method — see step 2                                                |
| `400`, code `20020`                 | the sum of payments does not match the receipt total                                                  |
| `400`, `data.error_code` = `20010`  | there is no open cash register in the shop                                                            |
| `408` exactly after 10 minutes      | the result was not delivered over the HTTP channel; the sale state is checked with a separate request |

Next: [verify the result in BILLZ](/en/start/verify/).