General Information
Information exchange with the SBP server is realized via RESTful API. All requests to the server must be executed via HTTPS using GET||POST||PUT||DELETE requests to the given ROOT address. Body of requests must be in JSON format. All not public requests must be signed by the client and the public key must be sent to the server for client identification and sign checking. 
Header: 
“Authorization”: {JSON WITH KEY AND PARTNERID}
        “X-Region”  : Moscow | Yerevan | ST. Petersburg
        “X-Language” : RU | AM | EN
        “WebSessionID” : f02fe5d6-c6ae-4b2e-9b4d-687534e11b01
        “Currency” :RUB | AMD | USD
Root:
        API.dexarmarket.ru


General Information
Check if server is available
Get Marketplaces
Set Marketplaces
Get Item
Delete Item
New Item
New Callback
New Question
Get random Items
Get items in category
Get searched items
Get Categories
Delete Category
New Category
Create new websession
Check websession status
Delete websession status
Add to cart
Create New QR code for cart checkout
Check QR code
item structure
category structure
Check if server is available
Client needs to periodically check if the server is available by sending “ping” to the client.   On error corresponding message must be shown.
Protocol: https
Type: GET
Path: /ping
Request Parameters: 
{


}
Response (Error):
{
"message": "pong",
"status": "Wrong Header"
}
Response (OK):
{
"message": "pong",
"status": "Correct Header"
}
________________


Get Marketplaces
Get Available Marketplaces
Protocol: https
Type: GET
Path: /marketplaces
Request Parameters: 
{
}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        [{“brand” : “dexar”,
        “api”:”dexar.market”,
        “bot”:”dexarmarket_bot”,
        “languagies”:[“”am,”ru”,”en”],
        “regions”:[“Mosocw - Russia”, ”St Petersburg - Russia”, ”Yerevan - Armenia”]
        “currency”:[“RUB, ”AMD”, ”USD”]
        “icon”:”./dexar.market.png”},
        {“brand” : “store”,
        “api”:”dexarmarket.store”,
        “bot”:”dexarstore_bot”,
        “languagies”:[“”am,”ru”,”en”],
        “regions”:[“Mosocw - Russia”,”St Petersburg - Russia”,”Yerevan - Armenia”]
        “currency”:[“”RUB,”AMD”,”USD”]
        “icon”:”./dexarmarket.store.png”},
        {“brand” : “Novo”,
        “api”:”novo.market”,
        “bot”:”novomarket_bot”,
        “languagies”:[“”am,”ru”,”en”],
        “regions”:[“Mosocw - Russia”, ”St Petersburg - Russia”,”Yerevan - Armenia”]
        “currency”:[“”RUB,”AMD”,”USD”]
        “icon”:”./novo.market.png”}]


}
________________


Set Marketplaces
Get Available Marketplaces
Protocol: https
Type: PUT
Path: /marketplaces
Request Parameters: 
{
        [{“brand” : “dexar”,
        “api”:”dexar.market”,
        “languagies”:[“”am,”ru”,”en”],
        “regions”:[“Mosocw - Russia”,”St Petersburg - Russia”,”Yerevan - Armenia”]
        “currency”:[“”RUB,”AMD”,”USD”]
        “icon”:”./dexar.market.png”},
        {“brand” : “store”,
        “api”:”dexarmarket.store”,
        “languagies”:[“”am,”ru”,”en”],
        “regions”:[“Mosocw - Russia”,”St Petersburg - Russia”,”Yerevan - Armenia”]
        “currency”:[“”RUB,”AMD”,”USD”]
        “icon”:”./dexarmarket.store.png”},
        {“brand” : “Novo”,
        “api”:”novo.market”,
        “languagies”:[“”am,”ru”,”en”],
        “regions”:[“Mosocw - Russia”, ”St Petersburg - Russia”,”Yerevan - Armenia”]
        “currency”:[“”RUB,”AMD”,”USD”]
        “icon”:”./novo.market.png”}]


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “status”:”Marketplace updated”
}
________________


Get Item
Get Item by ID 
Protocol: https
Type: GET
Path: /items/:itemID
Request Parameters: 
{


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “itemID”:...
}
________________
Delete Item
Delete the item
Protocol: https
Type: Delete
Path: /items/:itemID
Request Parameters: 
{


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “status”:”Item was deleted”
}
________________
New Item
Create new  Item 
Protocol: https
Type: POST
Path: /items/:itemID
Request Parameters: 
{
        “itemID”:...
}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “itemID”:...
}
________________
Update Item
Update the item
Protocol: https
Type: PUT
Path: /items/:itemID
Request Parameters: 
{
        “itemID”:...
}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “status”:”Item updated”
}
________________


