{
  "openapi": "3.1.0",
  "info": {
    "title": "AdaptGroup Shop API",
    "version": "0.1.0",
    "description": "API для Telegram Stars, Telegram Premium, пополнений игр/аккаунтов и цифровых кодов.\n\n**Base URL:** `https://shop-api.adaptgroup.pro`\n\nПередавайте `X-Api-Key` в заголовке и `api_key_id` в каждом JSON-запросе. Все маршруты используют POST. Все суммы в USD. Общий лимит — 100 запросов за 60 секунд на интеграцию.\n\nЦены каталога включают наценку платформы. При покупке цену передавать не нужно: с баланса интеграции списывается актуальная сумма.\n\nДокументация опубликована перед публичным запуском. Сквозное тестирование на рабочем окружении ещё предстоит. ID и цены в примерах условные и не являются предложениями текущего каталога.\n\n[Скачать OpenAPI (RU)](/openapi/shop.ru.json) · [OpenAPI (EN)](/openapi/shop.json)",
    "contact": {
      "name": "AdaptGroup",
      "url": "https://t.me/adapt_support",
      "email": "support@adaptgroup.org"
    }
  },
  "paths": {
    "/balance/check": {
      "post": {
        "tags": [
          "Balance"
        ],
        "summary": "Проверить баланс",
        "operationId": "checkBalance",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApiRequest"
              },
              "examples": {
                "balance": {
                  "summary": "Баланс",
                  "value": {
                    "api_key_id": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceCheckResponse"
                },
                "examples": {
                  "balance": {
                    "summary": "Баланс",
                    "value": {
                      "success": true,
                      "api_key_id": 1,
                      "balance": "25.0000",
                      "currency": "USD",
                      "balance_updated_at": "2026-09-26T12:00:00"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Возвращает текущий баланс вашей интеграции, а не предварительный расчёт. Валюта — USD."
      }
    },
    "/modules/list": {
      "post": {
        "tags": [
          "Catalog"
        ],
        "summary": "Список модулей",
        "operationId": "listModules",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApiRequest"
              },
              "examples": {
                "modules": {
                  "summary": "Модули",
                  "value": {
                    "api_key_id": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModulesResponse"
                },
                "examples": {
                  "modules": {
                    "summary": "Модули",
                    "value": {
                      "success": true,
                      "currency": "USD",
                      "modules": {
                        "stars": {
                          "price_per_star_usd": "0.0150"
                        },
                        "tg_premium": {
                          "nominals": [
                            {
                              "months": 3,
                              "price_usd": "12.0000"
                            },
                            {
                              "months": 6,
                              "price_usd": "16.0000"
                            },
                            {
                              "months": 12,
                              "price_usd": "29.0000"
                            }
                          ]
                        },
                        "topups": {
                          "items_count": 10,
                          "nominals_count": 50
                        },
                        "codes": {
                          "items_count": 8,
                          "nominals_count": 20
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Цены Stars и Premium, количество товаров и номиналов в пополнениях и кодах. Null вместо цены означает недоступность. Цены и ID в примерах условные."
      }
    },
    "/catalog/list": {
      "post": {
        "tags": [
          "Catalog"
        ],
        "summary": "Список товаров",
        "operationId": "listCatalog",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatalogListRequest"
              },
              "examples": {
                "topups": {
                  "summary": "Пополнения",
                  "value": {
                    "api_key_id": 1,
                    "module": "topups",
                    "query": "Example",
                    "limit": 50,
                    "offset": 0
                  }
                },
                "codes": {
                  "summary": "Коды",
                  "value": {
                    "api_key_id": 1,
                    "module": "codes",
                    "limit": 50,
                    "offset": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogListResponse"
                },
                "examples": {
                  "catalog": {
                    "summary": "Список товаров",
                    "value": {
                      "success": true,
                      "items": [
                        {
                          "id": 10,
                          "name": "Example Game",
                          "description": "Game account top-ups",
                          "image_url": null,
                          "nominals_count": 2
                        }
                      ],
                      "total_count": 1,
                      "limit": 50,
                      "offset": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Список активных товаров пополнений или кодов. Номиналы и цены получайте через /catalog/details. Для Stars и Premium этот маршрут не используется."
      }
    },
    "/catalog/details": {
      "post": {
        "tags": [
          "Catalog"
        ],
        "summary": "Детали товара",
        "operationId": "getCatalogItem",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatalogDetailsRequest"
              },
              "examples": {
                "topups": {
                  "summary": "Пополнения",
                  "value": {
                    "api_key_id": 1,
                    "module": "topups",
                    "item_id": 10
                  }
                },
                "codes": {
                  "summary": "Коды",
                  "value": {
                    "api_key_id": 1,
                    "module": "codes",
                    "item_id": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogDetailsResponse"
                },
                "examples": {
                  "item": {
                    "summary": "Товар и номиналы",
                    "value": {
                      "success": true,
                      "currency": "USD",
                      "item": {
                        "id": 10,
                        "name": "Example Game",
                        "description": "Game account top-ups",
                        "image_url": null,
                        "nominals_count": 2,
                        "nominals": [
                          {
                            "id": 11,
                            "name": "60 credits",
                            "price_usd": "0.9800",
                            "available": true
                          },
                          {
                            "id": 13,
                            "name": "300 credits",
                            "price_usd": null,
                            "available": false
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "404": {
            "description": "Товар, номинал или заказ не найден в указанной области.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Товар и его активные номиналы с вашей API-ценой за единицу. При недоступной цене возможны null и available=false. Поля получателя выбранного номинала — в /catalog/nominal."
      }
    },
    "/catalog/nominal": {
      "post": {
        "tags": [
          "Catalog"
        ],
        "summary": "Детали номинала",
        "operationId": "getCatalogNominal",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatalogNominalRequest"
              },
              "examples": {
                "topups": {
                  "summary": "Пополнения",
                  "value": {
                    "api_key_id": 1,
                    "module": "topups",
                    "item_id": 10,
                    "nominal_id": 11
                  }
                },
                "codes": {
                  "summary": "Коды",
                  "value": {
                    "api_key_id": 1,
                    "module": "codes",
                    "item_id": 20,
                    "nominal_id": 12
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogNominalResponse"
                },
                "examples": {
                  "topups": {
                    "summary": "Пополнения",
                    "value": {
                      "success": true,
                      "currency": "USD",
                      "nominal": {
                        "id": 11,
                        "item_id": 10,
                        "name": "60 credits",
                        "price_usd": "0.9800",
                        "available": true,
                        "input_fields": [
                          {
                            "key": "playerId",
                            "label": "UID",
                            "type": "input",
                            "required": true,
                            "options": []
                          },
                          {
                            "key": "server",
                            "label": "Server",
                            "type": "select",
                            "required": true,
                            "options": [
                              {
                                "key": "eu",
                                "label": "Europe"
                              },
                              {
                                "key": "asia",
                                "label": "Asia"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  },
                  "codes": {
                    "summary": "Коды",
                    "value": {
                      "success": true,
                      "currency": "USD",
                      "nominal": {
                        "id": 12,
                        "item_id": 20,
                        "name": "Gift code",
                        "price_usd": "0.9800",
                        "available": true,
                        "input_fields": []
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "404": {
            "description": "Товар, номинал или заказ не найден в указанной области.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Некорректный ответ при получении каталога или проверке получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Таймаут получения каталога или проверки получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Цена, доступность и актуальные поля получателя номинала, включая варианты серверов. ID принадлежат AdaptGroup. Ключи в примере условные: используйте реальные input_fields и options из ответа. У кодов полей получателя нет."
      }
    },
    "/orders/quote": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Рассчитать цену",
        "operationId": "quoteOrder",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/StarsQuoteRequest"
                  },
                  {
                    "$ref": "#/components/schemas/PremiumQuoteRequest"
                  },
                  {
                    "$ref": "#/components/schemas/CatalogQuoteRequest"
                  }
                ],
                "discriminator": {
                  "propertyName": "module",
                  "mapping": {
                    "stars": "#/components/schemas/StarsQuoteRequest",
                    "tg_premium": "#/components/schemas/PremiumQuoteRequest",
                    "topups": "#/components/schemas/CatalogQuoteRequest",
                    "codes": "#/components/schemas/CatalogQuoteRequest"
                  }
                },
                "title": "Data"
              },
              "examples": {
                "stars": {
                  "summary": "Telegram Stars",
                  "value": {
                    "api_key_id": 1,
                    "module": "stars",
                    "stars_amount": 50
                  }
                },
                "premium": {
                  "summary": "Telegram Premium",
                  "value": {
                    "api_key_id": 1,
                    "module": "tg_premium",
                    "months": 3
                  }
                },
                "topups": {
                  "summary": "Пополнения",
                  "value": {
                    "api_key_id": 1,
                    "module": "topups",
                    "nominal_id": 11,
                    "quantity": 1
                  }
                },
                "codes": {
                  "summary": "Коды",
                  "value": {
                    "api_key_id": 1,
                    "module": "codes",
                    "nominal_id": 12,
                    "quantity": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderQuoteResponse"
                },
                "examples": {
                  "quote": {
                    "summary": "Итоговая сумма",
                    "value": {
                      "success": true,
                      "module": "codes",
                      "amount_usd": "0.9800",
                      "currency": "USD"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Запрос нельзя выполнить: например, недостаточный баланс, неверный получатель или недоступный номинал.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "404": {
            "description": "Товар, номинал или заказ не найден в указанной области.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Некорректный ответ при получении каталога или проверке получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Таймаут получения каталога или проверки получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Рассчитывает текущую итоговую сумму в USD без проверки баланса интеграции, резервирования остатка и создания заказа. Цена не фиксируется. В /orders/create цену не передавайте: актуальная сумма рассчитывается и списывается при покупке."
      }
    },
    "/orders/create": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Создать заказ",
        "operationId": "createOrder",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/StarsCreateRequest"
                  },
                  {
                    "$ref": "#/components/schemas/PremiumCreateRequest"
                  },
                  {
                    "$ref": "#/components/schemas/TopupsCreateRequest"
                  },
                  {
                    "$ref": "#/components/schemas/CodesCreateRequest"
                  }
                ],
                "discriminator": {
                  "propertyName": "module",
                  "mapping": {
                    "stars": "#/components/schemas/StarsCreateRequest",
                    "tg_premium": "#/components/schemas/PremiumCreateRequest",
                    "topups": "#/components/schemas/TopupsCreateRequest",
                    "codes": "#/components/schemas/CodesCreateRequest"
                  }
                },
                "title": "Data"
              },
              "examples": {
                "stars": {
                  "summary": "Telegram Stars",
                  "value": {
                    "api_key_id": 1,
                    "module": "stars",
                    "stars_amount": 50,
                    "username": "example_user",
                    "api_user_id": "customer-789",
                    "partner_order_id": "order-456"
                  }
                },
                "premium": {
                  "summary": "Telegram Premium",
                  "value": {
                    "api_key_id": 1,
                    "module": "tg_premium",
                    "months": 3,
                    "username": "example_user",
                    "api_user_id": "customer-789",
                    "partner_order_id": "order-456"
                  }
                },
                "topups": {
                  "summary": "Пополнения",
                  "value": {
                    "api_key_id": 1,
                    "module": "topups",
                    "nominal_id": 11,
                    "quantity": 1,
                    "recipient_data": {
                      "playerId": "123456789",
                      "server": "eu"
                    },
                    "api_user_id": "customer-789",
                    "partner_order_id": "order-456"
                  }
                },
                "codes": {
                  "summary": "Коды",
                  "value": {
                    "api_key_id": 1,
                    "module": "codes",
                    "nominal_id": 12,
                    "quantity": 1,
                    "api_user_id": "customer-789",
                    "partner_order_id": "order-456"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCreateResponse"
                },
                "examples": {
                  "processing": {
                    "summary": "Принят в обработку",
                    "value": {
                      "success": true,
                      "order_id": 125,
                      "partner_order_id": "order-456",
                      "status": "processing",
                      "amount_usd": "0.9800",
                      "currency": "USD"
                    }
                  },
                  "completed": {
                    "summary": "Выполнен",
                    "value": {
                      "success": true,
                      "order_id": 125,
                      "partner_order_id": "order-456",
                      "status": "completed",
                      "amount_usd": "0.9800",
                      "currency": "USD"
                    }
                  },
                  "review": {
                    "summary": "Результат не подтверждён",
                    "value": {
                      "success": false,
                      "order_id": 125,
                      "partner_order_id": "order-456",
                      "status": "review",
                      "amount_usd": "0.9800",
                      "currency": "USD"
                    }
                  },
                  "refunded": {
                    "summary": "Средства возвращены",
                    "value": {
                      "success": false,
                      "order_id": 125,
                      "partner_order_id": "order-456",
                      "status": "refunded",
                      "amount_usd": "0.9800",
                      "currency": "USD"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Запрос нельзя выполнить: например, недостаточный баланс, неверный получатель или недоступный номинал.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Insufficient balance"
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "404": {
            "description": "Товар, номинал или заказ не найден в указанной области.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Некорректный ответ при получении каталога или проверке получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис недоступен либо результат создания не подтверждён. Если detail — объект с order_id, проверьте заказ через /orders/status; не повторяйте покупку.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCreationUnavailable"
                },
                "examples": {
                  "unavailable": {
                    "summary": "Недоступно",
                    "value": {
                      "detail": "Order creation unavailable"
                    }
                  },
                  "uncertain": {
                    "summary": "Результат не подтверждён",
                    "value": {
                      "detail": {
                        "message": "Order creation result unknown; check order status",
                        "order_id": 125,
                        "partner_order_id": "order-456"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "Таймаут получения каталога или проверки получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Каждый вызов создаёт отдельную покупку и списывает актуальную цену. Выберите ровно один вариант запроса по модулю. api_user_id — ваш клиент; необязательный partner_order_id связывает заказ с вашей системой, но не исключает повторы. Полей request_id и цены клиента нет. HTTP 200 со статусом processing означает принятие, а не выдачу. Учитывайте status даже при success=false: review — результат ещё не подтверждён, refunded — средства возвращены. Итог и коды получайте через /orders/status или финальный вебхук. Не повторяйте запрос автоматически после таймаута или неопределённого ответа; см. «Процесс покупки»."
      }
    },
    "/orders/status": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Статус заказа",
        "operationId": "getOrderStatus",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderStatusRequest"
              },
              "examples": {
                "status": {
                  "summary": "Статус заказа",
                  "value": {
                    "api_key_id": 1,
                    "order_id": 125
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderStatusResponse"
                },
                "examples": {
                  "completed": {
                    "summary": "Выполнен",
                    "value": {
                      "success": true,
                      "order": {
                        "order_id": 125,
                        "partner_order_id": "order-456",
                        "api_user_id": "customer-789",
                        "module": "codes",
                        "nominal_id": 12,
                        "quantity": 1,
                        "stars_amount": null,
                        "months": null,
                        "amount_usd": "0.9800",
                        "currency": "USD",
                        "status": "completed",
                        "created_at": "2026-09-26T12:00:00",
                        "updated_at": "2026-09-26T12:00:05",
                        "completed_at": "2026-09-26T12:00:05",
                        "recipient_data": {},
                        "codes": [
                          {
                            "content": "EXAMPLE-CODE",
                            "number": null,
                            "pin": null
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "404": {
            "description": "Товар, номинал или заказ не найден в указанной области.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Сохранённый статус и результат заказа этой интеграции. success=true означает успешное чтение, а не завершение покупки. Коды возвращаются только для завершённых заказов codes. Этот запрос не запускает повторную покупку."
      }
    },
    "/orders/list": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "История заказов",
        "operationId": "listOrders",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderListRequest"
              },
              "examples": {
                "all": {
                  "summary": "Все заказы",
                  "value": {
                    "api_key_id": 1,
                    "limit": 50,
                    "offset": 0
                  }
                },
                "filtered": {
                  "summary": "С фильтрами",
                  "value": {
                    "api_key_id": 1,
                    "module": "codes",
                    "status": "completed",
                    "api_user_id": "customer-789",
                    "partner_order_id": "order-456",
                    "date_from": "2026-09-01T00:00:00Z",
                    "date_to": "2026-09-30T23:59:59Z",
                    "limit": 50,
                    "offset": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderListResponse"
                },
                "examples": {
                  "orders": {
                    "summary": "История заказов",
                    "value": {
                      "success": true,
                      "orders": [
                        {
                          "order_id": 125,
                          "partner_order_id": "order-456",
                          "api_user_id": "customer-789",
                          "module": "codes",
                          "nominal_id": 12,
                          "quantity": 1,
                          "stars_amount": null,
                          "months": null,
                          "amount_usd": "0.9800",
                          "currency": "USD",
                          "status": "completed",
                          "created_at": "2026-09-26T12:00:00",
                          "updated_at": "2026-09-26T12:00:05",
                          "completed_at": "2026-09-26T12:00:05"
                        }
                      ],
                      "total_count": 1,
                      "limit": 50,
                      "offset": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Заказы интеграции от новых к старым по created_at и ID. Фильтры применяются вместе. api_user_id и partner_order_id сравниваются точно; один partner_order_id может быть у нескольких заказов. Границы дат включительные, в UTC. Коды и данные получателя доступны в /orders/status, не в списке."
      }
    },
    "/recipient/check": {
      "post": {
        "tags": [
          "Recipients"
        ],
        "summary": "Проверить получателя",
        "operationId": "checkRecipient",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/StarsRecipientRequest"
                  },
                  {
                    "$ref": "#/components/schemas/PremiumRecipientRequest"
                  },
                  {
                    "$ref": "#/components/schemas/TopupsRecipientRequest"
                  }
                ],
                "discriminator": {
                  "propertyName": "module",
                  "mapping": {
                    "stars": "#/components/schemas/StarsRecipientRequest",
                    "tg_premium": "#/components/schemas/PremiumRecipientRequest",
                    "topups": "#/components/schemas/TopupsRecipientRequest"
                  }
                },
                "title": "Data"
              },
              "examples": {
                "stars": {
                  "summary": "Telegram Stars",
                  "value": {
                    "api_key_id": 1,
                    "module": "stars",
                    "username": "example_user",
                    "stars_amount": 50
                  }
                },
                "premium": {
                  "summary": "Telegram Premium",
                  "value": {
                    "api_key_id": 1,
                    "module": "tg_premium",
                    "username": "example_user",
                    "months": 3
                  }
                },
                "topups": {
                  "summary": "Пополнения",
                  "value": {
                    "api_key_id": 1,
                    "module": "topups",
                    "nominal_id": 11,
                    "recipient_data": {
                      "playerId": "123456789",
                      "server": "eu"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат операции; учитывайте поля success и status/valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipientCheckResponse"
                },
                "examples": {
                  "valid": {
                    "summary": "Получатель подтверждён",
                    "value": {
                      "success": true,
                      "valid": true,
                      "supported": true,
                      "code": "recipient_valid",
                      "retryable": false,
                      "message": "Recipient verified",
                      "username": "example_user",
                      "display_name": "Example User"
                    }
                  },
                  "invalid": {
                    "summary": "Получатель не найден",
                    "value": {
                      "success": true,
                      "valid": false,
                      "supported": true,
                      "code": "recipient_not_found",
                      "retryable": false,
                      "message": "Recipient not found",
                      "username": null,
                      "display_name": null
                    }
                  },
                  "unsupported": {
                    "summary": "Проверка не поддерживается",
                    "value": {
                      "success": true,
                      "valid": false,
                      "supported": false,
                      "code": "validation_unsupported",
                      "retryable": false,
                      "message": "Recipient verification is not supported for this product",
                      "username": null,
                      "display_name": null
                    }
                  },
                  "unavailable": {
                    "summary": "Проверка недоступна",
                    "value": {
                      "success": false,
                      "valid": false,
                      "supported": null,
                      "code": "recipient_check_unavailable",
                      "retryable": true,
                      "message": "Recipient verification temporarily unavailable",
                      "username": null,
                      "display_name": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Отсутствующий/неверный API-ключ, неверный ID или отключённая интеграция.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Invalid api_key or api_key_id"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации: в том числе лишние поля или неверный вариант модуля.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "429": {
            "description": "Общий лимит интеграции превышен: 100 запросов за 60 секунд по всем публичным маршрутам.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "detail": "Too many requests"
                }
              }
            }
          },
          "500": {
            "description": "Непредвиденная ошибка сервера.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Некорректный ответ при получении каталога или проверке получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Сервис или данные временно недоступны.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Таймаут получения каталога или проверки получателя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "description": "Проверяет Telegram username или получателя пополнения без создания заказа и списания. Для кодов проверка не нужна. HTTP 200 может содержать valid=false или success=false: учитывайте все признаки ответа. Для пополнений validation_unsupported при success=true и supported=false позволяет покупку, но не подтверждает получателя. При покупке проверка выполняется повторно."
      }
    }
  },
  "components": {
    "schemas": {
      "ApiRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id"
        ],
        "title": "ApiRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "BalanceCheckResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "api_key_id": {
            "type": "integer",
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "balance": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "description": "Текущий баланс интеграции в USD, десятичная строка."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          },
          "balance_updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Последнее изменение баланса в UTC; null, если отсутствует. Суффикс часового пояса может отсутствовать."
          }
        },
        "type": "object",
        "required": [
          "success",
          "api_key_id",
          "balance"
        ],
        "title": "BalanceCheckResponse"
      },
      "CatalogDetailsRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "enum": [
              "topups",
              "codes"
            ],
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "item_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID товара из /catalog/list. Не является ID номинала."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "item_id"
        ],
        "title": "CatalogDetailsRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "CatalogDetailsResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          },
          "item": {
            "$ref": "#/components/schemas/CatalogItemDetails",
            "description": "Товар и его активные номиналы."
          }
        },
        "type": "object",
        "required": [
          "success",
          "item"
        ],
        "title": "CatalogDetailsResponse"
      },
      "CatalogItem": {
        "properties": {
          "id": {
            "type": "integer",
            "description": "Идентификатор этого объекта в AdaptGroup."
          },
          "name": {
            "type": "string",
            "description": "Название из каталога, заданное администратором."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Описание из каталога или null."
          },
          "image_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Абсолютная ссылка на картинку товара или null."
          },
          "nominals_count": {
            "type": "integer",
            "description": "Количество активных номиналов в каталоге, не остаток единиц товара."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "image_url",
          "nominals_count"
        ],
        "title": "CatalogItem"
      },
      "CatalogItemDetails": {
        "properties": {
          "id": {
            "type": "integer",
            "description": "Идентификатор этого объекта в AdaptGroup."
          },
          "name": {
            "type": "string",
            "description": "Название из каталога, заданное администратором."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Описание из каталога или null."
          },
          "image_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Абсолютная ссылка на картинку товара или null."
          },
          "nominals_count": {
            "type": "integer",
            "description": "Количество активных номиналов в каталоге, не остаток единиц товара."
          },
          "nominals": {
            "items": {
              "$ref": "#/components/schemas/NominalSummary"
            },
            "type": "array",
            "description": "Номиналы или сроки подписки."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "image_url",
          "nominals_count",
          "nominals"
        ],
        "title": "CatalogItemDetails"
      },
      "CatalogListRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "enum": [
              "topups",
              "codes"
            ],
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "query": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "description": "Поиск по названию товара без учёта регистра. Пустая строка или пробелы означают отсутствие фильтра."
          },
          "limit": {
            "type": "integer",
            "maximum": 200,
            "minimum": 1,
            "default": 50,
            "description": "Размер страницы: 1–200, по умолчанию 50."
          },
          "offset": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 0,
            "default": 0,
            "description": "Сколько записей пропустить; по умолчанию 0."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module"
        ],
        "title": "CatalogListRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "CatalogListResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/CatalogItem"
            },
            "type": "array",
            "description": "Товары по указанным фильтрам."
          },
          "total_count": {
            "type": "integer",
            "description": "Количество записей по фильтрам до пагинации."
          },
          "limit": {
            "type": "integer",
            "description": "Размер страницы: 1–200, по умолчанию 50."
          },
          "offset": {
            "type": "integer",
            "description": "Сколько записей пропустить; по умолчанию 0."
          }
        },
        "type": "object",
        "required": [
          "success",
          "items",
          "total_count",
          "limit",
          "offset"
        ],
        "title": "CatalogListResponse"
      },
      "CatalogModule": {
        "properties": {
          "items_count": {
            "type": "integer",
            "description": "Количество активных товаров в каталоге."
          },
          "nominals_count": {
            "type": "integer",
            "description": "Количество активных номиналов в каталоге, не остаток единиц товара."
          }
        },
        "type": "object",
        "required": [
          "items_count",
          "nominals_count"
        ],
        "title": "CatalogModule"
      },
      "CatalogNominal": {
        "properties": {
          "id": {
            "type": "integer",
            "description": "Идентификатор этого объекта в AdaptGroup."
          },
          "name": {
            "type": "string",
            "description": "Название из каталога, заданное администратором."
          },
          "price_usd": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ваша API-цена одной единицы номинала в USD с наценкой платформы. Null, если цена недоступна."
          },
          "available": {
            "type": "boolean",
            "description": "Доступен ли номинал сейчас. При покупке доступность проверяется повторно."
          },
          "item_id": {
            "type": "integer",
            "description": "ID товара из /catalog/list. Не является ID номинала."
          },
          "input_fields": {
            "items": {
              "$ref": "#/components/schemas/RecipientField"
            },
            "type": "array",
            "description": "Какие данные собрать для этого номинала. Для кодов массив пустой. Получайте актуальные поля перед проверкой или покупкой."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "price_usd",
          "available",
          "item_id",
          "input_fields"
        ],
        "title": "CatalogNominal"
      },
      "CatalogNominalRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "enum": [
              "topups",
              "codes"
            ],
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "item_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID товара из /catalog/list. Не является ID номинала."
          },
          "nominal_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "item_id",
          "nominal_id"
        ],
        "title": "CatalogNominalRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "CatalogNominalResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          },
          "nominal": {
            "$ref": "#/components/schemas/CatalogNominal",
            "description": "Выбранный номинал с ценой и полями получателя."
          }
        },
        "type": "object",
        "required": [
          "success",
          "nominal"
        ],
        "title": "CatalogNominalResponse"
      },
      "CatalogQuoteRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "enum": [
              "topups",
              "codes"
            ],
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "nominal_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          },
          "quantity": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 1,
            "default": 1,
            "description": "Количество единиц номинала. Для пополнений и кодов по умолчанию 1. Фактический лимит зависит от номинала и остатка. У заказов Stars/Premium quantity=1; их значение передаётся в stars_amount/months."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "nominal_id"
        ],
        "title": "CatalogQuoteRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "CodesCreateRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "codes",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "nominal_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          },
          "quantity": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 1,
            "default": 1,
            "description": "Количество единиц номинала. Для пополнений и кодов по умолчанию 1. Фактический лимит зависит от номинала и остатка. У заказов Stars/Premium quantity=1; их значение передаётся в stars_amount/months."
          },
          "api_user_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "\\S",
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1,
                "pattern": "\\S"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "nominal_id",
          "api_user_id"
        ],
        "title": "CodesCreateRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "ComplianceInfo": {
        "properties": {
          "paymentMethod": {
            "type": "string",
            "enum": [
              "credit_card",
              "debit_card",
              "digital_wallet",
              "bank_transfer",
              "crypto",
              "other"
            ],
            "description": "Способ оплаты клиента."
          },
          "playerIp": {
            "type": "string",
            "format": "ipvanyaddress",
            "description": "Фактический IPv4 или IPv6 клиента. Не подставляйте адрес своего сервера."
          },
          "sellerName": {
            "type": "string",
            "maxLength": 85,
            "minLength": 1,
            "pattern": "\\S",
            "description": "Название продавца, 1–85 символов; строка из пробелов не допускается."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "paymentMethod",
          "playerIp",
          "sellerName"
        ],
        "title": "ComplianceInfo"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "description": "Подробности ошибки. При валидации возвращается массив, у большинства остальных ошибок — строка."
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "Modules": {
        "properties": {
          "stars": {
            "$ref": "#/components/schemas/StarsModule",
            "description": "Telegram Stars."
          },
          "tg_premium": {
            "$ref": "#/components/schemas/PremiumModule",
            "description": "Telegram Premium."
          },
          "topups": {
            "$ref": "#/components/schemas/CatalogModule",
            "description": "Пополнения игр и аккаунтов."
          },
          "codes": {
            "$ref": "#/components/schemas/CatalogModule",
            "description": "Цифровые коды."
          }
        },
        "type": "object",
        "required": [
          "stars",
          "tg_premium",
          "topups",
          "codes"
        ],
        "title": "Modules"
      },
      "ModulesResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          },
          "modules": {
            "$ref": "#/components/schemas/Modules",
            "description": "Четыре поддерживаемых модуля: stars, tg_premium, topups и codes."
          }
        },
        "type": "object",
        "required": [
          "success",
          "modules"
        ],
        "title": "ModulesResponse"
      },
      "NominalSummary": {
        "properties": {
          "id": {
            "type": "integer",
            "description": "Идентификатор этого объекта в AdaptGroup."
          },
          "name": {
            "type": "string",
            "description": "Название из каталога, заданное администратором."
          },
          "price_usd": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ваша API-цена одной единицы номинала в USD с наценкой платформы. Null, если цена недоступна."
          },
          "available": {
            "type": "boolean",
            "description": "Доступен ли номинал сейчас. При покупке доступность проверяется повторно."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "price_usd",
          "available"
        ],
        "title": "NominalSummary"
      },
      "OrderCode": {
        "properties": {
          "content": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Содержимое выданного кода при наличии."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Номер выданной карты при наличии."
          },
          "pin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Выданный PIN при наличии."
          }
        },
        "type": "object",
        "title": "OrderCode"
      },
      "OrderCreateResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "order_id": {
            "type": "integer",
            "description": "ID заказа AdaptGroup. Используйте для получения результата без повторной покупки."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "status": {
            "type": "string",
            "description": "Статус заказа. Текущий процесс использует review, processing, completed и refunded; фильтр истории также принимает pending и failed. Подробнее на странице «Процесс покупки»."
          },
          "amount_usd": {
            "type": "string",
            "description": "Итоговая сумма в USD, десятичная строка. Расчёт предварительный; в заказе указана фактически списанная сумма."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          }
        },
        "type": "object",
        "required": [
          "success",
          "order_id",
          "partner_order_id",
          "status",
          "amount_usd"
        ],
        "title": "OrderCreateResponse"
      },
      "OrderDetails": {
        "properties": {
          "order_id": {
            "type": "integer",
            "description": "ID заказа AdaptGroup. Используйте для получения результата без повторной покупки."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "api_user_id": {
            "type": "string",
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "module": {
            "type": "string",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "nominal_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          },
          "quantity": {
            "type": "integer",
            "description": "Количество единиц номинала. Для пополнений и кодов по умолчанию 1. Фактический лимит зависит от номинала и остатка. У заказов Stars/Premium quantity=1; их значение передаётся в stars_amount/months."
          },
          "stars_amount": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Количество Telegram Stars: целое число от 50 до 100000."
          },
          "months": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Срок Telegram Premium: 3, 6 или 12 месяцев."
          },
          "amount_usd": {
            "type": "string",
            "description": "Итоговая сумма в USD, десятичная строка. Расчёт предварительный; в заказе указана фактически списанная сумма."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          },
          "status": {
            "type": "string",
            "description": "Статус заказа. Текущий процесс использует review, processing, completed и refunded; фильтр истории также принимает pending и failed. Подробнее на странице «Процесс покупки»."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Дата создания в UTC. В ответе может отсутствовать суффикс часового пояса."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Последнее изменение в UTC или null."
          },
          "completed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Дата завершения или возврата в UTC или null."
          },
          "recipient_data": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "description": "Строковые пары ключ/значение по input_fields выбранного номинала. Передавайте option.key, а не подпись. Сохраняйте написание и регистр ключей. Для кодов поле не передаётся."
          },
          "codes": {
            "items": {
              "$ref": "#/components/schemas/OrderCode"
            },
            "type": "array",
            "description": "Выданные коды только для завершённого заказа codes; иначе пустой массив. У кода могут быть content, number и/или pin."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "partner_order_id",
          "api_user_id",
          "module",
          "nominal_id",
          "quantity",
          "stars_amount",
          "months",
          "amount_usd",
          "status",
          "created_at",
          "updated_at",
          "completed_at",
          "recipient_data",
          "codes"
        ],
        "title": "OrderDetails"
      },
      "OrderListRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 20,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "pending",
                  "processing",
                  "completed",
                  "failed",
                  "refunded",
                  "review"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Статус заказа. Текущий процесс использует review, processing, completed и refunded; фильтр истории также принимает pending и failed. Подробнее на странице «Процесс покупки»."
          },
          "api_user_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "date_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Включительная нижняя граница даты создания заказа. ISO 8601; смещение приводится к UTC. Значение без смещения считается UTC."
          },
          "date_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Включительная верхняя граница даты создания заказа. Не может быть раньше date_from."
          },
          "limit": {
            "type": "integer",
            "maximum": 200,
            "minimum": 1,
            "default": 50,
            "description": "Размер страницы: 1–200, по умолчанию 50."
          },
          "offset": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 0,
            "default": 0,
            "description": "Сколько записей пропустить; по умолчанию 0."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id"
        ],
        "title": "OrderListRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "OrderListResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "orders": {
            "items": {
              "$ref": "#/components/schemas/OrderSummary"
            },
            "type": "array",
            "description": "Заказы этой интеграции от новых к старым. Выданных кодов здесь нет; используйте /orders/status."
          },
          "total_count": {
            "type": "integer",
            "description": "Количество записей по фильтрам до пагинации."
          },
          "limit": {
            "type": "integer",
            "description": "Размер страницы: 1–200, по умолчанию 50."
          },
          "offset": {
            "type": "integer",
            "description": "Сколько записей пропустить; по умолчанию 0."
          }
        },
        "type": "object",
        "required": [
          "success",
          "orders",
          "total_count",
          "limit",
          "offset"
        ],
        "title": "OrderListResponse"
      },
      "OrderQuoteResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "module": {
            "type": "string",
            "enum": [
              "stars",
              "tg_premium",
              "topups",
              "codes"
            ],
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "amount_usd": {
            "type": "string",
            "description": "Итоговая сумма в USD, десятичная строка. Расчёт предварительный; в заказе указана фактически списанная сумма."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          }
        },
        "type": "object",
        "required": [
          "success",
          "module",
          "amount_usd"
        ],
        "title": "OrderQuoteResponse"
      },
      "OrderStatusRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "order_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID заказа AdaptGroup. Используйте для получения результата без повторной покупки."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "order_id"
        ],
        "title": "OrderStatusRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "OrderStatusResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "order": {
            "$ref": "#/components/schemas/OrderDetails",
            "description": "Сохранённый заказ и его результат в этой интеграции."
          }
        },
        "type": "object",
        "required": [
          "success",
          "order"
        ],
        "title": "OrderStatusResponse"
      },
      "OrderSummary": {
        "properties": {
          "order_id": {
            "type": "integer",
            "description": "ID заказа AdaptGroup. Используйте для получения результата без повторной покупки."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "api_user_id": {
            "type": "string",
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "module": {
            "type": "string",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "nominal_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          },
          "quantity": {
            "type": "integer",
            "description": "Количество единиц номинала. Для пополнений и кодов по умолчанию 1. Фактический лимит зависит от номинала и остатка. У заказов Stars/Premium quantity=1; их значение передаётся в stars_amount/months."
          },
          "stars_amount": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Количество Telegram Stars: целое число от 50 до 100000."
          },
          "months": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Срок Telegram Premium: 3, 6 или 12 месяцев."
          },
          "amount_usd": {
            "type": "string",
            "description": "Итоговая сумма в USD, десятичная строка. Расчёт предварительный; в заказе указана фактически списанная сумма."
          },
          "currency": {
            "type": "string",
            "const": "USD",
            "default": "USD",
            "description": "Все цены и балансы в USD."
          },
          "status": {
            "type": "string",
            "description": "Статус заказа. Текущий процесс использует review, processing, completed и refunded; фильтр истории также принимает pending и failed. Подробнее на странице «Процесс покупки»."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Дата создания в UTC. В ответе может отсутствовать суффикс часового пояса."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Последнее изменение в UTC или null."
          },
          "completed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "Дата завершения или возврата в UTC или null."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "partner_order_id",
          "api_user_id",
          "module",
          "nominal_id",
          "quantity",
          "stars_amount",
          "months",
          "amount_usd",
          "status",
          "created_at",
          "updated_at",
          "completed_at"
        ],
        "title": "OrderSummary"
      },
      "PremiumCreateRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "tg_premium",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "months": {
            "type": "integer",
            "enum": [
              3,
              6,
              12
            ],
            "description": "Срок Telegram Premium: 3, 6 или 12 месяцев."
          },
          "api_user_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "\\S",
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1,
                "pattern": "\\S"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "username": {
            "type": "string",
            "minLength": 1,
            "description": "Публичный Telegram username получателя; можно с @ в начале. Числовой Telegram ID не подходит."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "months",
          "api_user_id",
          "username"
        ],
        "title": "PremiumCreateRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "PremiumModule": {
        "properties": {
          "nominals": {
            "items": {
              "$ref": "#/components/schemas/PremiumNominal"
            },
            "type": "array",
            "description": "Номиналы или сроки подписки."
          }
        },
        "type": "object",
        "required": [
          "nominals"
        ],
        "title": "PremiumModule"
      },
      "PremiumNominal": {
        "properties": {
          "months": {
            "type": "integer",
            "enum": [
              3,
              6,
              12
            ],
            "description": "Срок Telegram Premium: 3, 6 или 12 месяцев."
          },
          "price_usd": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ваша API-цена одной единицы номинала в USD с наценкой платформы. Null, если цена недоступна."
          }
        },
        "type": "object",
        "required": [
          "months",
          "price_usd"
        ],
        "title": "PremiumNominal"
      },
      "PremiumQuoteRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "tg_premium",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "months": {
            "type": "integer",
            "enum": [
              3,
              6,
              12
            ],
            "description": "Срок Telegram Premium: 3, 6 или 12 месяцев."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "months"
        ],
        "title": "PremiumQuoteRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "PremiumRecipientRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "tg_premium",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "username": {
            "type": "string",
            "minLength": 1,
            "description": "Публичный Telegram username получателя; можно с @ в начале. Числовой Telegram ID не подходит."
          },
          "months": {
            "type": "integer",
            "enum": [
              3,
              6,
              12
            ],
            "description": "Срок Telegram Premium: 3, 6 или 12 месяцев."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "username",
          "months"
        ],
        "title": "PremiumRecipientRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "RecipientCheckResponse": {
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Результат операции. Смотрите описание маршрута: HTTP 200 не всегда означает завершение покупки."
          },
          "valid": {
            "type": "boolean",
            "description": "Прошёл ли получатель проверку. Проверяйте вместе с success, supported и code."
          },
          "supported": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Поддерживается ли проверка получателя. Для пополнений false с code=validation_unsupported не означает, что получатель неверный."
          },
          "code": {
            "type": "string",
            "description": "Машинный код результата проверки. См. примеры ответа и «Процесс покупки»."
          },
          "retryable": {
            "type": "boolean",
            "description": "Можно ли повторить проверку получателя. Этот флаг не разрешает повторять /orders/create."
          },
          "message": {
            "type": "string",
            "description": "Текст результата для человека. В логике приложения используйте code, а не message."
          },
          "username": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Нормализованный Telegram username при наличии, иначе null."
          },
          "display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Имя получателя при наличии, иначе null."
          }
        },
        "type": "object",
        "required": [
          "success",
          "valid",
          "code",
          "retryable",
          "message"
        ],
        "title": "RecipientCheckResponse"
      },
      "RecipientField": {
        "properties": {
          "key": {
            "type": "string",
            "description": "Ключ поля или варианта для recipient_data; сохраняйте регистр."
          },
          "label": {
            "type": "string",
            "description": "Подпись для отображения. Не подменяйте ей ключ."
          },
          "type": {
            "type": "string",
            "enum": [
              "input",
              "select",
              "radio",
              "check"
            ],
            "description": "Тип элемента: input, select, radio или check. Все значения recipient_data — строки; для вариантов передавайте один option.key, не массив."
          },
          "required": {
            "type": "boolean",
            "description": "Обязательно ли заполнение поля получателя."
          },
          "options": {
            "items": {
              "$ref": "#/components/schemas/RecipientOption"
            },
            "type": "array",
            "description": "Доступные варианты. Передавайте ключ выбранного варианта строкой."
          }
        },
        "type": "object",
        "required": [
          "key",
          "label",
          "type",
          "required",
          "options"
        ],
        "title": "RecipientField"
      },
      "RecipientOption": {
        "properties": {
          "key": {
            "type": "string",
            "description": "Ключ поля или варианта для recipient_data; сохраняйте регистр."
          },
          "label": {
            "type": "string",
            "description": "Подпись для отображения. Не подменяйте ей ключ."
          }
        },
        "type": "object",
        "required": [
          "key",
          "label"
        ],
        "title": "RecipientOption"
      },
      "StarsCreateRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "stars",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "stars_amount": {
            "type": "integer",
            "maximum": 100000,
            "minimum": 50,
            "description": "Количество Telegram Stars: целое число от 50 до 100000."
          },
          "api_user_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "\\S",
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1,
                "pattern": "\\S"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "username": {
            "type": "string",
            "minLength": 1,
            "description": "Публичный Telegram username получателя; можно с @ в начале. Числовой Telegram ID не подходит."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "stars_amount",
          "api_user_id",
          "username"
        ],
        "title": "StarsCreateRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "StarsModule": {
        "properties": {
          "price_per_star_usd": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ваша API-цена одной Telegram Star в USD. Null, если корректная цена не настроена."
          }
        },
        "type": "object",
        "required": [
          "price_per_star_usd"
        ],
        "title": "StarsModule"
      },
      "StarsQuoteRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "stars",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "stars_amount": {
            "type": "integer",
            "maximum": 100000,
            "minimum": 50,
            "description": "Количество Telegram Stars: целое число от 50 до 100000."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "stars_amount"
        ],
        "title": "StarsQuoteRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "StarsRecipientRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "stars",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "username": {
            "type": "string",
            "minLength": 1,
            "description": "Публичный Telegram username получателя; можно с @ в начале. Числовой Telegram ID не подходит."
          },
          "stars_amount": {
            "type": "integer",
            "maximum": 100000,
            "minimum": 50,
            "description": "Количество Telegram Stars: целое число от 50 до 100000."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "username",
          "stars_amount"
        ],
        "title": "StarsRecipientRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "TopupsCreateRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "topups",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "nominal_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          },
          "quantity": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 1,
            "default": 1,
            "description": "Количество единиц номинала. Для пополнений и кодов по умолчанию 1. Фактический лимит зависит от номинала и остатка. У заказов Stars/Premium quantity=1; их значение передаётся в stars_amount/months."
          },
          "api_user_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "\\S",
            "description": "ID клиента в вашей системе: непустая строка 1–255 символов. Это не обязательно Telegram ID."
          },
          "partner_order_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255,
                "minLength": 1,
                "pattern": "\\S"
              },
              {
                "type": "null"
              }
            ],
            "description": "Необязательный ID заказа в вашей системе. Возвращается в ответе и используется для точного фильтра истории. Не уникален и не предотвращает повторные покупки."
          },
          "recipient_data": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "description": "Строковые пары ключ/значение по input_fields выбранного номинала. Передавайте option.key, а не подпись. Сохраняйте написание и регистр ключей. Для кодов поле не передаётся."
          },
          "compliance_info": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ComplianceInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Дополнительные сведения о платеже для номиналов, которые их принимают. По умолчанию не нужны; не передавайте для остальных номиналов. Если номинал не поддерживает поле, вернётся HTTP 400. Не заменяет recipient_data."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "nominal_id",
          "api_user_id",
          "recipient_data"
        ],
        "title": "TopupsCreateRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "TopupsRecipientRequest": {
        "properties": {
          "api_key_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID интеграции из дашборда. Передавайте в JSON каждого запроса."
          },
          "module": {
            "type": "string",
            "const": "topups",
            "description": "Ключ модуля. Выберите соответствующий вариант запроса; поля других модулей передавать нельзя."
          },
          "nominal_id": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": 1,
            "description": "ID номинала AdaptGroup, а не товара. Берётся из /catalog/details или /catalog/nominal."
          },
          "recipient_data": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "description": "Строковые пары ключ/значение по input_fields выбранного номинала. Передавайте option.key, а не подпись. Сохраняйте написание и регистр ключей. Для кодов поле не передаётся."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "api_key_id",
          "module",
          "nominal_id",
          "recipient_data"
        ],
        "title": "TopupsRecipientRequest",
        "description": "JSON запроса. Неизвестные поля запрещены."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "description": "Расположение поля с ошибкой."
          },
          "msg": {
            "type": "string",
            "description": "Сообщение ошибки валидации."
          },
          "type": {
            "type": "string",
            "description": "Машинный тип ошибки валидации."
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "detail": {
            "type": "string",
            "description": "Описание ошибки."
          }
        }
      },
      "OrderCreationUnavailable": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "detail": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "required": [
                  "message",
                  "order_id",
                  "partner_order_id"
                ],
                "properties": {
                  "message": {
                    "type": "string"
                  },
                  "order_id": {
                    "type": "integer"
                  },
                  "partner_order_id": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "API-ключ из настроек интеграции в дашборде. Не размещайте его в браузерном коде."
      }
    }
  },
  "servers": [
    {
      "url": "https://shop-api.adaptgroup.pro",
      "description": "Shop API"
    }
  ],
  "tags": [
    {
      "name": "Catalog",
      "x-displayName": "Каталог",
      "description": "Модули, товары, цены номиналов и поля получателя."
    },
    {
      "name": "Recipients",
      "x-displayName": "Получатели",
      "description": "Проверка получателя без покупки."
    },
    {
      "name": "Orders",
      "x-displayName": "Заказы",
      "description": "Расчёт цены, покупка и результаты заказов."
    },
    {
      "name": "Balance",
      "x-displayName": "Баланс",
      "description": "Текущий баланс интеграции."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}
