{
  "openapi": "3.1.0",
  "info": {
    "title": "OVE Crypto Gateway API",
    "version": "1.0.0",
    "description": "OVE multi-merchant cryptocurrency payments, checkout and operator API."
  },
  "servers": [
    {
      "url": "https://cr.ove.rs"
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "Сервис"
        ],
        "summary": "Состояние Gateway",
        "description": "Состояние Gateway. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_health",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        }
      }
    },
    "/v1/assets": {
      "get": {
        "tags": [
          "Сервис"
        ],
        "summary": "Доступные активы",
        "description": "Возвращает только пары asset/network, для которых wallet seed готов к работе.",
        "operationId": "get_v1_assets",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        }
      }
    },
    "/v1/invoices": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "Список invoices",
        "description": "Создает invoice или возвращает историю с cursor pagination, в зависимости от HTTP-метода.",
        "operationId": "get_v1_invoices",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Создание invoice",
        "description": "Создает invoice или возвращает историю с cursor pagination, в зависимости от HTTP-метода.",
        "operationId": "post_v1_invoices",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "merchant_order_id": "order-123",
                "asset": "USDT",
                "network": "tron",
                "amount_atomic": "25000000",
                "expires_in_seconds": 1800,
                "description": "Order 123",
                "success_url": "https://merchant.example/orders/123",
                "metadata": {
                  "customer": "42"
                }
              }
            }
          }
        }
      }
    },
    "/v1/invoices/{invoice_id}": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "Получение invoice",
        "description": "Получение invoice. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_v1_invoices_invoice_id",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/withdrawals": {
      "get": {
        "tags": [
          "Withdrawals"
        ],
        "summary": "Список withdrawals",
        "description": "Создает withdrawal или возвращает историю. Для token assets разрешен только fee_mode=additional.",
        "operationId": "get_v1_withdrawals",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "Withdrawals"
        ],
        "summary": "Создание withdrawal",
        "description": "Создает withdrawal или возвращает историю. Для token assets разрешен только fee_mode=additional.",
        "operationId": "post_v1_withdrawals",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "asset": "USDT",
                "network": "tron",
                "amount_atomic": "10000000",
                "address": "T...",
                "fee_mode": "additional",
                "metadata": {
                  "payout": "p-123"
                }
              }
            }
          }
        }
      }
    },
    "/v1/withdrawals/{withdrawal_id}": {
      "get": {
        "tags": [
          "Withdrawals"
        ],
        "summary": "Получение withdrawal",
        "description": "Получение withdrawal. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_v1_withdrawals_withdrawal_id",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "withdrawal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/balances": {
      "get": {
        "tags": [
          "Баланс"
        ],
        "summary": "Merchant-балансы",
        "description": "Merchant-балансы. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_v1_balances",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/api-keys": {
      "get": {
        "tags": [
          "Ключи"
        ],
        "summary": "Список API-ключей",
        "description": "Список API-ключей. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_v1_api_keys",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "merchantHmac": []
          }
        ],
        "parameters": [
          {
            "name": "X-Api-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-Api-Nonce",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Api-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/v1/status": {
      "get": {
        "tags": [
          "Operator"
        ],
        "summary": "Операторский статус",
        "description": "Операторский статус. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_admin_v1_status",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ]
      }
    },
    "/admin/v1/callbacks": {
      "get": {
        "tags": [
          "Operator"
        ],
        "summary": "Инциденты callbacks",
        "description": "Инциденты callbacks. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_admin_v1_callbacks",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ]
      }
    },
    "/admin/v1/consolidations": {
      "get": {
        "tags": [
          "Operator"
        ],
        "summary": "Инциденты консолидации",
        "description": "Инциденты консолидации. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "get_admin_v1_consolidations",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ]
      }
    },
    "/admin/v1/callbacks/{callback_id}/retry": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Повтор callback",
        "description": "Повтор callback. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_callbacks_callback_id_retry",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "parameters": [
          {
            "name": "callback_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/v1/merchants": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Создание merchant",
        "description": "Создание merchant. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_merchants",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "name": "Example shop",
                "callback_url": "https://merchant.example/payments",
                "callback_hosts": [
                  "merchant.example"
                ]
              }
            }
          }
        }
      }
    },
    "/admin/v1/fee-policies": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Глобальная fee policy",
        "description": "Глобальная fee policy. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_fee_policies",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "asset": "USDT",
                "network": "tron",
                "platform_fee_basis_points": 500,
                "platform_fee_cap_atomic": "10000000"
              }
            }
          }
        }
      }
    },
    "/admin/v1/merchants/{merchant_id}/api-keys": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Выпуск merchant API-ключа",
        "description": "Выпуск merchant API-ключа. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_merchants_merchant_id_api_keys",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/v1/merchants/{merchant_id}/api-keys/{api_key_id}": {
      "delete": {
        "tags": [
          "Operator"
        ],
        "summary": "Отзыв merchant API-ключа",
        "description": "Отзыв merchant API-ключа. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "delete_admin_v1_merchants_merchant_id_api_keys_api_key_id",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api_key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/v1/merchants/{merchant_id}/policies": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Merchant policy",
        "description": "Merchant policy. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_merchants_merchant_id_policies",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/v1/withdrawals/{withdrawal_id}/resolve": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Решение manual review",
        "description": "Решение manual review. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_withdrawals_withdrawal_id_resolve",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "parameters": [
          {
            "name": "withdrawal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/v1/consolidations/{consolidation_id}/retry": {
      "post": {
        "tags": [
          "Operator"
        ],
        "summary": "Повтор консолидации",
        "description": "Повтор консолидации. Возвращает JSON-ответ или стандартную JSON-ошибку.",
        "operationId": "post_admin_v1_consolidations_consolidation_id_retry",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "security": [
          {
            "adminBearer": []
          }
        ],
        "parameters": [
          {
            "name": "consolidation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/pay/{token}": {
      "get": {
        "tags": [
          "Checkout"
        ],
        "summary": "Hosted checkout",
        "description": "Публичная HTML-страница оплаты с QR, серверно-синхронизированным таймером и live status.",
        "operationId": "get_pay_token",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/pay/{token}/status": {
      "get": {
        "tags": [
          "Checkout"
        ],
        "summary": "Статус hosted checkout",
        "description": "JSON-состояние checkout для polling; включает серверное время и срок действия.",
        "operationId": "get_pay_token_status",
        "responses": {
          "200": {
            "description": "Успешный ответ"
          },
          "400": {
            "description": "Ошибка запроса"
          },
          "401": {
            "description": "Ошибка авторизации"
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "merchantHmac": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "Дополнительно обязательна HMAC-SHA256 подпись запроса."
      },
      "adminBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Operator admin token"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
