{
  "openapi": "3.1.0",
  "info": {
    "title": "AdaptGroup Pay API",
    "version": "1.0.0",
    "description": "API for accepting payments in your projects. Supports SBP and cryptocurrency.\n\n**Base URL:** `https://api-pay.adaptgroup.app`\n\n**Authentication:** pass your API key in the `X-Api-Key` header and integration ID in the request body.\n\n**Rate limit:** 100 requests per 60 seconds per `api_key_id`. Returns `429 Too Many Requests` when exceeded.\n\n[📥 Download OpenAPI spec](/openapi/pay.json)",
    "contact": {
      "name": "AdaptGroup Support",
      "url": "https://t.me/adapt_support",
      "email": "support@adaptgroup.org"
    }
  },
  "servers": [
    {
      "url": "https://api-pay.adaptgroup.app",
      "description": "Production"
    }
  ],
  "security": [
    { "ApiKeyAuth": [] }
  ],
  "tags": [
    {
      "name": "Payments",
      "description": "Create payments and retrieve their status"
    },
    {
      "name": "Reference",
      "description": "Exchange rates and available payment methods"
    }
  ],
  "paths": {
    "/invoice/create": {
      "post": {
        "tags": ["Payments"],
        "summary": "Create payment",
        "description": "Creates a new payment and returns a payment URL.\n\n**Payment expiration:**\n- SBP — 15 minutes\n- Crypto — 30 minutes",
        "operationId": "createInvoice",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceRequest"
              },
              "examples": {
                "sbp_rub": {
                  "summary": "SBP in RUB",
                  "value": {
                    "api_key_id": 1,
                    "amount": 500,
                    "currency": "RUB",
                    "payment_method": "sbp",
                    "external_user_id": "user_123",
                    "redirect_url": "https://example.com/success"
                  }
                },
                "crypto_usd": {
                  "summary": "Crypto in USD",
                  "value": {
                    "api_key_id": 1,
                    "amount": 10.00,
                    "currency": "USD",
                    "payment_method": "crypto"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateInvoiceResponse"
                },
                "example": {
                  "success": true,
                  "payment_id": "550e8400-e29b-41d4-a716-446655440000",
                  "payment_url": "https://pay.example.com/invoice/550e8400",
                  "amount": 500,
                  "currency": "RUB",
                  "amount_usd": 5.4321,
                  "expires_at": "2026-05-02T12:15:00"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "examples": {
                  "invalid_method": {
                    "summary": "Invalid payment method",
                    "value": { "detail": "Invalid payment method" }
                  },
                  "amount_out_of_range": {
                    "summary": "Amount out of range",
                    "value": { "detail": "Amount must be between 0.15 and 1000 USD" }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Invalid api_key or api_key_id" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Too many requests" }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Service temporarily unavailable" }
              }
            }
          }
        }
      }
    },
    "/invoice/status": {
      "post": {
        "tags": ["Payments"],
        "summary": "Get payment status",
        "description": "Returns the current status of a payment by its `payment_id`.\n\n**Payment statuses:**\n- `pending` — awaiting payment\n- `success` — paid\n- `expired` — payment expired\n- `cancelled` — cancelled\n- `refunded` — refunded",
        "operationId": "getInvoiceStatus",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetPaymentStatusRequest"
              },
              "example": {
                "api_key_id": 1,
                "payment_id": "550e8400-e29b-41d4-a716-446655440000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPaymentStatusResponse"
                },
                "examples": {
                  "pending": {
                    "summary": "Awaiting payment",
                    "value": {
                      "success": true,
                      "payment_id": "550e8400-e29b-41d4-a716-446655440000",
                      "status": "pending",
                      "amount": "500",
                      "currency": "RUB",
                      "amount_usd": "5.4321",
                      "payment_method": "sbp",
                      "payment_url": "https://pay.example.com/invoice/550e8400",
                      "expires_at": "2026-05-02T12:15:00",
                      "created_at": "2026-05-02T12:00:00",
                      "completed_at": null,
                      "refunded_at": null
                    }
                  },
                  "success": {
                    "summary": "Paid",
                    "value": {
                      "success": true,
                      "payment_id": "550e8400-e29b-41d4-a716-446655440000",
                      "status": "success",
                      "amount": "500",
                      "currency": "RUB",
                      "amount_usd": "5.4321",
                      "payment_method": "sbp",
                      "payment_url": null,
                      "expires_at": "2026-05-02T12:15:00",
                      "created_at": "2026-05-02T12:00:00",
                      "completed_at": "2026-05-02T12:05:00",
                      "refunded_at": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Invalid api_key or api_key_id" }
              }
            }
          },
          "403": {
            "description": "Payment belongs to another integration",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Access denied" }
              }
            }
          },
          "404": {
            "description": "Payment not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Payment not found" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Too many requests" }
              }
            }
          }
        }
      }
    },
    "/reference/rates": {
      "post": {
        "tags": ["Reference"],
        "summary": "Exchange rates",
        "description": "Returns the current RUB to USD exchange rate. Use this to convert amounts before creating a payment.",
        "operationId": "getExchangeRates",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferenceRequest"
              },
              "example": {
                "api_key_id": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current exchange rates",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ExchangeRatesResponse" },
                "example": {
                  "success": true,
                  "rates": { "RUB": 91.45 }
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Invalid api_key or api_key_id" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Too many requests" }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Service temporarily unavailable" }
              }
            }
          }
        }
      }
    },
    "/reference/methods": {
      "post": {
        "tags": ["Reference"],
        "summary": "Payment methods",
        "description": "Returns a list of available payment methods with commissions and limits for your integration.",
        "operationId": "getPaymentMethods",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferenceRequest"
              },
              "example": {
                "api_key_id": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "List of payment methods",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentMethodsResponse" },
                "example": {
                  "success": true,
                  "methods": [
                    {
                      "method": "sbp",
                      "commission": "9.00",
                      "min_usd": 0.15,
                      "max_usd": 1000.0
                    },
                    {
                      "method": "crypto",
                      "commission": "5.00",
                      "min_usd": 0.15,
                      "max_usd": 1000.0
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Invalid api_key or api_key_id" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "detail": "Too many requests" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "Your integration API key. Obtained from the dashboard."
      }
    },
    "schemas": {
      "CreateInvoiceRequest": {
        "type": "object",
        "required": ["api_key_id", "amount", "currency", "payment_method"],
        "properties": {
          "api_key_id": {
            "type": "integer",
            "description": "Integration ID",
            "example": 1
          },
          "amount": {
            "type": "number",
            "description": "Payment amount. Min: 0.15 USD, max: 1000 USD",
            "example": 500
          },
          "currency": {
            "type": "string",
            "enum": ["RUB", "USD"],
            "description": "Amount currency. If `RUB`, converted to USD at the current rate",
            "example": "RUB"
          },
          "payment_method": {
            "type": "string",
            "enum": ["sbp", "crypto"],
            "description": "Payment method. `sbp` — SBP via QR code, `crypto` — cryptocurrency (coin selected by payer)",
            "example": "sbp"
          },
          "external_user_id": {
            "type": "string",
            "description": "Your system's user ID. Optional, used for analytics",
            "example": "user_123",
            "nullable": true
          },
          "redirect_url": {
            "type": "string",
            "description": "URL to redirect after payment. If not provided, uses `project_url` from integration settings",
            "example": "https://example.com/success",
            "nullable": true
          }
        }
      },
      "CreateInvoiceResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique payment ID",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          },
          "payment_url": {
            "type": "string",
            "description": "Payment page URL",
            "example": "https://pay.example.com/invoice/550e8400"
          },
          "amount": {
            "type": "number",
            "description": "Amount in the specified currency",
            "example": 500
          },
          "currency": { "type": "string", "example": "RUB" },
          "amount_usd": {
            "type": "number",
            "description": "Amount in USD",
            "example": 5.4321
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Payment expiration time (UTC)",
            "example": "2026-05-02T12:15:00"
          }
        }
      },
      "GetPaymentStatusRequest": {
        "type": "object",
        "required": ["api_key_id", "payment_id"],
        "properties": {
          "api_key_id": {
            "type": "integer",
            "example": 1
          },
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "description": "Payment ID returned when the payment was created",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          }
        }
      },
      "GetPaymentStatusResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "payment_id": { "type": "string", "format": "uuid" },
          "status": {
            "type": "string",
            "enum": ["pending", "success", "expired", "cancelled", "refunded"],
            "description": "Current payment status",
            "example": "success"
          },
          "amount": { "type": "string", "example": "500" },
          "currency": { "type": "string", "example": "RUB" },
          "amount_usd": { "type": "string", "example": "5.4321" },
          "payment_method": {
            "type": "string",
            "enum": ["sbp", "crypto"],
            "example": "sbp"
          },
          "payment_url": {
            "type": "string",
            "nullable": true,
            "description": "Payment URL. Only available for `pending` status"
          },
          "expires_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "completed_at": { "type": "string", "format": "date-time", "nullable": true },
          "refunded_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "ReferenceRequest": {
        "type": "object",
        "required": ["api_key_id"],
        "properties": {
          "api_key_id": {
            "type": "integer",
            "example": 1
          }
        }
      },
      "ExchangeRatesResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "rates": {
            "type": "object",
            "properties": {
              "RUB": {
                "type": "number",
                "description": "Number of rubles per 1 USD",
                "example": 91.45
              }
            }
          }
        }
      },
      "PaymentMethodsResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "methods": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "method": {
                  "type": "string",
                  "enum": ["sbp", "crypto"],
                  "example": "sbp"
                },
                "commission": {
                  "type": "string",
                  "description": "Commission percentage",
                  "example": "9.00"
                },
                "min_usd": {
                  "type": "number",
                  "description": "Minimum amount in USD",
                  "example": 0.15
                },
                "max_usd": {
                  "type": "number",
                  "description": "Maximum amount in USD",
                  "example": 1000.0
                }
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "example": "Invalid api_key or api_key_id"
          }
        }
      }
    }
  }
}