{
  "openapi": "3.0.3",
  "info": {
    "title": "BUZZ Pay API",
    "version": "2.0.0",
    "description": "Описание API BUZZ Pay. Руководства и примеры кода на сайте документации."
  },
  "servers": [
    {
      "url": "https://buzz-pay.com/api/sub/v1"
    }
  ],
  "tags": [
    {
      "name": "Курсы и справочники"
    },
    {
      "name": "Баланс и история"
    },
    {
      "name": "Кассы"
    },
    {
      "name": "Платежи"
    },
    {
      "name": "KYC"
    },
    {
      "name": "Песочница"
    },
    {
      "name": "База клиентов"
    }
  ],
  "paths": {
    "/rates": {
      "get": {
        "tags": [
          "Курсы и справочники"
        ],
        "summary": "Текущий курс",
        "description": "Курс с учётом вашей наценки — тот же, что в кабинете. Обновляется примерно раз в 30 секунд.\n\nЕсли для кабинета включены тарифы по типам трафика, в ответе появляются `traffic_tariffs_enabled: true` и `rates_by_traffic_type` — курс для каждого типа (`default` — для касс без отдельного тарифа). Курс конкретной кассы: `GET /rates?point_id=<id>` — `rub_per_usdt` вернётся уже по тарифу этой кассы. Без `point_id` `rub_per_usdt` — базовый тариф.",
        "responses": {
          "200": {
            "description": "Курс",
            "content": {
              "application/json": {
                "example": {
                  "rub_per_usdt": 88.4136,
                  "updated_at": "2026-09-19T10:00:00+00:00",
                  "local_rates": {
                    "THB": {
                      "symbol": "฿",
                      "per_usdt": 32.4041,
                      "rub_per_unit": 2.724653,
                      "units_per_rub": 0.367
                    }
                  },
                  "traffic_tariffs_enabled": true,
                  "rates_by_traffic_type": {
                    "default": {
                      "rub_per_usdt": 88.4136
                    },
                    "exchange": {
                      "rub_per_usdt": 90.46
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "point_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "ID кассы — курс по её тарифу (при мультитарифе)."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/currencies": {
      "get": {
        "tags": [
          "Курсы и справочники"
        ],
        "summary": "Локальные валюты",
        "description": "Список валют, доступных для касс.",
        "responses": {
          "200": {
            "description": "Список",
            "content": {
              "application/json": {
                "example": [
                  {
                    "code": "USDT",
                    "name": "Tether USD",
                    "symbol": "$",
                    "decimals": 2
                  },
                  {
                    "code": "THB",
                    "name": "Thai Baht",
                    "symbol": "฿",
                    "decimals": 2
                  }
                ]
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/traffic-types": {
      "get": {
        "tags": [
          "Курсы и справочники"
        ],
        "summary": "Типы трафика",
        "description": "Справочник типов трафика для создания касс.",
        "responses": {
          "200": {
            "description": "Список",
            "content": {
              "application/json": {
                "example": [
                  {
                    "key": "exchange",
                    "label": "Обмен валюты"
                  }
                ]
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/capabilities": {
      "get": {
        "tags": [
          "Курсы и справочники"
        ],
        "summary": "Возможности кабинета",
        "description": "Какие функции включены для кабинета.",
        "responses": {
          "200": {
            "description": "Возможности",
            "content": {
              "application/json": {
                "example": {
                  "allow_permanent_link": true,
                  "allow_offline_points": true
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/balance": {
      "get": {
        "tags": [
          "Баланс и история"
        ],
        "summary": "Баланс",
        "description": "Баланс кабинета в USDT: available — доступно к выводу, hold — на удержании (hold_kyc, hold_release, hold_payouts).",
        "responses": {
          "200": {
            "description": "Баланс",
            "content": {
              "application/json": {
                "example": {
                  "balances": {
                    "usdt": {
                      "available": 1250.5,
                      "hold": 120,
                      "hold_payouts": 0,
                      "hold_refunds": 0,
                      "hold_kyc": 20,
                      "hold_release": 100
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/balance-history": {
      "get": {
        "tags": [
          "Баланс и история"
        ],
        "summary": "История баланса",
        "description": "Движения баланса: зачисления, холды, выплаты.",
        "responses": {
          "200": {
            "description": "История",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": 1,
                      "date": "2026-09-19T10:05:00+00:00",
                      "type": "credit_order",
                      "amount": 56.55,
                      "currency": "USDT",
                      "balance_after": 1307.05,
                      "note": "BP-004210"
                    }
                  ],
                  "source": "ledger"
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/points": {
      "get": {
        "tags": [
          "Кассы"
        ],
        "summary": "Список касс",
        "description": "Все кассы вашего кабинета с настройками.",
        "responses": {
          "200": {
            "description": "Кассы",
            "content": {
              "application/json": {
                "example": [
                  {
                    "id": 12,
                    "name": "Основная",
                    "account": "USDT",
                    "comission": 0,
                    "is_active": true,
                    "permanent_link": true,
                    "payment_reference": "Z9X8C7V6B5N4M3L2",
                    "custom_fields": [
                      {
                        "key": "purpose",
                        "label": "Назначение",
                        "type": "select",
                        "options": [
                          "Аренда",
                          "Депозит"
                        ],
                        "required": true,
                        "to_comment": true
                      }
                    ]
                  }
                ]
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Кассы"
        ],
        "summary": "Создать кассу",
        "description": "Новая касса сразу привязывается к вашему кабинету. Тестовым ключом недоступно (403 test_mode_readonly).",
        "responses": {
          "201": {
            "description": "Создана",
            "content": {
              "application/json": {
                "example": {
                  "id": 13,
                  "name": "Касса сайта",
                  "account": "USDT",
                  "is_active": true,
                  "permanent_link": true,
                  "payment_reference": "Q1W2E3R4T5Y6U7I8"
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "account": {
                    "type": "string",
                    "default": "USDT"
                  },
                  "comission": {
                    "type": "number"
                  },
                  "permanent_link": {
                    "type": "boolean"
                  },
                  "require_name": {
                    "type": "boolean"
                  },
                  "require_email": {
                    "type": "boolean"
                  },
                  "fixed_amount_rub": {
                    "type": "number"
                  },
                  "kyc_mode": {
                    "type": "string",
                    "enum": [
                      "verified",
                      "unverified"
                    ]
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Касса сайта",
                "account": "USDT",
                "permanent_link": true
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/points/{id}": {
      "get": {
        "tags": [
          "Кассы"
        ],
        "summary": "Касса по ID",
        "description": "",
        "responses": {
          "200": {
            "description": "Касса",
            "content": {
              "application/json": {
                "example": {
                  "id": 12,
                  "name": "Основная",
                  "account": "USDT",
                  "comission": 0,
                  "is_active": true
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID кассы",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Кассы"
        ],
        "summary": "Обновить кассу",
        "description": "Передайте только поля, которые нужно изменить. PATCH работает так же. Тестовым ключом недоступно.",
        "responses": {
          "200": {
            "description": "Обновлена",
            "content": {
              "application/json": {
                "example": {
                  "id": 13,
                  "name": "Касса сайта",
                  "is_active": false
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID кассы",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "is_active": {
                    "type": "boolean"
                  },
                  "comission": {
                    "type": "number"
                  }
                },
                "required": []
              },
              "example": {
                "is_active": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders": {
      "post": {
        "tags": [
          "Платежи"
        ],
        "summary": "Создать платёж",
        "description": "Создаёт платёж на кассе и возвращает payment_url — ссылку на страницу оплаты для клиента.\n\n**KYC.** `kyc_type=unverified` (по умолчанию) — клиент проходит проверку сам на странице оплаты. `kyc_type=verified` — документы загружаете вы: multipart/form-data с `file_document`, `file_selfie`, `file_address` (см. примеры с файлами), либо позже через `/orders/by-reference/{reference}/documents`. Передайте `client_external_id` (или `client_phone`) — и для следующих платежей этого клиента файлы не нужны. Подробнее — руководство «Проверка клиента».\n\nТестовым ключом заказ создаётся в песочнице (is_test: true) и оплачивается через simulate-payment.",
        "responses": {
          "201": {
            "description": "Создан",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "order": {
                      "$ref": "#/components/schemas/Order"
                    },
                    "payment_url": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "unverified",
                    "kyc_status": "pending",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00"
                  },
                  "payment_url": "https://buzz-pay.com/pay/A1B2C3D4E5F6G7H8"
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrder"
              },
              "examples": {
                "minimal": {
                  "summary": "Минимальный",
                  "value": {
                    "point_id": 12,
                    "amount_rub": 5000
                  }
                },
                "unverified": {
                  "summary": "unverified: клиент проходит KYC на странице оплаты",
                  "value": {
                    "point_id": 12,
                    "amount_rub": 5000,
                    "kyc_type": "unverified",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "description": "Заказ #123"
                  }
                },
                "verified_returning": {
                  "summary": "verified: повторный клиент (документы уже одобрены, файлы не нужны)",
                  "value": {
                    "point_id": 12,
                    "amount_rub": 3000,
                    "kyc_type": "verified",
                    "client_external_id": "user-777"
                  }
                },
                "verified_by_phone": {
                  "summary": "verified: клиент по телефону",
                  "value": {
                    "point_id": 12,
                    "amount_rub": 3000,
                    "kyc_type": "verified",
                    "client_phone": "+79001234567",
                    "client_name": "Иван Петров"
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/CreateOrder"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "file_document": {
                        "type": "string",
                        "format": "binary",
                        "description": "Разворот паспорта (до 10 МБ)"
                      },
                      "file_selfie": {
                        "type": "string",
                        "format": "binary",
                        "description": "Селфи с паспортом"
                      },
                      "file_address": {
                        "type": "string",
                        "format": "binary",
                        "description": "Страница с пропиской (passport_type=ru)"
                      }
                    }
                  }
                ]
              },
              "examples": {
                "verified_ru": {
                  "summary": "verified: паспорт РФ + документы (первый платёж клиента)",
                  "value": {
                    "point_id": 12,
                    "amount_rub": 5000,
                    "kyc_type": "verified",
                    "client_external_id": "user-777",
                    "client_name": "Иван Петров",
                    "passport_type": "ru"
                  }
                },
                "verified_other": {
                  "summary": "verified: иностранный паспорт + адрес текстом",
                  "value": {
                    "point_id": 12,
                    "amount_rub": 5000,
                    "kyc_type": "verified",
                    "client_external_id": "user-778",
                    "client_name": "John Smith",
                    "passport_type": "other",
                    "client_address": "Bangkok, Sukhumvit 21, 5/12"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "get": {
        "tags": [
          "Платежи"
        ],
        "summary": "Список платежей",
        "description": "Платежи ваших касс, новые первыми. pagination.total считается до фильтрации по кассам и может быть больше фактического — листайте, пока data не станет пустым. Тестовым ключом — заказы песочницы (фильтр только status).",
        "responses": {
          "200": {
            "description": "Список",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": 4210,
                      "order_number": "BP-004210",
                      "status": "paid",
                      "amount_rub": 5000,
                      "amount_usdt": 56.55,
                      "rate_usdt": 88.41,
                      "payment_reference": "A1B2C3D4E5F6G7H8",
                      "client_name": "Иван Петров",
                      "client_external_id": "user-777",
                      "kyc_type": "unverified",
                      "kyc_status": "pending",
                      "point": {
                        "id": 12,
                        "name": "Основная",
                        "account": "USDT"
                      },
                      "created_at": "2026-09-19T10:00:00+00:00"
                    }
                  ],
                  "pagination": {
                    "current_page": 1,
                    "last_page": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Страница (по умолчанию 1)",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Записей на странице (по умолчанию 20, макс. 100)",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "pending | processing | paid | cancelled | expired",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "processing",
                "paid",
                "cancelled",
                "expired"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Начало периода YYYY-MM-DD",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Конец периода YYYY-MM-DD",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "point_id",
            "in": "query",
            "description": "Фильтр по кассе",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Поиск по номеру / клиенту",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/{id}": {
      "get": {
        "tags": [
          "Платежи"
        ],
        "summary": "Платёж по ID",
        "description": "",
        "responses": {
          "200": {
            "description": "Платёж",
            "content": {
              "application/json": {
                "example": {
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "unverified",
                    "kyc_status": "pending",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID платежа",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "patch": {
        "tags": [
          "Платежи"
        ],
        "summary": "Комментарий к платежу",
        "description": "Задаёт client_name — комментарий, видимый в кабинете в колонке «Комментарий». Пустая строка очищает.",
        "responses": {
          "200": {
            "description": "Обновлён",
            "content": {
              "application/json": {
                "example": {
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Заказ #123, Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "unverified",
                    "kyc_status": "pending",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID платежа",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_name": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true
                  }
                },
                "required": [
                  "client_name"
                ]
              },
              "example": {
                "client_name": "Заказ #123, Иван Петров"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/by-reference/{reference}": {
      "get": {
        "tags": [
          "Платежи"
        ],
        "summary": "Платёж по reference",
        "description": "Поиск по payment_reference из ссылки на оплату.",
        "responses": {
          "200": {
            "description": "Платёж",
            "content": {
              "application/json": {
                "example": {
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "unverified",
                    "kyc_status": "pending",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "description": "payment_reference",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/by-external-id/{externalId}": {
      "get": {
        "tags": [
          "Платежи"
        ],
        "summary": "Платёж по вашему ID",
        "description": "Поиск по client_external_id, переданному при создании.",
        "responses": {
          "200": {
            "description": "Платёж",
            "content": {
              "application/json": {
                "example": {
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "unverified",
                    "kyc_status": "pending",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "externalId",
            "in": "path",
            "required": true,
            "description": "Ваш идентификатор клиента",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/{id}/kyc": {
      "get": {
        "tags": [
          "KYC"
        ],
        "summary": "Статус KYC платежа",
        "description": "kyc_status: pending (ждёт клиента или документы), submitted (на проверке), approved, rejected. Для тестовых заказов всегда 404.",
        "responses": {
          "200": {
            "description": "KYC",
            "content": {
              "application/json": {
                "example": {
                  "kyc_type": "verified",
                  "kyc_status": "approved",
                  "client": {
                    "first_name": "Иван",
                    "last_name": "Петров",
                    "status": "verified"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID платежа",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/points/{id}/order": {
      "post": {
        "tags": [
          "Платежи"
        ],
        "summary": "Платёж по постоянной ссылке",
        "description": "Для касс с permanent_link: создаёт платёж с заранее заданной суммой и данными плательщика, отдаёт payment_url.",
        "responses": {
          "201": {
            "description": "Создан",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "order": {
                      "$ref": "#/components/schemas/Order"
                    },
                    "payment_url": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 1500,
                    "amount_usdt": 16.97,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "unverified",
                    "kyc_status": "pending",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00"
                  },
                  "payment_url": "https://buzz-pay.com/pay/A1B2C3D4E5F6G7H8"
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID кассы с постоянной ссылкой",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount_rub": {
                    "type": "number"
                  },
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string"
                  },
                  "client_external_id": {
                    "type": "string"
                  },
                  "custom": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Ответы на дополнительные поля кассы {ключ: значение}"
                  }
                }
              },
              "examples": {
                "amount_only": {
                  "summary": "Только сумма",
                  "value": {
                    "amount_rub": 1500
                  }
                },
                "with_payer": {
                  "summary": "Сумма + данные плательщика",
                  "value": {
                    "amount_rub": 1500,
                    "first_name": "Иван",
                    "last_name": "Петров",
                    "email": "ivan@example.com"
                  }
                },
                "with_client_key": {
                  "summary": "С вашим ID клиента",
                  "value": {
                    "amount_rub": 1500,
                    "first_name": "Иван",
                    "last_name": "Петров",
                    "client_external_id": "user-777"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/by-reference/{reference}/documents": {
      "post": {
        "tags": [
          "KYC"
        ],
        "summary": "Дозагрузить документы к платежу",
        "description": "multipart/form-data, хотя бы один файл обязателен. В ответе verified_kyc_status — фактический статус после загрузки. Передайте client_phone/client_name, чтобы документы привязались к клиенту базы. В песочнице файлы не сохраняются, kyc_status сразу approved.",
        "responses": {
          "200": {
            "description": "Загружено",
            "content": {
              "application/json": {
                "example": {
                  "message": "Документы загружены",
                  "verified_kyc_status": "submitted",
                  "verified_client_id": 91
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "description": "payment_reference платежа",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file_document": {
                    "type": "string",
                    "format": "binary",
                    "description": "Разворот паспорта (до 10 МБ)"
                  },
                  "file_selfie": {
                    "type": "string",
                    "format": "binary",
                    "description": "Селфи с паспортом"
                  },
                  "file_address": {
                    "type": "string",
                    "format": "binary",
                    "description": "Страница с пропиской"
                  },
                  "client_name": {
                    "type": "string"
                  },
                  "client_phone": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "docs_only": {
                  "summary": "Только документы",
                  "value": {
                    "client_name": "Иван Петров"
                  }
                },
                "docs_with_client": {
                  "summary": "Документы + привязка к клиенту базы по телефону",
                  "value": {
                    "client_name": "Иван Петров",
                    "client_phone": "+79001234567"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/by-reference/{reference}/attach-client": {
      "post": {
        "tags": [
          "KYC"
        ],
        "summary": "Привязать клиента базы к платежу",
        "description": "Привязывает уже проверенного клиента (id из GET /clients) без повторной загрузки документов. В песочнице недоступно (404).",
        "responses": {
          "200": {
            "description": "Привязан",
            "content": {
              "application/json": {
                "example": {
                  "message": "Клиент привязан",
                  "order": {
                    "id": 4210,
                    "order_number": "BP-004210",
                    "status": "pending",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": "verified",
                    "kyc_status": "approved",
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00",
                    "client_id": 91
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "validation_failed",
                  "message": "The amount rub field is required.",
                  "errors": {
                    "amount_rub": [
                      "The amount rub field is required."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "description": "payment_reference платежа",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "integer"
                  }
                },
                "required": [
                  "client_id"
                ]
              },
              "example": {
                "client_id": 91
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/orders/{id}/simulate-payment": {
      "post": {
        "tags": [
          "Песочница"
        ],
        "summary": "Симуляция оплаты (только тестовый ключ)",
        "description": "Переводит тестовый заказ в paid без реальной оплаты и отправляет вебхук order.paid с is_test: true. С боевым ключом — 403.",
        "responses": {
          "200": {
            "description": "Оплачен",
            "content": {
              "application/json": {
                "example": {
                  "message": "Тестовый платёж успешно симулирован.",
                  "order": {
                    "id": 90000001,
                    "order_number": "BP-TEST-90000001",
                    "status": "paid",
                    "amount_rub": 5000,
                    "amount_usdt": 56.55,
                    "rate_usdt": 88.41,
                    "payment_reference": "A1B2C3D4E5F6G7H8",
                    "client_name": "Иван Петров",
                    "client_external_id": "user-777",
                    "kyc_type": null,
                    "kyc_status": null,
                    "point": {
                      "id": 12,
                      "name": "Основная",
                      "account": "USDT"
                    },
                    "created_at": "2026-09-19T10:00:00+00:00",
                    "global_id": "BP-TEST-90000001",
                    "is_test": true
                  },
                  "webhook_queued": true,
                  "_sandbox": "Тестовый режим — база не затронута."
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "Боевой ключ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "test_key_required",
                  "message": "Симуляция оплаты доступна только с тестовым ключом (тестовый ключ)."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID тестового заказа (90 000 000+)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/clients": {
      "get": {
        "tags": [
          "База клиентов"
        ],
        "summary": "Список клиентов",
        "description": "Проверенные клиенты вашего кабинета: документы загружаются один раз, повторные платежи создаются по client_external_id или client_phone.",
        "responses": {
          "200": {
            "description": "Клиенты",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": 91,
                      "external_id": "user-777",
                      "phone": "+79001234567",
                      "first_name": "Иван",
                      "last_name": "Петров",
                      "status": "verified"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "description": "Поиск по имени / телефону / ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Фильтр по статусу верификации",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/clients/{key}": {
      "get": {
        "tags": [
          "База клиентов"
        ],
        "summary": "Клиент по ID или телефону",
        "description": "",
        "responses": {
          "200": {
            "description": "Клиент",
            "content": {
              "application/json": {
                "example": {
                  "client": {
                    "id": 91,
                    "external_id": "user-777",
                    "phone": "+79001234567",
                    "first_name": "Иван",
                    "last_name": "Петров",
                    "status": "verified"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ключ отсутствует, отозван или неверен",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "API-ключ недействителен или отозван."
                }
              }
            }
          },
          "403": {
            "description": "API выключен владельцем кабинета или раздел не включён",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "scope_disabled",
                  "message": "Раздел «orders» не включён для вашего кабинета."
                }
              }
            }
          },
          "404": {
            "description": "Не найдено или не принадлежит вашему кабинету",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found",
                  "message": "Не найдено."
                }
              }
            }
          },
          "429": {
            "description": "Превышен лимит 120 запросов в минуту",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "too_many_requests",
                  "message": "Too Many Attempts."
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "client_external_id или телефон",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "боевой или тестовый API-ключ",
        "description": "Ключ из раздела «API» кабинета. Тестовый ключ включает песочницу."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "errors": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "CreateOrder": {
        "type": "object",
        "required": [
          "point_id",
          "amount_rub"
        ],
        "properties": {
          "point_id": {
            "type": "integer",
            "description": "ID кассы (GET /points)"
          },
          "amount_rub": {
            "type": "number",
            "minimum": 0.01,
            "description": "Сумма в ₽"
          },
          "description": {
            "type": "string",
            "maxLength": 500,
            "description": "Назначение платежа"
          },
          "client_name": {
            "type": "string",
            "description": "Имя клиента для отчётности"
          },
          "client_external_id": {
            "type": "string",
            "maxLength": 64,
            "description": "Ваш ID клиента — ключ клиента базы; документы нужны только при первом платеже"
          },
          "client_phone": {
            "type": "string",
            "description": "Телефон клиента — альтернативный ключ клиента базы"
          },
          "kyc_type": {
            "type": "string",
            "enum": [
              "unverified",
              "verified"
            ],
            "description": "unverified — клиент проходит проверку сам на странице оплаты (по умолчанию); verified — документы загружаете вы"
          },
          "passport_type": {
            "type": "string",
            "enum": [
              "ru",
              "other"
            ],
            "description": "Для verified: ru — паспорт РФ (нужна страница с пропиской), other — иностранный (адрес текстом)"
          },
          "client_address": {
            "type": "string",
            "maxLength": 500,
            "description": "Адрес регистрации для passport_type=other"
          },
          "custom": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Ответы на дополнительные поля кассы {ключ: значение}; конфиг полей — в GET /points (custom_fields). Обязательные поля проверяются, значения попадают в заказ как custom_fields"
          }
        }
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "order_number": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "paid",
              "cancelled",
              "expired"
            ]
          },
          "is_test": {
            "type": "boolean",
            "description": "Только у заказов песочницы"
          },
          "amount_rub": {
            "type": "number"
          },
          "amount_usdt": {
            "type": "number",
            "nullable": true
          },
          "rate_usdt": {
            "type": "number",
            "nullable": true
          },
          "payment_reference": {
            "type": "string"
          },
          "client_name": {
            "type": "string",
            "nullable": true
          },
          "client_external_id": {
            "type": "string",
            "nullable": true
          },
          "kyc_type": {
            "type": "string",
            "nullable": true
          },
          "kyc_status": {
            "type": "string",
            "nullable": true
          },
          "point": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              },
              "account": {
                "type": "string"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "custom_fields": {
            "type": "array",
            "description": "Ответы на дополнительные поля кассы",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}