New Callback
Update the item
Protocol: https
Type: POST
Path: /items/:itemID/callback
Request Parameters: 
{
        "rating": 5,
          "comment": "Отличный товар!",
          "sessionID": “ f02fe5d6-c6ae-4b2e-9b4d-687534e11b01”
          "timestamp": "2026-02-28T12:00:00Z"
}
Response !=200(Error):
{
   "error": "wrong item"
}
Response =200(OK):
{
        “status”:”Callback added”
}
________________
New Question
Update the item
Protocol: https
Type: POST
Path: /items/:itemID/questiion
Request Parameters: 
{
          "question": "some question!",
          "sessionID": “ f02fe5d6-c6ae-4b2e-9b4d-687534e11b01”
          "timestamp": "2026-02-28T12:00:00Z"
}
Response !=200(Error):
{
   "error": "wrong item"
}
Response =200(OK):
{
        “status”:”Questiion added”
}
________________


Get random Items
Get given number of items from random categorues
Protocol: https
Type: GET
Path: /items/randomitems?count=15 // 20 is the default
Request Parameters: 
{


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        [“itemID”:...]
}
________________
Get items in category 
Get all items in category and in all subcategories inside the category
Protocol: https
Type: GET
Path: /category/:categoryID?count=30, skip=60 // default skip=0, default count=20


Request Parameters: 
{
}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        [“itemID”:...]
}
________________


Get searched items
Get all items in category and in all subcategories inside the category
Protocol: https
Type: GET
Path: /searchitems
Parameters:
{
search (string) — query text
categoryIDs (string) — e.g., 1,2,5 (includes all subcategories)
minPrice / maxPrice (float) — price range
tag (string) — e.g., sale
sort (string) — relevance (default), price_asc, price_desc, popular, rating
skip / count — default 0 / 20
}
Examples:
* ?search=iphone&sort=popular
* ?categoryIDs=1,5&minPrice=100&maxPrice=500
* ?tag=new&sort=price_asc&count=10


Request Parameters: 
{


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
  "total": 12,
  "skip": 0,
  "count": 12,
  "isGlobal": false,
  "items": [
    { "itemID": 101, "name": "..." }
  ]
}
________________


Get Categories
Get all available categories 
Protocol: https
Type: GET
Path: /category
Request Parameters: 
{


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “categoryID”:...
}
________________
Delete Category
Delete EMPTY category, no items and no subcategories must present
Protocol: https
Type: Delete
Path: /category/:categoryID
Request Parameters: 
{


}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “status”:”Category was deleted”
}
________________
New Category
Create new  category 
Protocol: https
Type: POST
Path: /category/
Request Parameters: 
{
        “CategoryID”:...
}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “CategoryID”:...
}
________________
Update Category
Update existing category
Protocol: https
Type: PUT
Path: /category/:categoryID
Request Parameters: 
{
        “itemID”:...
}
Response !=200(Error):
{
   "error": "wrong header"
}
Response =200(OK):
{
        “status”:”Category was updated”
}
________________
Create new websession
Creates a new websession for qr generation. By timeout a new websession must be requested, after the user shows some activity (click on qr).
Protocol: https
Type POST
Path /websession
Request Parameters: 
{


}
Response (OK):
{
"sessionId": “1AF3781BF6B94604B771AEA1D44FA63A”,
"userId" :  "",
"expires" : "sessionId",
"userSessionId": "", 
"status": false
         }
________________
Check websession status
Check if the user is already logged in. a new websession for qr generation. By timeout a new websession must be requested, after the user shows some activity (click on qr).
Protocol: https
Type GET
Path /websession/:webSessionID
Request Parameters: 
{


}
Response (OK):
{
"sessionId": “1AF3781BF6B94604B771AEA1D44FA63A”,
"userId" :  "kHaAe9roaC2uq63AKGE/8+Ti/t/iFro68QhEZ1dRGLo",
"expires" : "sessionId",
"userSessionId": "8A94EFEFD003426A9B456C48CAC99BE6", 
"x-Region" : "Moscow",
"x-Language" : "RU",
"currency" : "RUB",
"Status": true,
"cart": [
        { "itemID": 12, "quantity": 1, “colour”:”black”, “size”:”42”,"priice":230.50 }, 
        { "itemID": 13, "quantity": 2, “colour”:”dark”, “size”:”L”,"priice":250.50 }, 
    { "itemID": 14, "quantity": 3, “colour”:”blue”, “size”:”50”,"priice":290.50 }, 
]
}
________________
Delete websession status
Delete the session to log out from the system.
Protocol: https
Type DELETE
Path /websession/:webSessionID
Request Parameters: 
{
}
Response (OK):
{
        “status”:”User logged out”
}
   
