{
  "openapi": "3.0.3",
  "info": {
    "title": "Arzan Pay Kaspi Pay API",
    "version": "1.0.0",
    "description": "API для создания Kaspi Pay счетов, sandbox-тестов, webhooks, возвратов, каталога и подписок."
  },
  "servers": [
    {
      "url": "https://pay.arzan.cloud/api"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "InvoiceCreate": {
        "type": "object",
        "required": [
          "amount",
          "phone_number"
        ],
        "properties": {
          "amount": {
            "type": "number",
            "example": 10000
          },
          "phone_number": {
            "type": "string",
            "example": "77011234567"
          },
          "description": {
            "type": "string",
            "example": "Заказ #1042"
          },
          "external_order_id": {
            "type": "string",
            "example": "order_1042"
          },
          "is_sandbox": {
            "type": "boolean",
            "example": true
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "inv_88cfc192"
          },
          "external_order_id": {
            "type": "string",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "example": "10000.00"
          },
          "currency": {
            "type": "string",
            "example": "KZT"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "paid",
              "canceled",
              "refunded"
            ]
          },
          "description": {
            "type": "string"
          },
          "phone_number": {
            "type": "string"
          },
          "kaspi_invoice_id": {
            "type": "string",
            "nullable": true
          },
          "payment_url": {
            "type": "string",
            "nullable": true
          },
          "is_sandbox": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookCreate": {
        "type": "object",
        "required": [
          "url",
          "events"
        ],
        "properties": {
          "url": {
            "type": "string",
            "example": "https://example.kz/webhooks/kaspi"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "invoice.status_changed",
              "invoice.refunded"
            ]
          }
        }
      },
      "SubscriptionCreate": {
        "type": "object",
        "required": [
          "phone_number",
          "amount"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "example": "77011234567"
          },
          "amount": {
            "type": "number",
            "example": 10000
          },
          "billing_period": {
            "type": "string",
            "example": "monthly"
          },
          "description": {
            "type": "string",
            "example": "Абонплата"
          },
          "is_sandbox": {
            "type": "boolean",
            "example": true
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Повторный запрос с тем же ключом вернет тот же response и не создаст дубль."
      }
    }
  },
  "paths": {
    "/organizations/verify": {
      "post": {
        "summary": "Проверить API key и организацию",
        "responses": {
          "200": {
            "description": "Организация найдена"
          },
          "401": {
            "description": "API key неверный"
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "summary": "Получить текущего мерчанта",
        "responses": {
          "200": {
            "description": "Информация о мерчанте"
          }
        }
      }
    },
    "/v1/invoices": {
      "get": {
        "summary": "Список счетов",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "is_sandbox",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список счетов"
          }
        }
      },
      "post": {
        "summary": "Создать счет",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Счет создан",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации"
          },
          "409": {
            "description": "Kaspi не подключен"
          },
          "502": {
            "description": "Kaspi не создал счет"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/v1/invoices/{id}": {
      "get": {
        "summary": "Получить счет",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Счет"
          },
          "404": {
            "description": "Счет не найден"
          }
        }
      }
    },
    "/v1/invoices/{id}/cancel": {
      "post": {
        "summary": "Отменить счет через Kaspi remote cancel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Счет отменен"
          },
          "409": {
            "description": "Счет нельзя отменить"
          }
        }
      }
    },
    "/v1/invoices/status/check": {
      "post": {
        "summary": "Проверить статусы через Kaspi",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Statuses checked"
          }
        }
      }
    },
    "/v1/qr": {
      "post": {
        "summary": "Создать Kaspi QR",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "amount": {
                    "type": "number",
                    "example": 10000
                  },
                  "comment": {
                    "type": "string",
                    "example": "Заказ #1042"
                  },
                  "external_order_id": {
                    "type": "string",
                    "example": "order_1042"
                  },
                  "is_sandbox": {
                    "type": "boolean",
                    "example": true
                  },
                  "latitude": {
                    "type": "number",
                    "example": 43.238949
                  },
                  "longitude": {
                    "type": "number",
                    "example": 76.889709
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "QR created"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/v1/invoices/{id}/refund": {
      "post": {
        "summary": "Создать возврат по оплаченному счету через Kaspi",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number"
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Возврат создан"
          },
          "409": {
            "description": "Счет не оплачен"
          }
        }
      }
    },
    "/v1/refunds": {
      "get": {
        "summary": "Список возвратов",
        "responses": {
          "200": {
            "description": "Возвраты"
          }
        }
      },
      "post": {
        "summary": "Создать возврат по оплаченному счету или QR через Kaspi",
        "responses": {
          "201": {
            "description": "Refund created"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/v1/webhooks": {
      "get": {
        "summary": "Список webhook endpoints",
        "responses": {
          "200": {
            "description": "Webhooks"
          }
        }
      },
      "post": {
        "summary": "Создать webhook endpoint",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created"
          }
        }
      }
    },
    "/v1/webhooks/{id}/test": {
      "post": {
        "summary": "Отправить тестовый webhook",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Test queued"
          }
        }
      }
    },
    "/v1/catalog": {
      "get": {
        "summary": "Список товаров",
        "responses": {
          "200": {
            "description": "Catalog"
          }
        }
      },
      "post": {
        "summary": "Создать товары",
        "responses": {
          "201": {
            "description": "Items created"
          }
        }
      }
    },
    "/v1/catalog/units": {
      "get": {
        "summary": "Единицы измерения",
        "responses": {
          "200": {
            "description": "Units"
          }
        }
      }
    },
    "/v1/subscriptions": {
      "get": {
        "summary": "Список подписок",
        "responses": {
          "200": {
            "description": "Subscriptions"
          }
        }
      },
      "post": {
        "summary": "Создать подписку",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Subscription created"
          }
        }
      }
    },
    "/v1/kaspi/session": {
      "get": {
        "summary": "Мониторинг Kaspi session текущего мерчанта",
        "responses": {
          "200": {
            "description": "Kaspi session status"
          }
        }
      }
    },
    "/v1/audit-logs": {
      "get": {
        "summary": "Audit logs платежных действий",
        "responses": {
          "200": {
            "description": "Audit logs"
          }
        }
      }
    },
    "/v1/webhook-deliveries": {
      "get": {
        "summary": "История webhook доставок",
        "responses": {
          "200": {
            "description": "Webhook delivery log"
          }
        }
      }
    },
    "/v1/webhook-deliveries/{id}/retry": {
      "post": {
        "summary": "Повторить webhook delivery",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Retry queued"
          }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "summary": "Очередь jobs/retry/dead-letter",
        "responses": {
          "200": {
            "description": "Jobs"
          }
        }
      }
    },
    "/v1/sandbox/invoices/{id}/simulate": {
      "post": {
        "summary": "Sandbox simulate paid/canceled/failed/pending",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "paid",
                      "canceled",
                      "failed",
                      "pending"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sandbox invoice updated"
          }
        }
      }
    }
  }
}