________________
Add to cart
Add a all item to users (session) cart
Protocol: https
Type Post
Path /websession/:webSessionID
Request Parameters: 
{
 [
        { "itemID": 12, "quantity": 1, “colour”:”black”, “size”:”42”,"priice":230.50 }, 
        { "itemID": 13, "quantity": 2, “colour”:”dark”, “size”:”L”,"priice":250.50 }, 
    { "itemID": 14, "quantity": 3, “colour”:”blue”, “size”:”50”,"priice":290.50 }, 
]
}
Response (OK):
{
"sessionId": “1AF3781BF6B94604B771AEA1D44FA63A”,
"userId" :  "kHaAe9roaC2uq63AKGE/8+Ti/t/iFro68QhEZ1dRGLo",
"expires" : "sessionId",
"userSessionId": "8A94EFEFD003426A9B456C48CAC99BE6", 
"Status": true,
"cart": [
        { "itemID": 12, "quantity": 1, “colour”:”black”, “size”:”42”,"priice":230.50 }, 
        { "itemID": 13, "quantity": 2, “colour”:”dark”, “size”:”L”,"priice":250.50 }, 
    { "itemID": 14, "quantity": 3, “colour”:”blue”, “size”:”50”,"priice":290.50 }, 
]
          }
________________
Create New QR code for cart checkout
Create New QR for payment via SBP
Protocol: https
Type POST
Path  /websession/:webSessionID/qr
Request Parameters: 
{
}


Response !=200(Error):
{
   "error": "wrong key"
}
Response =200(OK):
{
 "qrId": "BD10002CI1V3JP1T8QR8TIQ8K35RBVQB",
 "qrStatus": "NEW",
 "qrExpirationDate": "2025-11-20T10:10:44Z",
 "Payload": "https://qr.nspk.ru/BD10002CI1V3JP1T8QR8TIQ8K35RBVQB?type=02&bank=100000000007&sum=1000&cur=RUB&crc=8ACC",
   "qrUrl": "https://e-commerce.raiffeisen.ru/api/sbp/v1/qr/BD10002CI1V3JP1T8QR8TIQ8K35RBVQB/image"
}
________________


Check QR code
Check QR status
Protocol: https
Type GET
Path /websession/:webSessionID/:qrID
Request Parameters: 
{
}


Response !=200(Error):
{
   "error": "Error from the bank "
}
Response =200(OK):
{
   "additionalInfo": "",
   "paymentPurpose": "",
   "amount": 10,
   "code": "SUCCESS",
   "createDate": "2025-11-20T13:17:20.453884+03:00",
   "currency": "RUB",
   "order": "102_540",
   "paymentStatus": "NO_INFO", //check for SUCCESS
   "qrId": "BD1000263VS7G81D8JCP5FHFTFEH38MT",
   "transactionDate": "",
   "transactionId": 0,
   "qrExpirationDate": "2025-11-20T13:32:20+03:00"
}








## 8. Авторизация (вход через Telegram)


Авторизация **через Telegram** с **cookie-сессиями** (HttpOnly, Secure, SameSite=None).


Все auth-эндпоинты должны поддерживать CORS с `credentials: true`.


### Процесс авторизации


```
1. Пользователь нажимает «Оформить заказ» → не авторизован → показывается диалог входа
2. Нажимает «Войти через Telegram» → открывается https://t.me/{bot}?start=auth_{callback}
3. Пользователь запускает бота в Telegram
4. Бот отправляет данные пользователя → бэкенд /auth/telegram/callback
5. Бэкенд создаёт сессию → устанавливает Set-Cookie
6. Фронтенд опрашивает GET /auth/session каждые 3 секунды
7. Сессия обнаружена → диалог закрывается → оформление заказа продолжается
```


---


### `GET /auth/session` — Проверить текущую сессию


**Запрос:** Только cookie (сессионная cookie, установленная бэкендом).


**Ответ `200`** (авторизован):
```json
{
  "sessionId": "sess_abc123",
  "telegramUserId": 123456789,
  "username": "john_doe",
  "displayName": "John Doe",
  "active": true,
  "expiresAt": "2026-03-01T12:00:00Z"
}
```


**Ответ `200`** (сессия истекла):
```json
{
  "sessionId": "sess_abc123",
  "telegramUserId": 123456789,
  "username": "john_doe",
  "displayName": "John Doe",
  "active": false,
  "expiresAt": "2026-02-27T12:00:00Z"
}
```


**Ответ `401`** (нет сессии):
```json
{ "error": "No active session" }
```


**Объект AuthSession:**


| Поле             | Тип     | Обязат. | Описание                                  |
|------------------|---------|---------|-------------------------------------------|
| `sessionId`      | string  | да      | Уникальный ID сессии                      |
| `telegramUserId` | number  | да      | ID пользователя в Telegram                |
| `username`       | string? | нет     | @username в Telegram (может быть null)    |
| `displayName`    | string  | да      | Отображаемое имя (имя + фамилия)          |
| `active`         | boolean | да      | Действительна ли сессия                   |
| `expiresAt`      | string  | да      | Дата истечения в формате ISO 8601         |


---


### `GET /auth/telegram/callback` — Callback авторизации Telegram-бота


Вызывается Telegram-ботом после авторизации пользователя.


**Тело запроса (от бота):**
```json
{
  "id": 123456789,
  "first_name": "John",
  "last_name": "Doe",
  "username": "john_doe",
  "photo_url": "https://t.me/i/userpic/...",
  "auth_date": 1709100000,
  "hash": "abc123def456..."
}
```




Бот должен:
1. Слушать команду `/start auth_{callbackUrl}`
2. Извлечь callback URL
3. Отправить данные пользователя (`id`, `first_name`, `username` и т.д.) на этот callback URL
4. Callback URL: `{apiUrl}/auth/telegram/callback`


---


## Полный справочник эндпоинтов


### Новые эндпоинты


| Метод  | Путь                      | Описание                        | Авторизация |
|--------|---------------------------|---------------------------------|-------------|
| `GET`  | `/regions`                | Список доступных регионов       | Нет         |
| `GET`  | `/auth/session`           | Проверка текущей сессии         | Cookie      |
| `GET`  | `/auth/telegram/callback` | Callback авторизации через бота | Нет (бот)   |
| `POST` | `/auth/logout`            | Завершение сессии               | Cookie      |


________________


item structure
   CategoryID  uint64     `json:"categoryID" binding:"required"`
   ItemID      uint64     `json:"itemID" binding:"required"`
   Name        string     `json:"name" binding:"required"`
   Description string     `json:"description"`
   Discount    float32    `json:"discount" `
   Rating      float32    `json:"rating" binding:"required"`
   Visible            bool          `json:"rating"`
   Priority    uint64        `json:"priority"`
   Tags              []string   `json:"tags"`
   Badges      []string   `json:"badges"`
   Details    []itemdetail   `json:"itemdetails"`
        Colour         string     `json:"colour" binding:"required"`                 
        Size         string            `json:"size" binding:"required"`
        Price     float32    `json:"price" binding:"required"`
           Currency  string     `json:"currency" binding:"required"`
        Remaining uint64     `json:"remaining" binding:"required"`
    Names []itemname `json:"names"`
        Language        string `json:"language"`
        Value         string `json:"value"`
   Descriptions []itemdescription `json:"descriptions" `
        Language string         `json:"language"`
        Value    string        `json:"value"`
   Attributes []attribute `json:"attributes" binding:"required"`
        Key string `json:"key"`
        Value string `json:"value"`
   Photos      []photo    `json:"photos"`
           Type string `json:"type" binding:"required"` //video || photo
                   URL  string `json:"url" binding:"required"`
   Questions   []question `json:"questions"`
        Question string `json:"question" `
           Answer   string `json:"answer" `
           Like     uint64 `json:"like" `
           Dislike  uint64 `json:"dislike" `
   Visits       uint64    `json:"visits"`
   Callbacks   []callback `json:"callbacks" binding:"required"`
           Rating    float32 `json:"rating,omitempty"`
           Content   string  `json:"content,omitempty"`
           Userid    string  `json:"userID"`
           Answer    string  `json:"answer"`
           Timestamp string  `json:"timestamp"`
   PartnerID   []string     `json:"partnerID" binding:"required"`


category structure
   CategoryID uint64 `json:"categoryID" binding:"required"`
   ParentID   uint64 `json:"parentID" binding:"required"`
   Name       string `json:"name" binding:"required"`
   Visible    bool   `json:"visible" `
   Priority   uint64 `json:"priority" `
   Icon       string `json:"icon"`
   WideIcon   string `json:"wideicon"` 
   ItemsCount uint64 
   CategoriesCount uint64
   Names []itemname `json:"names"`
        Language        string `json:"language"`
        Value         string `json:"value"`