86 Commits

Author SHA1 Message Date
sdarbinyan
9aaff4d80a removed parazite 2026-06-19 16:13:54 +04:00
sdarbinyan
7a06843bf5 fixes 2026-06-19 15:01:54 +04:00
sdarbinyan
1decc08f77 userId 2026-06-19 12:43:25 +04:00
sdarbinyan
c0cfbcbcbb changed type 2026-06-19 02:00:34 +04:00
sdarbinyan
688c225911 removed parasite 2026-06-19 01:57:27 +04:00
sdarbinyan
3e79304e5c timer 2026-06-18 18:32:36 +04:00
sdarbinyan
e7d8ec8c63 chek 2026-06-18 18:30:20 +04:00
sdarbinyan
1e3cd99c69 redirect 2026-06-18 18:29:39 +04:00
sdarbinyan
3ab67cbe2d empty commit 2026-06-18 16:36:10 +04:00
sdarbinyan
b3c056980d removed mail 2026-06-18 16:35:34 +04:00
sdarbinyan
fb3bb6c77c submited 2026-06-18 15:09:56 +04:00
sdarbinyan
bdc330c885 chagned status 2026-06-18 13:11:05 +04:00
sdarbinyan
31da7f85cf header layout fix 2026-06-10 17:49:22 +04:00
sdarbinyan
69e63fc5f3 fixed cards 2026-06-10 17:40:14 +04:00
sdarbinyan
fe6fc2cb74 changes for ofert 2026-06-10 15:35:23 +04:00
sdarbinyan
80cc90d347 api changes 2026-06-06 22:38:01 +04:00
sdarbinyan
9b5c2dd95c api 2026-06-06 19:25:00 +04:00
sdarbinyan
58e0869916 api changed 2026-06-06 16:16:37 +04:00
sdarbinyan
14bdd3bcd0 api change 2026-06-05 18:23:24 +04:00
sdarbinyan
a10216a392 polling 2026-06-05 17:57:18 +04:00
sdarbinyan
e53c8230e6 payment 2026-06-02 02:12:08 +04:00
sdarbinyan
c6bc05560e change 2026-06-02 01:46:12 +04:00
sdarbinyan
63b0e18396 api change 2026-06-02 00:57:36 +04:00
sdarbinyan
1bec150822 Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-06-01 00:47:57 +04:00
sdarbinyan
4d8dc6b59c api auth 2026-06-01 00:47:26 +04:00
tonoyan
b0a744034b phone number and address 2026-05-28 12:56:41 +00:00
sdarbinyan
49f69f6af0 port 2026-05-19 03:53:23 +04:00
sdarbinyan
5017b62059 empty 2026-05-19 03:24:02 +04:00
sdarbinyan
ea80f90d0f api 2026-05-19 03:20:25 +04:00
sdarbinyan
dd74432dd7 api 2026-05-19 03:14:12 +04:00
sdarbinyan
4aef4881e1 changes 2026-05-19 02:57:19 +04:00
sdarbinyan
7bc3eb10c1 lorelo 2026-05-19 02:46:13 +04:00
sdarbinyan
55957df00c apis 2026-05-19 02:07:39 +04:00
sdarbinyan
cb2666177a lavero 2026-05-19 02:01:36 +04:00
sdarbinyan
6e5fb3b86a QR login 2026-04-14 23:14:26 +04:00
sdarbinyan
a15f2bca6a dynamic phone and bots 2026-04-14 22:28:34 +04:00
sdarbinyan
1897cbe7a6 phone novo 2026-04-14 16:15:45 +04:00
sdarbinyan
ab1732d74b guid 2026-04-14 13:49:54 +04:00
sdarbinyan
7df15a4243 phone number 2026-04-14 13:48:56 +04:00
sdarbinyan
abb74390e8 style changes for novo 2026-04-13 23:32:46 +04:00
sdarbinyan
06a7568386 fixed novo market apis 2026-04-13 23:19:38 +04:00
sdarbinyan
77737f0ba9 fixing novo 2026-04-13 22:39:33 +04:00
sdarbinyan
6de461473e added docs 2026-03-25 15:42:27 +04:00
sdarbinyan
db781fd871 qr login with telegram 2026-03-25 15:32:50 +04:00
sdarbinyan
ce301e9c70 translation into armenian 2026-03-25 14:52:26 +04:00
sdarbinyan
64288b5ce1 offer 2026-03-25 14:27:53 +04:00
sdarbinyan
a8bb725f78 Add ООО «ИНТ ФАКТОРИНГ» (ИНН 9909697635) as second company across all pages 2026-03-24 17:15:48 +04:00
tonoyan
df2208ab53 dexar.market 2026-03-24 10:55:29 +00:00
tonoyan
72deb8d5e3 add dexar.market 2026-03-24 10:53:03 +00:00
sdarbinyan
5566e011b7 fixed cart 2026-03-24 03:24:34 +04:00
sdarbinyan
ee23fd2d3c color 2026-03-24 03:12:04 +04:00
sdarbinyan
2a41062769 random 2026-03-24 02:58:51 +04:00
sdarbinyan
6624de7a32 random items 2026-03-24 02:52:39 +04:00
sdarbinyan
44553f5bd4 changes 2026-03-24 02:46:58 +04:00
sdarbinyan
5ed255dddb Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-03-24 02:27:59 +04:00
sdarbinyan
650bf137f2 fixes 2026-03-24 02:25:50 +04:00
root
3a8bc2f893 change ports in start 2026-03-23 21:31:26 +00:00
root
d29de100c6 add loccal changes 2026-03-23 21:20:11 +00:00
sdarbinyan
97214c3a90 Merge branch 'back-office-integration'
# Conflicts:
#	src/app/pages/cart/cart.component.ts
#	src/app/pages/category/category.component.html
#	src/app/pages/category/category.component.ts
#	src/app/pages/item-detail/item-detail.component.html
#	src/app/pages/item-detail/item-detail.component.ts
#	src/app/pages/legal/company-details/en/company-details-en.component.html
#	src/app/pages/legal/company-details/hy/company-details-hy.component.html
#	src/app/pages/legal/company-details/ru/company-details-ru.component.html
#	src/app/pages/legal/public-offer/en/public-offer-en.component.html
#	src/app/pages/legal/public-offer/ru/public-offer-ru.component.html
#	src/app/pages/search/search.component.ts
#	src/app/services/api.service.ts
2026-03-24 00:18:13 +04:00
sdarbinyan
56f4c56b9e integration new apis 2026-03-24 00:09:11 +04:00
sdarbinyan
0b3b2ee463 changes 2026-03-06 18:40:58 +04:00
sdarbinyan
c3e4e695eb changes and optimisations 2026-03-06 17:45:34 +04:00
sdarbinyan
c112aded47 added sceleton for loading 2026-03-06 17:22:35 +04:00
sdarbinyan
75f029b872 added condition 2026-03-06 16:59:01 +04:00
root
f823df7e15 Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-03-05 16:49:39 +00:00
sdarbinyan
af78c053ba fixed design 2026-03-05 20:45:15 +04:00
root
4ef4223367 Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-03-05 16:27:13 +00:00
sdarbinyan
7b18376d28 added info for legal 2026-03-05 20:23:42 +04:00
root
c64b9cfee8 Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-03-04 14:20:07 +00:00
sdarbinyan
712281d2e8 closed en/am 2026-03-04 16:45:01 +04:00
sdarbinyan
0626dcbe46 changes in legal 2026-03-04 16:40:25 +04:00
root
d288a5fb3c Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-03-02 08:57:24 +00:00
sdarbinyan
3445f55758 updates 2026-03-01 02:43:14 +04:00
sdarbinyan
350581cbe9 changes for md 2026-02-28 17:42:36 +04:00
sdarbinyan
377da22761 Merge branch 'auth-system' into back-office-integration 2026-02-28 17:37:14 +04:00
sdarbinyan
421346d957 Merge remote-tracking branch 'origin' into back-office-integration 2026-02-28 16:13:14 +04:00
sdarbinyan
d6097e2b5d style fixes 2026-02-20 10:58:06 +04:00
sdarbinyan
369af40f20 bo integration 2026-02-20 10:44:03 +04:00
root
75b45abe4f Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-02-19 21:32:07 +00:00
root
2bd98b29eb Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-02-18 14:07:44 +00:00
root
82cbf07120 okMerge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-02-14 15:28:51 +00:00
root
e07356a700 add new server 2026-02-14 09:52:29 +00:00
root
5068a3a114 Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-02-14 09:51:37 +00:00
root
333ea45c38 Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-01-22 20:35:13 +00:00
root
b22390f3eb Merge branch 'main' of https://sources.vitanova.network/sdarbinyan/marketplaces 2026-01-22 20:27:30 +00:00
root
3f285ca15f local build 2026-01-22 11:58:50 +00:00
253 changed files with 15365 additions and 2783 deletions

2
.gitignore vendored
View File

@@ -38,7 +38,7 @@ yarn-error.log
/libpeerconnection.log
testem.log
/typings
/public/images/
# System files
.DS_Store
Thumbs.db

View File

@@ -54,8 +54,8 @@
},
{
"type": "anyComponentStyle",
"maximumWarning": "25kB",
"maximumError": "35kB"
"maximumWarning": "40kB",
"maximumError": "50kB"
}
],
"outputHashing": "all",
@@ -129,8 +129,74 @@
},
{
"type": "anyComponentStyle",
"maximumWarning": "25kB",
"maximumError": "35kB"
"maximumWarning": "40kB",
"maximumError": "50kB"
}
],
"outputHashing": "all",
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": true
},
"fonts": {
"inline": true
}
},
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"serviceWorker": "ngsw-config.json"
},
"lavero": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.lavero.ts"
},
{
"replace": "src/app/brands/brand-routes.ts",
"with": "src/app/brands/brand-routes.lavero.ts"
}
],
"index": "src/index.lavero.html",
"styles": [
"src/styles.scss",
"src/styles/themes/lavero.theme.scss"
],
"outputPath": "dist/laveromarket",
"optimization": false,
"extractLicenses": false,
"sourceMap": true
},
"lavero-production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.lavero.production.ts"
},
{
"replace": "src/app/brands/brand-routes.ts",
"with": "src/app/brands/brand-routes.lavero.ts"
}
],
"index": "src/index.lavero.html",
"styles": [
"src/styles.scss",
"src/styles/themes/lavero.theme.scss"
],
"outputPath": "dist/laveromarket",
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "40kB",
"maximumError": "50kB"
}
],
"outputHashing": "all",
@@ -154,7 +220,14 @@
},
"serve": {
"options": {
"allowedHosts": ["novo.market", "dexarmarket.ru", "localhost"]
"allowedHosts": [
"novo.market",
"dexarmarket.ru",
"dexar.market",
"localhost",
"lovero.store"
],
"proxyConfig": "proxy.conf.json"
},
"builder": "@angular/build:dev-server",
"configurations": {
@@ -165,36 +238,24 @@
"buildTarget": "Dexarmarket:build:development"
},
"novo": {
"buildTarget": "Dexarmarket:build:novo"
"buildTarget": "Dexarmarket:build:novo",
"proxyConfig": "proxy.conf.novo.json"
},
"novo-production": {
"buildTarget": "Dexarmarket:build:novo-production"
},
"lavero": {
"buildTarget": "Dexarmarket:build:lavero",
"proxyConfig": "proxy.conf.lavero.json"
},
"lavero-production": {
"buildTarget": "Dexarmarket:build:lavero-production"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular/build:extract-i18n"
},
"test": {
"builder": "@angular/build:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.scss"
]
}
}
}
}

View File

@@ -1,24 +1,471 @@
# API Changes Required for Backend
# Complete Backend API Documentation
## Overview
Frontend has been updated with two new features:
1. **Region/Location system** — catalog filtering by region
2. **Auth/Login system** — Telegram-based authentication required before payment
Base URLs:
- Dexar: `https://api.dexarmarket.ru:445`
- Novo: `https://api.novo.market:444`
> **Last updated:** February 2026
> **Frontend:** Angular 21 · Dual-brand (Dexar + Novo)
> **Covers:** Catalog, Cart, Payments, Reviews, Regions, Auth, i18n, BackOffice
---
## 1. Region / Location Endpoints
## Base URLs
### 1.1 `GET /regions` — List available regions
| Brand | Dev | Production |
|--------|----------------------------------|----------------------------------|
| Dexar | `https://api.dexarmarket.ru:445` | `https://api.dexarmarket.ru:445` |
| Novo | `https://api.novo.market:444` | `https://api.novo.market:444` |
Returns the list of regions where the marketplace operates.
---
**Response** `200 OK`
## Global HTTP Headers
The frontend **automatically attaches** two custom headers to **every API request** via an interceptor. The backend should read these headers and use them to filter/translate responses accordingly.
| Header | Example Value | Description |
|---------------|---------------|------------------------------------------------------------|
| `X-Region` | `moscow` | Region ID selected by the user. **Absent** = global (all). |
| `X-Language` | `ru` | Active UI language: `ru`, `en`, or `hy`. |
### Backend behavior
- **`X-Region`**: If present, filter items/categories to only those available in that region. If absent, return everything (global catalog).
- **`X-Language`**: If present, return translated `name`, `description`, etc. for categories/items when translations exist. If absent or `ru`, use russians defaults.
### CORS requirements for these headers
```
Access-Control-Allow-Headers: Content-Type, X-Region, X-Language
```
---
## 1. Health Check
### `GET /ping`
Simple health check.
**Response `200`:**
```json
{ "message": "pong" }
```
---
## 2. Catalog — Categories
### `GET /category`
Returns all top-level categories. Respects `X-Region` and `X-Language` headers.
**Response `200`:**
```json
[
{
"categoryID": 1,
"name": "Электроника",
"parentID": 0,
"icon": "https://...",
"wideBanner": "https://...",
"itemCount": 42,
"priority": 10,
"id": "cat_abc123",
"visible": true,
"img": "https://...",
"projectId": "proj_xyz",
"subcategories": [
{
"id": "sub_001",
"name": "Смартфоны",
"visible": true,
"priority": 5,
"img": "https://...",
"categoryId": "cat_abc123",
"parentId": "cat_abc123",
"itemCount": 20,
"hasItems": true,
"subcategories": []
}
]
}
]
```
**Category object:**
| Field | Type | Required | Description |
|------------------|---------------|----------|----------------------------------------------------|
| `categoryID` | number | yes | Legacy numeric ID |
| `name` | string | yes | Category display name (translated if `X-Language`) |
| `parentID` | number | yes | Parent category ID (`0` = top-level) |
| `icon` | string | no | Category icon URL |
| `wideBanner` | string | no | Wide banner image URL |
| `itemCount` | number | no | Number of items in category |
| `priority` | number | no | Sort priority (higher = first) |
| `id` | string | no | BackOffice string ID |
| `visible` | boolean | no | Whether category is shown (`true` default) |
| `img` | string | no | BackOffice image URL (maps to `icon`) |
| `projectId` | string | no | BackOffice project reference |
| `subcategories` | Subcategory[] | no | Nested subcategories |
**Subcategory object:**
| Field | Type | Required | Description |
|------------------|---------------|----------|------------------------------------|
| `id` | string | yes | Subcategory ID |
| `name` | string | yes | Display name |
| `visible` | boolean | no | Whether visible |
| `priority` | number | no | Sort priority |
| `img` | string | no | Image URL |
| `categoryId` | string | yes | Parent category ID |
| `parentId` | string | yes | Direct parent ID |
| `itemCount` | number | no | Number of items |
| `hasItems` | boolean | no | Whether has any items |
| `subcategories` | Subcategory[] | no | Nested children |
---
### `GET /category/:categoryID`
Returns items in a specific category. Respects `X-Region` and `X-Language` headers.
**Query params:**
| Param | Type | Default | Description |
|----------|--------|---------|--------------------|
| `count` | number | `50` | Items per page |
| `skip` | number | `0` | Offset for paging |
**Response `200`:** Array of [Item](#item-object) objects.
---
## 3. Items
### `GET /item/:itemID`
Returns a single item. Respects `X-Region` and `X-Language` headers.
**Response `200`:** A single [Item](#item-object) object.
---
### `GET /searchitems`
Full-text search across items. Respects `X-Region` and `X-Language` headers.
**Query params:**
| Param | Type | Default | Description |
|----------|--------|---------|----------------------|
| `search` | string | — | Search query (required) |
| `count` | number | `50` | Items per page |
| `skip` | number | `0` | Offset for paging |
**Response `200`:**
```json
{
"items": [ /* Item objects */ ],
"total": 128,
"count": 50,
"skip": 0
}
```
---
### `GET /randomitems`
Returns random items for carousel/recommendations. Respects `X-Region` and `X-Language` headers.
**Query params:**
| Param | Type | Default | Description |
|------------|--------|---------|------------------------------------|
| `count` | number | `5` | Number of items to return |
| `category` | number | — | Optional: limit to this category |
**Response `200`:** Array of [Item](#item-object) objects.
---
### Item Object
The backend can return items in **either** legacy format or BackOffice format. The frontend normalizes both.
```json
{
"categoryID": 1,
"itemID": 123,
"name": "iPhone 15 Pro",
"photos": [{ "url": "https://..." }],
"description": "Описание товара",
"currency": "RUB",
"price": 89990,
"discount": 10,
"remainings": "high",
"rating": 4.5,
"callbacks": [
{
"rating": 5,
"content": "Отличный товар!",
"userID": "user_123",
"timestamp": "2026-02-01T12:00:00Z"
}
],
"questions": [
{
"question": "Есть ли гарантия?",
"answer": "Да, 12 месяцев",
"upvotes": 5,
"downvotes": 0
}
],
"id": "item_abc123",
"visible": true,
"priority": 10,
"imgs": ["https://img1.jpg", "https://img2.jpg"],
"tags": ["new", "popular"],
"badges": ["bestseller", "sale"],
"simpleDescription": "Краткое описание",
"descriptionFields": [
{ "key": "Процессор", "value": "A17 Pro" },
{ "key": "Память", "value": "256 GB" }
],
"subcategoryId": "sub_001",
"translations": {
"en": {
"name": "iPhone 15 Pro",
"simpleDescription": "Short description",
"description": [
{ "key": "Processor", "value": "A17 Pro" }
]
},
"hy": {
"name": "iPhone 15 Pro",
"simpleDescription": "Կարcheck check check"
}
},
"comments": [
{
"id": "cmt_001",
"text": "Отличный товар!",
"author": "user_123",
"stars": 5,
"createdAt": "2026-02-01T12:00:00Z"
}
],
"quantity": 50
}
```
**Full Item fields:**
| Field | Type | Required | Description |
|---------------------|-------------------|----------|------------------------------------------------------------|
| `categoryID` | number | yes | Category this item belongs to |
| `itemID` | number | yes | Legacy numeric item ID |
| `name` | string | yes | Item display name |
| `photos` | Photo[] | no | Legacy photo array `[{ url }]` |
| `description` | string | yes | Text description |
| `currency` | string | yes | Currency code (default: `RUB`) |
| `price` | number | yes | Price in the currency's smallest display unit |
| `discount` | number | yes | Discount percentage (`0``100`) |
| `remainings` | string | no | Stock level: `high`, `medium`, `low`, `out` |
| `rating` | number | yes | Average rating (`0``5`) |
| `callbacks` | Review[] | no | Legacy reviews (alias for reviews) |
| `questions` | Question[] | no | Q&A entries |
| `id` | string | no | BackOffice string ID |
| `visible` | boolean | no | Whether item is visible (`true` default) |
| `priority` | number | no | Sort priority (higher = first) |
| `imgs` | string[] | no | BackOffice image URLs (maps to `photos`) |
| `tags` | string[] | no | Item tags for filtering |
| `badges` | string[] | no | Display badges (`bestseller`, `sale`, etc.) |
| `simpleDescription` | string | no | Short plain-text description |
| `descriptionFields` | DescriptionField[]| no | Structured `[{ key, value }]` descriptions |
| `subcategoryId` | string | no | BackOffice subcategory reference |
| `translations` | Record | no | Translations keyed by lang code (see below) |
| `comments` | Comment[] | no | BackOffice comments format |
| `quantity` | number | no | Numeric stock count (maps to `remainings` on frontend) |
**Nested types:**
| Type | Fields |
|--------------------|-----------------------------------------------------------------|
| `Photo` | `url: string`, `photo?: string`, `video?: string`, `type?: string` |
| `DescriptionField` | `key: string`, `value: string` |
| `Comment` | `id?: string`, `text: string`, `author?: string`, `stars?: number`, `createdAt?: string` |
| `Review` | `rating?: number`, `content?: string`, `userID?: string`, `answer?: string`, `timestamp?: string` |
| `Question` | `question: string`, `answer: string`, `upvotes: number`, `downvotes: number` |
| `ItemTranslation` | `name?: string`, `simpleDescription?: string`, `description?: DescriptionField[]` |
---
## 4. Cart
### `POST /cart` — Add item to cart
**Request body:**
```json
{ "itemID": 123, "quantity": 1 }
```
**Response `200`:**
```json
{ "message": "Added to cart" }
```
---
### `PATCH /cart` — Update item quantity
**Request body:**
```json
{ "itemID": 123, "quantity": 3 }
```
**Response `200`:**
```json
{ "message": "Updated" }
```
---
### `DELETE /cart` — Remove items from cart
**Request body:** Array of item IDs
```json
[123, 456]
```
**Response `200`:**
```json
{ "message": "Removed" }
```
---
### `GET /cart` — Get cart contents
**Response `200`:** Array of [Item](#item-object) objects (each with `quantity` field).
---
## 5. Payments (SBP / QR)
### `POST /cart` — Create payment (SBP QR)
> Note: Same endpoint as add-to-cart but with different body schema.
**Request body:**
```json
{
"amount": 89990,
"currency": "RUB",
"siteuserID": "tg_123456789",
"siteorderID": "order_abc123",
"redirectUrl": "",
"telegramUsername": "john_doe",
"items": [
{ "itemID": 123, "price": 89990, "name": "iPhone 15 Pro" }
]
}
```
**Response `200`:**
```json
{
"qrId": "qr_abc123",
"qrStatus": "CREATED",
"qrExpirationDate": "2026-02-28T13:00:00Z",
"payload": "https://qr.nspk.ru/...",
"qrUrl": "https://qr.nspk.ru/..."
}
```
---
### `GET /qr/payment/:qrId` — Check payment status
**Response `200`:**
```json
{
"additionalInfo": "",
"paymentPurpose": "Order #order_abc123",
"amount": 89990,
"code": "SUCCESS",
"createDate": "2026-02-28T12:00:00Z",
"currency": "RUB",
"order": "order_abc123",
"paymentStatus": "COMPLETED",
"qrId": "qr_abc123",
"transactionDate": "2026-02-28T12:01:00Z",
"transactionId": 999,
"qrExpirationDate": "2026-02-28T13:00:00Z",
"phoneNumber": "+7XXXXXXXXXX"
}
```
| `paymentStatus` values | Meaning |
|------------------------|---------------------------|
| `CREATED` | QR generated, not paid |
| `WAITING` | Payment in progress |
| `COMPLETED` | Payment successful |
| `EXPIRED` | QR code expired |
| `CANCELLED` | Payment cancelled |
---
### `POST /purchase-email` — Submit email after payment
**Request body:**
```json
{
"email": "user@example.com",
"telegramUserId": "123456789",
"items": [
{ "itemID": 123, "name": "iPhone 15 Pro", "price": 89990, "currency": "RUB" }
]
}
```
**Response `200`:**
```json
{ "message": "Email sent" }
```
---
## 6. Reviews / Comments
### `POST /comment` — Submit a review
**Request body:**
```json
{
"itemID": 123,
"rating": 5,
"comment": "Great product!",
"username": "john_doe",
"userId": 123456789,
"timestamp": "2026-02-28T12:00:00Z"
}
```
**Response `200`:**
```json
{ "message": "Review submitted" }
```
---
## 7. Regions
### `GET /regions` — List available regions
Returns regions where the marketplace operates.
**Response `200`:**
```json
[
{
@@ -46,52 +493,44 @@ Returns the list of regions where the marketplace operates.
```
**Region object:**
| Field | Type | Required | Description |
|---------------|--------|----------|------------------------------|
| `id` | string | yes | Unique region identifier |
| `city` | string | yes | City name (display) |
| `country` | string | yes | Country name (display) |
| `countryCode` | string | yes | ISO 3166-1 alpha-2 code |
| `timezone` | string | no | IANA timezone string |
> If this endpoint is unavailable, the frontend falls back to 6 hardcoded regions (Moscow, SPB, Yerevan, Minsk, Almaty, Tbilisi).
| Field | Type | Required | Description |
|---------------|--------|----------|--------------------------|
| `id` | string | yes | Unique region identifier |
| `city` | string | yes | City name (display) |
| `country` | string | yes | Country name |
| `countryCode` | string | yes | ISO 3166-1 alpha-2 |
| `timezone` | string | no | IANA timezone |
> **Fallback:** If this endpoint is down, the frontend uses 6 hardcoded defaults: Moscow, SPB, Yerevan, Minsk, Almaty, Tbilisi.
---
### 1.2 Region Query Parameter on Existing Endpoints
The following **existing** endpoints now accept an optional `?region=` query parameter:
| Endpoint | Example |
|---------------------------------|----------------------------------------------|
| `GET /category` | `GET /category?region=moscow` |
| `GET /category/:id` | `GET /category/5?count=50&skip=0&region=spb` |
| `GET /item/:id` | `GET /item/123?region=yerevan` |
| `GET /searchitems` | `GET /searchitems?search=phone&region=moscow` |
| `GET /randomitems` | `GET /randomitems?count=5&region=almaty` |
**Behavior:**
- If `region` param is **present** → return only items/categories available in that region
- If `region` param is **absent** → return all items globally (current behavior, no change)
- The `region` value matches the `id` field from the `/regions` response
---
## 2. Auth / Login Endpoints
## 8. Authentication (Telegram Login)
Authentication is **Telegram-based** with **cookie sessions** (HttpOnly, Secure, SameSite=None).
All auth endpoints must support CORS with `credentials: true`.
All auth endpoints must include `withCredentials: true` CORS support.
### 2.1 `GET /auth/session` — Check current session
### Auth flow
Called on every page load to check if the user has an active session.
```
1. User clicks "Checkout" → not authenticated → login dialog shown
2. User clicks "Log in with Telegram" → opens https://t.me/{bot}?start=auth_{callback}
3. User starts the bot in Telegram
4. Bot sends user data → backend /auth/telegram/callback
5. Backend creates session → sets Set-Cookie
6. Frontend polls GET /auth/session every 3s
7. Session detected → dialog closes → checkout proceeds
```
**Request:**
- Cookies: session cookie (set by backend)
- CORS: `withCredentials: true`
---
**Response `200 OK`** (authenticated):
### `GET /auth/session` — Check current session
**Request:** Cookies only (session cookie set by backend).
**Response `200`** (authenticated):
```json
{
"sessionId": "sess_abc123",
@@ -103,7 +542,7 @@ Called on every page load to check if the user has an active session.
}
```
**Response `200 OK`** (expired session):
**Response `200`** (expired):
```json
{
"sessionId": "sess_abc123",
@@ -115,37 +554,29 @@ Called on every page load to check if the user has an active session.
}
```
**Response `401 Unauthorized`** (no session / invalid cookie):
**Response `401`** (no session):
```json
{
"error": "No active session"
}
{ "error": "No active session" }
```
**AuthSession object:**
| Field | Type | Required | Description |
|------------------|---------|----------|------------------------------------------|
| `sessionId` | string | yes | Unique session ID |
| `telegramUserId` | number | yes | Telegram user ID |
| `username` | string? | no | Telegram @username (can be null) |
| `displayName` | string | yes | User display name (first_name + last_name) |
| `active` | boolean | yes | Whether session is currently valid |
| `expiresAt` | string | yes | ISO 8601 expiration datetime |
| Field | Type | Required | Description |
|------------------|---------|----------|--------------------------------------------|
| `sessionId` | string | yes | Unique session ID |
| `telegramUserId` | number | yes | Telegram user ID |
| `username` | string? | no | Telegram @username (can be null) |
| `displayName` | string | yes | User display name (first + last) |
| `active` | boolean | yes | Whether session is valid |
| `expiresAt` | string | yes | ISO 8601 expiration datetime |
---
### 2.2 `GET /auth/telegram/callback` — Telegram bot auth callback
### `GET /auth/telegram/callback` — Telegram bot auth callback
This is the URL the Telegram bot redirects to after the user starts the bot.
Called by the Telegram bot after user authenticates.
**Flow:**
1. Frontend generates link: `https://t.me/{botUsername}?start=auth_{encodedCallbackUrl}`
2. User clicks → opens Telegram → starts the bot
3. Bot sends user data to this callback endpoint
4. Backend creates session, sets `Set-Cookie` header
5. Frontend polls `GET /auth/session` every 3 seconds to detect when session becomes active
**Request** (from Telegram bot / webhook):
**Request body (from bot):**
```json
{
"id": 123456789,
@@ -158,7 +589,7 @@ This is the URL the Telegram bot redirects to after the user starts the bot.
}
```
**Response:** Should set a session cookie and return:
**Response:** Must set a session cookie and return:
```json
{
"sessionId": "sess_abc123",
@@ -167,93 +598,89 @@ This is the URL the Telegram bot redirects to after the user starts the bot.
```
**Cookie requirements:**
| Attribute | Value | Notes |
|------------|----------------|------------------------------------------|
| `HttpOnly` | `true` | Not accessible via JS |
| `Secure` | `true` | HTTPS only |
| Attribute | Value | Notes |
|------------|----------------|--------------------------------------------|
| `HttpOnly` | `true` | Not accessible via JS |
| `Secure` | `true` | HTTPS only |
| `SameSite` | `None` | Required for cross-origin (API ≠ frontend) |
| `Path` | `/` | |
| `Max-Age` | `86400` (24h) | Or as needed |
| `Domain` | API domain | |
> **Important:** Since the API domain differs from the frontend domain, `SameSite=None` + `Secure=true` is required for the cookie to be sent cross-origin.
| `Path` | `/` | |
| `Max-Age` | `86400` (24h) | Or as needed |
---
### 2.3 `POST /auth/logout` — End session
### `POST /auth/logout` — End session
**Request:**
- Cookies: session cookie
- CORS: `withCredentials: true`
- Body: `{}` (empty)
**Request:** Cookies only, empty body `{}`
**Response `200 OK`:**
**Response `200`:**
```json
{
"message": "Logged out"
}
{ "message": "Logged out" }
```
Should clear/invalidate the session cookie.
Must clear/invalidate the session cookie.
---
## 3. CORS Configuration
### Session refresh
For auth cookies to work cross-origin, the backend CORS config must include:
The frontend re-checks the session **60 seconds before `expiresAt`**. If the backend supports sliding expiration, it can reset the cookie's `Max-Age` on each `GET /auth/session`.
---
## 9. i18n / Translations
The frontend supports 3 languages: **Russian (ru)**, **English (en)**, **Armenian (hy)**.
The active language is sent via the `X-Language` HTTP header on every request.
### What the backend should do with `X-Language`
1. **Categories & items**: If `translations` field exists for the requested language, return the translated `name`, `description`, etc. OR the backend can apply translations server-side and return already-translated fields.
2. **The `translations` field** on items (optional approach):
```json
{
"translations": {
"en": {
"name": "iPhone 15 Pro",
"simpleDescription": "Short desc in English",
"description": [{ "key": "Processor", "value": "A17 Pro" }]
},
"hy": {
"name": "iPhone 15 Pro",
"simpleDescription": "Կarcheck check"
}
}
}
```
3. **Recommended approach**: Read `X-Language` header and return the `name`/`description` in that language directly. If no translation exists, return the Russian default.
---
## 10. CORS Configuration
For auth cookies and custom headers to work, the backend CORS config must include:
```
Access-Control-Allow-Origin: https://dexarmarket.ru (NOT *)
Access-Control-Allow-Origin: https://dexarmarket.ru (NOT wildcard *)
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Headers: Content-Type, X-Region, X-Language
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
```
> `Access-Control-Allow-Origin` **cannot** be `*` when `Allow-Credentials: true`. Must be the exact frontend origin.
> **Important:** `Access-Control-Allow-Origin` cannot be `*` when `Allow-Credentials: true`. Must be the exact frontend origin.
For Novo, also allow `https://novo.market`.
**Allowed origins:**
- `https://dexarmarket.ru`
- `https://novo.market`
- `http://localhost:4200` (dev)
- `http://localhost:4201` (dev, Novo)
---
## 4. Session Refresh Behavior
The frontend automatically re-checks the session **60 seconds before `expiresAt`**. If the backend supports session extension (sliding expiration), it can re-set the cookie with a fresh `Max-Age` on every `GET /auth/session` call.
---
## 5. Auth Gate — Checkout Flow
The checkout button (`POST /cart` payment) now requires authentication:
- If the user is **not logged in** → frontend shows a Telegram login dialog instead of proceeding
- If the user **is logged in** → checkout proceeds normally
- The session cookie is sent automatically with the payment request
No backend changes needed for the payment endpoint itself — just ensure it reads the session cookie if needed for order association.
---
## Summary of New Endpoints
| Method | Path | Purpose | Auth Required |
|--------|----------------------------|-----------------------------|---------------|
| `GET` | `/regions` | List available regions | No |
| `GET` | `/auth/session` | Check current session | Cookie |
| `GET` | `/auth/telegram/callback` | Telegram bot auth callback | No (from bot) |
| `POST` | `/auth/logout` | End session | Cookie |
## Summary of Modified Endpoints
| Method | Path | Change |
|--------|-------------------|---------------------------------------|
| `GET` | `/category` | Added optional `?region=` param |
| `GET` | `/category/:id` | Added optional `?region=` param |
| `GET` | `/item/:id` | Added optional `?region=` param |
| `GET` | `/searchitems` | Added optional `?region=` param |
| `GET` | `/randomitems` | Added optional `?region=` param |
---
## Telegram Bot Setup
## 11. Telegram Bot Setup
Each brand needs its own bot:
- **Dexar:** `@dexarmarket_bot`
@@ -262,5 +689,38 @@ Each brand needs its own bot:
The bot should:
1. Listen for `/start auth_{callbackUrl}` command
2. Extract the callback URL
3. Send the user's Telegram data (id, first_name, username, etc.) to that callback URL
3. Send the user's Telegram data (`id`, `first_name`, `username`, etc.) to that callback URL
4. The callback URL is `{apiUrl}/auth/telegram/callback`
---
## Complete Endpoint Reference
### New endpoints
| Method | Path | Description | Auth |
|--------|---------------------------|----------------------------|----------|
| `GET` | `/regions` | List available regions | No |
| `GET` | `/auth/session` | Check current session | Cookie |
| `GET` | `/auth/telegram/callback` | Telegram bot auth callback | No (bot) |
| `POST` | `/auth/logout` | End session | Cookie |
### Existing endpoints
| Method | Path | Description | Auth | Headers |
|----------|-----------------------|-------------------------|------|--------------------|
| `GET` | `/ping` | Health check | No | — |
| `GET` | `/category` | List categories | No | X-Region, X-Language |
| `GET` | `/category/:id` | Items in category | No | X-Region, X-Language |
| `GET` | `/item/:id` | Single item | No | X-Region, X-Language |
| `GET` | `/searchitems` | Search items | No | X-Region, X-Language |
| `GET` | `/randomitems` | Random items | No | X-Region, X-Language |
| `POST` | `/cart` | Add to cart / Payment | No* | — |
| `PATCH` | `/cart` | Update cart quantity | No* | — |
| `DELETE` | `/cart` | Remove from cart | No* | — |
| `GET` | `/cart` | Get cart contents | No* | — |
| `POST` | `/comment` | Submit review | No | — |
| `GET` | `/qr/payment/:qrId` | Check payment status | No | — |
| `POST` | `/purchase-email` | Submit email after pay | No | — |
> \* Cart/payment endpoints may use the session cookie if available for order association, but don't strictly require auth. The frontend enforces auth before checkout.

726
docs/API_DOCS_RU.md Normal file
View File

@@ -0,0 +1,726 @@
# Полная документация Backend API
> **Последнее обновление:** Февраль 2026
> **Фронтенд:** Angular 21 · Два бренда (Dexar + Novo)
> **Охватывает:** Каталог, Корзина, Оплата, Отзывы, Регионы, Авторизация, i18n, BackOffice
---
## Базовые URL
| Бренд | Dev | Production |
|--------|----------------------------------|----------------------------------|
| Dexar | `https://api.dexarmarket.ru:445` | `https://api.dexarmarket.ru:445` |
| Novo | `https://api.novo.market:444` | `https://api.novo.market:444` |
---
## Глобальные HTTP-заголовки
Фронтенд **автоматически добавляет** два кастомных заголовка к **каждому API-запросу** через interceptor. Бэкенд должен читать эти заголовки и использовать для фильтрации/перевода ответов.
| Заголовок | Пример значения | Описание |
|---------------|-----------------|-------------------------------------------------------------------|
| `X-Region` | `moscow` | ID региона, выбранного пользователем. **Отсутствует** = все регионы. |
| `X-Language` | `ru` | Активный язык интерфейса: `ru`, `en` или `hy`. |
### Поведение бэкенда
- **`X-Region`**: Если присутствует — фильтровать товары/категории только по этому региону. Если отсутствует — возвращать всё (глобальный каталог).
- **`X-Language`**: Если присутствует — возвращать переведённые `name`, `description` и т.д., если переводы существуют. Если отсутствует или `ru` — возвращать на русском (по умолчанию).
### Требования CORS для этих заголовков
```
Access-Control-Allow-Headers: Content-Type, X-Region, X-Language
```
---
## 1. Проверка состояния
### `GET /ping`
Простая проверка работоспособности.
**Ответ `200`:**
```json
{ "message": "pong" }
```
---
## 2. Каталог — Категории
### `GET /category`
Возвращает все категории верхнего уровня. Учитывает заголовки `X-Region` и `X-Language`.
**Ответ `200`:**
```json
[
{
"categoryID": 1,
"name": "Электроника",
"parentID": 0,
"icon": "https://...",
"wideBanner": "https://...",
"itemCount": 42,
"priority": 10,
"id": "cat_abc123",
"visible": true,
"img": "https://...",
"projectId": "proj_xyz",
"subcategories": [
{
"id": "sub_001",
"name": "Смартфоны",
"visible": true,
"priority": 5,
"img": "https://...",
"categoryId": "cat_abc123",
"parentId": "cat_abc123",
"itemCount": 20,
"hasItems": true,
"subcategories": []
}
]
}
]
```
**Объект Category:**
| Поле | Тип | Обязат. | Описание |
|------------------|---------------|---------|-----------------------------------------------------|
| `categoryID` | number | да | Числовой ID (legacy) |
| `name` | string | да | Название категории (переведённое если `X-Language`) |
| `parentID` | number | да | ID родительской категории (`0` = верхний уровень) |
| `icon` | string | нет | URL иконки категории |
| `wideBanner` | string | нет | URL широкого баннера |
| `itemCount` | number | нет | Количество товаров в категории |
| `priority` | number | нет | Приоритет сортировки (больше = выше) |
| `id` | string | нет | Строковый ID из BackOffice |
| `visible` | boolean | нет | Видима ли категория (по умолч. `true`) |
| `img` | string | нет | URL изображения из BackOffice (маппится на `icon`) |
| `projectId` | string | нет | Ссылка на проект в BackOffice |
| `subcategories` | Subcategory[] | нет | Вложенные подкатегории |
**Объект Subcategory:**
| Поле | Тип | Обязат. | Описание |
|------------------|---------------|---------|----------------------------------|
| `id` | string | да | ID подкатегории |
| `name` | string | да | Отображаемое название |
| `visible` | boolean | нет | Видима ли |
| `priority` | number | нет | Приоритет сортировки |
| `img` | string | нет | URL изображения |
| `categoryId` | string | да | ID родительской категории |
| `parentId` | string | да | ID прямого родителя |
| `itemCount` | number | нет | Количество товаров |
| `hasItems` | boolean | нет | Есть ли товары |
| `subcategories` | Subcategory[] | нет | Вложенные дочерние подкатегории |
---
### `GET /category/:categoryID`
Возвращает товары определённой категории. Учитывает заголовки `X-Region` и `X-Language`.
**Query-параметры:**
| Параметр | Тип | По умолч. | Описание |
|----------|--------|-----------|-----------------------|
| `count` | number | `50` | Товаров на страницу |
| `skip` | number | `0` | Смещение для пагинации |
**Ответ `200`:** Массив объектов [Item](#объект-item).
---
## 3. Товары
### `GET /item/:itemID`
Возвращает один товар. Учитывает заголовки `X-Region` и `X-Language`.
**Ответ `200`:** Один объект [Item](#объект-item).
---
### `GET /searchitems`
Полнотекстовый поиск по товарам. Учитывает заголовки `X-Region` и `X-Language`.
**Query-параметры:**
| Параметр | Тип | По умолч. | Описание |
|----------|--------|-----------|-------------------------------|
| `search` | string | — | Поисковый запрос (обязателен) |
| `count` | number | `50` | Товаров на страницу |
| `skip` | number | `0` | Смещение для пагинации |
**Ответ `200`:**
```json
{
"items": [ /* объекты Item */ ],
"total": 128,
"count": 50,
"skip": 0
}
```
---
### `GET /randomitems`
Возвращает случайные товары для карусели/рекомендаций. Учитывает заголовки `X-Region` и `X-Language`.
**Query-параметры:**
| Параметр | Тип | По умолч. | Описание |
|------------|--------|-----------|--------------------------------------|
| `count` | number | `5` | Количество товаров |
| `category` | number | — | Ограничить данной категорией (опц.) |
**Ответ `200`:** Массив объектов [Item](#объект-item).
---
### Объект Item
Бэкенд может возвращать товары в **любом** из двух форматов — legacy или BackOffice. Фронтенд нормализует оба варианта.
```json
{
"categoryID": 1,
"itemID": 123,
"name": "iPhone 15 Pro",
"photos": [{ "url": "https://..." }],
"description": "Описание товара",
"currency": "RUB",
"price": 89990,
"discount": 10,
"remainings": "high",
"rating": 4.5,
"callbacks": [
{
"rating": 5,
"content": "Отличный товар!",
"userID": "user_123",
"timestamp": "2026-02-01T12:00:00Z"
}
],
"questions": [
{
"question": "Есть ли гарантия?",
"answer": "Да, 12 месяцев",
"upvotes": 5,
"downvotes": 0
}
],
"id": "item_abc123",
"visible": true,
"priority": 10,
"imgs": ["https://img1.jpg", "https://img2.jpg"],
"tags": ["new", "popular"],
"badges": ["bestseller", "sale"],
"simpleDescription": "Краткое описание",
"descriptionFields": [
{ "key": "Процессор", "value": "A17 Pro" },
{ "key": "Память", "value": "256 GB" }
],
"subcategoryId": "sub_001",
"translations": {
"en": {
"name": "iPhone 15 Pro",
"simpleDescription": "Short description",
"description": [
{ "key": "Processor", "value": "A17 Pro" }
]
},
"hy": {
"name": "iPhone 15 Pro",
"simpleDescription": "Կարcheck check"
}
},
"comments": [
{
"id": "cmt_001",
"text": "Отличный товар!",
"author": "user_123",
"stars": 5,
"createdAt": "2026-02-01T12:00:00Z"
}
],
"quantity": 50
}
```
**Все поля Item:**
| Поле | Тип | Обязат. | Описание |
|---------------------|-------------------|---------|-----------------------------------------------------------|
| `categoryID` | number | да | Категория, к которой принадлежит товар |
| `itemID` | number | да | Числовой ID товара (legacy) |
| `name` | string | да | Название товара |
| `photos` | Photo[] | нет | Массив фотографий `[{ url }]` (legacy) |
| `description` | string | да | Текстовое описание |
| `currency` | string | да | Код валюты (по умолч. `RUB`) |
| `price` | number | да | Цена |
| `discount` | number | да | Процент скидки (`0``100`) |
| `remainings` | string | нет | Уровень остатка: `high`, `medium`, `low`, `out` |
| `rating` | number | да | Средний рейтинг (`0``5`) |
| `callbacks` | Review[] | нет | Отзывы (legacy формат) |
| `questions` | Question[] | нет | Вопросы и ответы |
| `id` | string | нет | Строковый ID из BackOffice |
| `visible` | boolean | нет | Виден ли товар (по умолч. `true`) |
| `priority` | number | нет | Приоритет сортировки (больше = выше) |
| `imgs` | string[] | нет | URL картинок из BackOffice (маппится на `photos`) |
| `tags` | string[] | нет | Теги для фильтрации |
| `badges` | string[] | нет | Бейджи (`bestseller`, `sale` и т.д.) |
| `simpleDescription` | string | нет | Краткое текстовое описание |
| `descriptionFields` | DescriptionField[]| нет | Структурированное описание `[{ key, value }]` |
| `subcategoryId` | string | нет | Ссылка на подкатегорию из BackOffice |
| `translations` | Record | нет | Переводы по ключу языка (см. ниже) |
| `comments` | Comment[] | нет | Комментарии в формате BackOffice |
| `quantity` | number | нет | Числовое кол-во на складе (маппится на `remainings`) |
**Вложенные типы:**
| Тип | Поля |
|--------------------|-----------------------------------------------------------------|
| `Photo` | `url: string`, `photo?: string`, `video?: string`, `type?: string` |
| `DescriptionField` | `key: string`, `value: string` |
| `Comment` | `id?: string`, `text: string`, `author?: string`, `stars?: number`, `createdAt?: string` |
| `Review` | `rating?: number`, `content?: string`, `userID?: string`, `answer?: string`, `timestamp?: string` |
| `Question` | `question: string`, `answer: string`, `upvotes: number`, `downvotes: number` |
| `ItemTranslation` | `name?: string`, `simpleDescription?: string`, `description?: DescriptionField[]` |
---
## 4. Корзина
### `POST /cart` — Добавить товар в корзину
**Тело запроса:**
```json
{ "itemID": 123, "quantity": 1 }
```
**Ответ `200`:**
```json
{ "message": "Added to cart" }
```
---
### `PATCH /cart` — Обновить количество товара
**Тело запроса:**
```json
{ "itemID": 123, "quantity": 3 }
```
**Ответ `200`:**
```json
{ "message": "Updated" }
```
---
### `DELETE /cart` — Удалить товары из корзины
**Тело запроса:** Массив ID товаров
```json
[123, 456]
```
**Ответ `200`:**
```json
{ "message": "Removed" }
```
---
### `GET /cart` — Получить содержимое корзины
**Ответ `200`:** Массив объектов [Item](#объект-item) (каждый с полем `quantity`).
---
## 5. Оплата (СБП / QR)
### `POST /cart` — Создать платёж (СБП QR)
> Примечание: Тот же эндпоинт что и добавление в корзину, но с другой схемой тела запроса.
**Тело запроса:**
```json
{
"amount": 89990,
"currency": "RUB",
"siteuserID": "tg_123456789",
"siteorderID": "order_abc123",
"redirectUrl": "",
"telegramUsername": "john_doe",
"items": [
{ "itemID": 123, "price": 89990, "name": "iPhone 15 Pro" }
]
}
```
**Ответ `200`:**
```json
{
"qrId": "qr_abc123",
"qrStatus": "CREATED",
"qrExpirationDate": "2026-02-28T13:00:00Z",
"payload": "https://qr.nspk.ru/...",
"qrUrl": "https://qr.nspk.ru/..."
}
```
---
### `GET /qr/payment/:qrId` — Проверить статус оплаты
**Ответ `200`:**
```json
{
"additionalInfo": "",
"paymentPurpose": "Order #order_abc123",
"amount": 89990,
"code": "SUCCESS",
"createDate": "2026-02-28T12:00:00Z",
"currency": "RUB",
"order": "order_abc123",
"paymentStatus": "COMPLETED",
"qrId": "qr_abc123",
"transactionDate": "2026-02-28T12:01:00Z",
"transactionId": 999,
"qrExpirationDate": "2026-02-28T13:00:00Z",
"phoneNumber": "+7XXXXXXXXXX"
}
```
| Значение `paymentStatus` | Значение |
|--------------------------|------------------------------|
| `CREATED` | QR создан, не оплачен |
| `WAITING` | Оплата в процессе |
| `COMPLETED` | Оплата успешна |
| `EXPIRED` | QR-код истёк |
| `CANCELLED` | Оплата отменена |
---
### `POST /purchase-email` — Отправить email после оплаты
**Тело запроса:**
```json
{
"email": "user@example.com",
"telegramUserId": "123456789",
"items": [
{ "itemID": 123, "name": "iPhone 15 Pro", "price": 89990, "currency": "RUB" }
]
}
```
**Ответ `200`:**
```json
{ "message": "Email sent" }
```
---
## 6. Отзывы / Комментарии
### `POST /comment` — Оставить отзыв
**Тело запроса:**
```json
{
"itemID": 123,
"rating": 5,
"comment": "Отличный товар!",
"username": "john_doe",
"userId": 123456789,
"timestamp": "2026-02-28T12:00:00Z"
}
```
**Ответ `200`:**
```json
{ "message": "Review submitted" }
```
---
## 7. Регионы
### `GET /regions` — Список доступных регионов
Возвращает регионы, в которых работает маркетплейс.
**Ответ `200`:**
```json
[
{
"id": "moscow",
"city": "Москва",
"country": "Россия",
"countryCode": "RU",
"timezone": "Europe/Moscow"
},
{
"id": "spb",
"city": "Санкт-Петербург",
"country": "Россия",
"countryCode": "RU",
"timezone": "Europe/Moscow"
},
{
"id": "yerevan",
"city": "Ереван",
"country": "Армения",
"countryCode": "AM",
"timezone": "Asia/Yerevan"
}
]
```
**Объект Region:**
| Поле | Тип | Обязат. | Описание |
|---------------|--------|---------|----------------------------------|
| `id` | string | да | Уникальный идентификатор региона |
| `city` | string | да | Название города |
| `country` | string | да | Название страны |
| `countryCode` | string | да | Код страны ISO 3166-1 alpha-2 |
| `timezone` | string | нет | Часовой пояс IANA |
> **Фоллбэк:** Если эндпоинт недоступен, фронтенд использует 6 захардкоженных значений: Москва, СПб, Ереван, Минск, Алматы, Тбилиси.
---
## 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..."
}
```
**Ответ:** Должен установить cookie сессии и вернуть:
```json
{
"sessionId": "sess_abc123",
"message": "Authenticated successfully"
}
```
**Требования к cookie:**
| Атрибут | Значение | Примечание |
|------------|----------------|-----------------------------------------------------|
| `HttpOnly` | `true` | Недоступна из JavaScript |
| `Secure` | `true` | Только HTTPS |
| `SameSite` | `None` | Обязательно для cross-origin (API ≠ фронтенд) |
| `Path` | `/` | |
| `Max-Age` | `86400` (24ч) | Или по необходимости |
---
### `POST /auth/logout` — Завершить сессию
**Запрос:** Только cookie, пустое тело `{}`
**Ответ `200`:**
```json
{ "message": "Logged out" }
```
Должен очистить/инвалидировать cookie сессии.
---
### Обновление сессии
Фронтенд повторно проверяет сессию за **60 секунд до `expiresAt`**. Если бэкенд поддерживает скользящий срок действия (sliding expiration), можно обновлять `Max-Age` cookie при каждом вызове `GET /auth/session`.
---
## 9. i18n / Переводы
Фронтенд поддерживает 3 языка: **Русский (ru)**, **Английский (en)**, **Армянский (hy)**.
Активный язык отправляется через HTTP-заголовок `X-Language` с каждым запросом.
### Что бэкенд должен делать с `X-Language`
1. **Категории и товары**: Если для запрошенного языка есть поле `translations`, вернуть переведённые `name`, `description` и т.д. ИЛИ бэкенд может применять переводы на стороне сервера и возвращать уже переведённые поля.
2. **Поле `translations`** на товарах (опциональный подход):
```json
{
"translations": {
"en": {
"name": "iPhone 15 Pro",
"simpleDescription": "Short desc in English",
"description": [{ "key": "Processor", "value": "A17 Pro" }]
},
"hy": {
"name": "iPhone 15 Pro",
"simpleDescription": "Կarcheck check"
}
}
}
```
3. **Рекомендуемый подход**: Читать заголовок `X-Language` и возвращать `name`/`description` на этом языке напрямую. Если перевода нет — возвращать русский вариант по умолчанию.
---
## 10. Настройка CORS
Для работы auth-cookie и кастомных заголовков конфигурация CORS бэкенда должна включать:
```
Access-Control-Allow-Origin: https://dexarmarket.ru (НЕ wildcard *)
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-Region, X-Language
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
```
> **Важно:** `Access-Control-Allow-Origin` не может быть `*` при `Allow-Credentials: true`. Должен быть точный origin фронтенда.
**Разрешённые origins:**
- `https://dexarmarket.ru`
- `https://novo.market`
- `http://localhost:4200` (dev)
- `http://localhost:4201` (dev, Novo)
---
## 11. Настройка Telegram-бота
Каждому бренду нужен свой бот:
- **Dexar:** `@dexarmarket_bot`
- **Novo:** `@novomarket_bot`
Бот должен:
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 |
### Существующие эндпоинты
| Метод | Путь | Описание | Авт. | Заголовки |
|----------|-----------------------|---------------------------|------|--------------------|
| `GET` | `/ping` | Проверка состояния | Нет | — |
| `GET` | `/category` | Список категорий | Нет | X-Region, X-Language |
| `GET` | `/category/:id` | Товары категории | Нет | X-Region, X-Language |
| `GET` | `/item/:id` | Один товар | Нет | X-Region, X-Language |
| `GET` | `/searchitems` | Поиск товаров | Нет | X-Region, X-Language |
| `GET` | `/randomitems` | Случайные товары | Нет | X-Region, X-Language |
| `POST` | `/cart` | Добавить в корзину / Оплата | Нет* | — |
| `PATCH` | `/cart` | Обновить кол-во | Нет* | — |
| `DELETE` | `/cart` | Удалить из корзины | Нет* | — |
| `GET` | `/cart` | Содержимое корзины | Нет* | — |
| `POST` | `/comment` | Оставить отзыв | Нет | — |
| `GET` | `/qr/payment/:qrId` | Статус оплаты | Нет | — |
| `POST` | `/purchase-email` | Отправить email после оплаты | Нет | — |
> \* Эндпоинты корзины/оплаты могут использовать cookie сессии (если есть) для привязки к заказу, но не требуют авторизации строго. Фронтенд проверяет авторизацию перед оформлением заказа.

View File

@@ -0,0 +1,824 @@
# Авторизация через Telegram — Backend & Bot
> Всё что нужно Go-разработчику для реализации авторизации.
> Фронтенд **полностью готов** и ждёт эти эндпоинты.
---
## Статус
| Компонент | Готов? |
|-----------|--------|
| Frontend (Angular) — диалог, QR, поллинг, корзина | ✅ Готов |
| Telegram бот (обработка `/start`) | ❌ Нужно |
| Backend — 6 HTTP-эндпоинтов | ❌ Нужно |
| Хранилище сессий + QR-токенов | ❌ Нужно |
| CORS для cookie-based запросов | ❌ Нужно |
---
## Архитектура
Два сценария авторизации:
### Сценарий 1: Прямой вход (кнопка "Войти через Telegram")
Пользователь нажимает кнопку → открывается Telegram → бот выдаёт кнопку "Войти на сайт" → callback ставит cookie → фронтенд поллит `/auth/session`.
### Сценарий 2: QR-логин с десктопа (основной)
```
ДЕСКТОП БРАУЗЕР СЕРВЕР (Go) TELEGRAM
│ │ │
│ 1. POST /auth/qr/create │ │
│ ─────────────────────────────> │ │
│ { token: "abc", url: "..." } │ │
│ <───────────────────────────── │ │
│ │ │
│ 2. Показать QR: │ │
│ t.me/Bot?start=login_abc │ │
│ │ │
│ ПОЛЬЗОВАТЕЛЬ СКАНИРУЕТ ТЕЛЕФОНОМ │
│ │ │
│ │ 3. /start login_abc │
│ │ <────────────────────────│
│ │ │
│ │ Бот → POST /auth/qr/confirm
│ │ Бот → "✅ Вы вошли!" │
│ │ ────────────────────────>│
│ │ │
│ 4. GET /auth/qr/poll?token=abc │ │
│ (каждые 3 сек) │ │
│ ─────────────────────────────> │ │
│ { status: "confirmed", │ │
│ session: {...} } │ │
│ + Set-Cookie: dx_session=... │ │
│ <───────────────────────────── │ │
│ │ │
│ 5. POST /websession/{sessionId} │ │
│ [{ itemID, quantity, ... }] │ ← корзина │
│ ─────────────────────────────> │ │
│ │ │
│ 6. Готово! Авторизован + корзина│ │
```
---
## Бренды и боты
| Бренд | Username бота | Домен фронтенда | API сервер | Cookie Domain |
|-------|---------------|------------------|------------|---------------|
| Dexar | `DexarSupport_bot` | `dexarmarket.ru` | `api.dexarmarket.ru:445` | `.dexarmarket.ru` |
| Novo | `novomarket_bot` | `novo.market` | `api.novo.market:444` | `.novo.market` |
Бот создаётся через https://t.me/BotFather → `/newbot`. Сохранить `BOT_TOKEN`.
---
## Хранилище
### Структура: Сессия
```go
type Session struct {
SessionID string `json:"sessionId"`
TelegramUserID int64 `json:"telegramUserId"`
Username *string `json:"username"` // может быть null
DisplayName string `json:"displayName"`
Active bool `json:"active"`
ExpiresAt time.Time `json:"expiresAt"`
}
```
**TTL:** 24 часа.
### Структура: QR-токен (одноразовый)
```go
type AuthToken struct {
Token string `json:"token"`
Status string `json:"status"` // "pending" | "confirmed" | "expired"
SessionID string `json:"sessionId"` // заполняется после подтверждения ботом
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt"`
}
```
**TTL:** 5 минут.
### Варианты хранения
**Redis (рекомендуется):**
```go
// Сессия
redisClient.Set(ctx, "session:"+s.SessionID, json, 24*time.Hour)
// QR-токен
redisClient.Set(ctx, "auth_token:"+t.Token, json, 5*time.Minute)
```
**sync.Map (для MVP):**
```go
var sessions sync.Map
var authTokens sync.Map
// Очистка устаревших токенов — запустить горутину при старте
func cleanupExpiredTokens() {
ticker := time.NewTicker(1 * time.Minute)
for range ticker.C {
authTokens.Range(func(key, value any) bool {
t := value.(AuthToken)
if time.Now().After(t.ExpiresAt) {
authTokens.Delete(key)
}
return true
})
}
}
```
---
## HTTP-эндпоинты
### 1. `POST /auth/qr/create`
Фронтенд вызывает при открытии диалога логина. Создаёт одноразовый QR-токен.
```go
func handleQrCreate(w http.ResponseWriter, r *http.Request) {
// 1. Сгенерировать криптографически безопасный токен
tokenBytes := make([]byte, 32)
if _, err := rand.Read(tokenBytes); err != nil {
http.Error(w, "internal error", 500)
return
}
token := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(tokenBytes)
// 2. Определить бота по origin
botUsername := getBotForOrigin(r.Header.Get("Origin"))
// 3. Сохранить токен
authToken := AuthToken{
Token: token,
Status: "pending",
CreatedAt: time.Now(),
ExpiresAt: time.Now().Add(5 * time.Minute),
}
saveAuthToken(authToken)
// 4. Ответить
qrURL := fmt.Sprintf("https://t.me/%s?start=login_%s", botUsername, token)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"token": token,
"url": qrURL,
})
}
func getBotForOrigin(origin string) string {
if strings.Contains(origin, "novo.market") {
return "novomarket_bot"
}
return "DexarSupport_bot"
}
```
**Ответ:**
```json
{ "token": "dG9rZW4tYWJj....", "url": "https://t.me/DexarSupport_bot?start=login_dG9rZW4tYWJj...." }
```
> Telegram ограничивает `start` до 64 символов. `login_` (6) + base64url из 32 байт (43) = 49 ✅
---
### 2. `GET /auth/qr/poll?token={token}`
Фронтенд вызывает каждые 3 секунды. Когда бот подтвердил — возвращает сессию и ставит cookie.
```go
func handleQrPoll(w http.ResponseWriter, r *http.Request) {
tokenStr := r.URL.Query().Get("token")
if tokenStr == "" {
http.Error(w, "missing token", 400)
return
}
authToken, ok := getAuthToken(tokenStr)
if !ok {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "expired"})
return
}
switch authToken.Status {
case "pending":
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "pending"})
case "confirmed":
session, err := getSession(authToken.SessionID)
if err != nil {
http.Error(w, "session not found", 500)
return
}
// Cookie в ДЕСКТОПНЫЙ браузер
domain := getDomainForOrigin(r.Header.Get("Origin"))
http.SetCookie(w, &http.Cookie{
Name: "dx_session",
Value: session.SessionID,
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteNoneMode,
MaxAge: 86400,
Domain: domain,
})
// Удалить использованный токен
deleteAuthToken(tokenStr)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"status": "confirmed",
"session": session,
})
}
}
func getDomainForOrigin(origin string) string {
if strings.Contains(origin, "novo.market") {
return ".novo.market"
}
return ".dexarmarket.ru"
}
```
**Ответы:**
| Статус | JSON |
|--------|------|
| Ждём | `{ "status": "pending" }` |
| Подтверждено | `{ "status": "confirmed", "session": { sessionId, telegramUserId, username, displayName, active, expiresAt } }` + `Set-Cookie` |
| Истекло | `{ "status": "expired" }` |
---
### 3. `POST /auth/qr/confirm` (внутренний, для бота)
Бот вызывает когда пользователь отсканировал QR. Привязывает сессию к токену.
```go
func handleQrConfirm(w http.ResponseWriter, r *http.Request) {
// Проверить секрет бота
if r.Header.Get("X-Bot-Secret") != os.Getenv("BOT_INTERNAL_SECRET") {
http.Error(w, "forbidden", 403)
return
}
var req struct {
Token string `json:"token"`
User struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
} `json:"telegram_user"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "bad request", 400)
return
}
authToken, ok := getAuthToken(req.Token)
if !ok || authToken.Status != "pending" {
http.Error(w, "token not found or already used", 404)
return
}
// Создать сессию
displayName := req.User.FirstName
if req.User.LastName != "" {
displayName += " " + req.User.LastName
}
var username *string
if req.User.Username != "" {
username = &req.User.Username
}
session := Session{
SessionID: uuid.New().String(),
TelegramUserID: req.User.ID,
Username: username,
DisplayName: displayName,
Active: true,
ExpiresAt: time.Now().Add(24 * time.Hour),
}
saveSession(session)
// Привязать сессию к токену
authToken.Status = "confirmed"
authToken.SessionID = session.SessionID
saveAuthToken(*authToken)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
```
**Запрос от бота:**
```json
{
"token": "dG9rZW4tYWJj...",
"telegram_user": {
"id": 123456789,
"first_name": "Иван",
"last_name": "Петров",
"username": "ivan_petrov"
}
}
```
---
### 4. `GET /auth/session`
Фронтенд вызывает для проверки текущей сессии. Читает cookie.
```go
func handleGetSession(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("dx_session")
if err != nil {
http.Error(w, "unauthorized", 401)
return
}
session, err := getSession(cookie.Value)
if err != nil {
http.Error(w, "unauthorized", 401)
return
}
if time.Now().After(session.ExpiresAt) {
session.Active = false
saveSession(session)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(session)
}
```
**Формат ответа (200)** — фронтенд ожидает **точно эти поля**:
```json
{
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"telegramUserId": 123456789,
"username": "ivan_petrov",
"displayName": "Иван Петров",
"active": true,
"expiresAt": "2026-03-25T14:30:00Z"
}
```
| Поле | Тип | Обязательно | Примечание |
|------|-----|-------------|------------|
| `sessionId` | string (UUID) | да | Используется для `/websession/{sessionId}` |
| `telegramUserId` | number | да | Telegram user ID |
| `username` | string / null | нет | Telegram @username |
| `displayName` | string | да | "Имя Фамилия" — показывается в UI |
| `active` | boolean | да | `false` = истекла |
| `expiresAt` | string (ISO 8601) | да | Фронтенд перепроверяет за 60 сек до |
**Ошибка:** любой HTTP не-200 → фронтенд считает "не авторизован".
---
### 5. `GET /auth/telegram/callback`
Для прямого входа (по кнопке в Telegram, не через QR). Открывается в браузере.
```go
func handleTelegramCallback(w http.ResponseWriter, r *http.Request) {
token := r.URL.Query().Get("token")
if token == "" {
http.Error(w, "missing token", 400)
return
}
session, err := getSession(token)
if err != nil || !session.Active {
http.Error(w, "invalid or expired token", 401)
return
}
domain := getDomainForOrigin(r.Header.Get("Origin"))
if domain == "" {
domain = ".dexarmarket.ru" // fallback для прямого перехода
}
http.SetCookie(w, &http.Cookie{
Name: "dx_session",
Value: session.SessionID,
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteNoneMode,
MaxAge: 86400,
Domain: domain,
})
// Редирект на сайт
http.Redirect(w, r, "https://dexarmarket.ru", http.StatusFound)
}
```
---
### 6. `POST /auth/logout`
```go
func handleLogout(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("dx_session")
if err == nil {
deleteSession(cookie.Value)
}
http.SetCookie(w, &http.Cookie{
Name: "dx_session",
Value: "",
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteNoneMode,
MaxAge: -1,
Domain: ".dexarmarket.ru",
})
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"message":"ok"}`))
}
```
---
## Cookie-параметры
| Параметр | Значение | Почему |
|----------|----------|--------|
| `Name` | `dx_session` | |
| `SameSite` | `None` | Фронтенд на `dexarmarket.ru`, API на `api.dexarmarket.ru:445` — разные origins |
| `Secure` | `true` | Обязательно при `SameSite=None` |
| `Domain` | `.dexarmarket.ru` | Доступна и на `dexarmarket.ru` и на `api.dexarmarket.ru` |
| `HttpOnly` | `true` | Недоступна из JS — защита от XSS |
| `MaxAge` | `86400` | 24 часа |
---
## CORS
Фронтенд шлёт `withCredentials: true`. Бэкенд обязан вернуть правильные заголовки.
```go
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
allowed := map[string]bool{
"https://dexarmarket.ru": true,
"https://www.dexarmarket.ru": true,
"https://novo.market": true,
"https://www.novo.market": true,
"http://localhost:4200": true,
}
if allowed[origin] {
w.Header().Set("Access-Control-Allow-Origin", origin) // НЕ "*"
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
}
if r.Method == "OPTIONS" {
w.WriteHeader(200)
return
}
next.ServeHTTP(w, r)
})
}
```
> **Критично:** `Access-Control-Allow-Origin` не может быть `"*"` при `withCredentials`. Вернуть конкретный origin.
---
## Роутинг
```go
mux := http.NewServeMux()
// Существующие
mux.HandleFunc("GET /items/{id}", handleGetItem)
mux.HandleFunc("GET /category", handleGetCategories)
mux.HandleFunc("POST /websession/{id}", handleWebSession)
mux.HandleFunc("POST /websession/{id}/qr", handleCreateQR)
mux.HandleFunc("GET /websession/{id}/{qrId}", handleCheckPayment)
// Auth — прямой вход
mux.HandleFunc("GET /auth/session", handleGetSession)
mux.HandleFunc("GET /auth/telegram/callback", handleTelegramCallback)
mux.HandleFunc("POST /auth/logout", handleLogout)
// Auth — QR-логин
mux.HandleFunc("POST /auth/qr/create", handleQrCreate)
mux.HandleFunc("GET /auth/qr/poll", handleQrPoll)
mux.HandleFunc("POST /auth/qr/confirm", handleQrConfirm)
handler := corsMiddleware(mux)
http.ListenAndServeTLS(":445", "cert.pem", "key.pem", handler)
```
---
## Telegram-бот
### Обработчик `/start`
```go
const (
confirmURL = "http://localhost:8080/auth/qr/confirm"
botInternalSecret = os.Getenv("BOT_INTERNAL_SECRET")
)
func handleStart(update tgbotapi.Update) {
text := update.Message.Text
user := update.Message.From
switch {
case strings.HasPrefix(text, "/start login_"):
handleQrLogin(update, user, strings.TrimPrefix(text, "/start login_"))
case strings.HasPrefix(text, "/start auth"):
handleDirectAuth(update, user)
default:
sendWelcome(update)
}
}
```
### QR-логин (основной)
```go
func handleQrLogin(update tgbotapi.Update, user *tgbotapi.User, token string) {
reqBody := map[string]interface{}{
"token": token,
"telegram_user": map[string]interface{}{
"id": user.ID,
"first_name": user.FirstName,
"last_name": user.LastName,
"username": user.UserName,
},
}
bodyBytes, _ := json.Marshal(reqBody)
req, _ := http.NewRequest("POST", confirmURL, bytes.NewReader(bodyBytes))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Bot-Secret", botInternalSecret)
resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode != 200 {
msg := tgbotapi.NewMessage(update.Message.Chat.ID,
"❌ Не удалось войти. QR-код мог устареть. Попробуйте обновить страницу и отсканировать новый QR.")
bot.Send(msg)
return
}
defer resp.Body.Close()
displayName := buildDisplayName(user)
msg := tgbotapi.NewMessage(update.Message.Chat.ID,
fmt.Sprintf("✅ Вы вошли на сайт как %s!\n\nМожете вернуться в браузер — страница обновится автоматически.", displayName))
bot.Send(msg)
}
func buildDisplayName(user *tgbotapi.User) string {
name := user.FirstName
if user.LastName != "" {
name += " " + user.LastName
}
return name
}
```
### Прямой вход (кнопка, для обратной совместимости)
```go
func handleDirectAuth(update tgbotapi.Update, user *tgbotapi.User) {
session := Session{
SessionID: uuid.New().String(),
TelegramUserID: user.ID,
Username: stringPtr(user.UserName),
DisplayName: buildDisplayName(user),
Active: true,
ExpiresAt: time.Now().Add(24 * time.Hour),
}
saveSession(session)
callbackURL := "https://api.dexarmarket.ru:445/auth/telegram/callback"
loginURL := callbackURL + "?token=" + session.SessionID
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Нажмите кнопку чтобы войти:")
msg.ReplyMarkup = tgbotapi.NewInlineKeyboardMarkup(
tgbotapi.NewInlineKeyboardRow(
tgbotapi.NewInlineKeyboardButtonURL("🔐 Войти на сайт", loginURL),
),
)
bot.Send(msg)
}
```
### Запуск бота (long polling)
```go
func main() {
bot, _ := tgbotapi.NewBotAPI(os.Getenv("BOT_TOKEN"))
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
updates := bot.GetUpdatesChan(u)
for update := range updates {
if update.Message != nil && strings.HasPrefix(update.Message.Text, "/start") {
handleStart(update)
}
}
}
```
---
## Синхронизация корзины
Сразу после QR-логина фронтенд автоматически отправляет корзину:
```
POST /websession/{sessionId}
```
Тело — массив:
```json
[
{
"itemID": 123,
"quantity": 2,
"colour": "#ff0000",
"size": "XL",
"price": 1500
}
]
```
| Поле | Тип | Примечание |
|------|-----|------------|
| `itemID` | number | ID товара |
| `quantity` | number | Количество |
| `colour` | string | CSS hex (`#ff0000`). Бэкенд отдаёт `0xff0000`, фронтенд конвертирует |
| `size` | string | `"default"` если размер один |
| `price` | number | Финальная цена **с учётом скидки** |
> Этот эндпоинт (`POST /websession/{id}`) уже существует. Ничего менять не нужно, просто учитывать что он вызывается сразу после успешного логина.
---
## Безопасность
### Криптографический токен
```go
tokenBytes := make([]byte, 32) // 256 бит
crypto/rand.Read(tokenBytes)
token := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(tokenBytes)
```
**НЕ использовать:** `math/rand`, UUID, timestamp.
### Токен одноразовый
- После `confirmed` → удалить при первом успешном `poll`
- После 5 минут → автоудаление (TTL)
- Повторный `poll``"expired"`
### Защита `/auth/qr/confirm`
```go
if r.Header.Get("X-Bot-Secret") != os.Getenv("BOT_INTERNAL_SECRET") {
http.Error(w, "forbidden", 403)
return
}
```
Дополнительно: можно ограничить по IP (`127.0.0.1`) если бот на том же сервере.
### Rate limiting для `/auth/qr/create`
Не более **5 токенов в минуту** с одного IP:
```go
var ipCounts sync.Map
func rateLimitQrCreate(ip string) bool {
key := ip + ":" + time.Now().Format("2006-01-02T15:04")
val, _ := ipCounts.LoadOrStore(key, new(int32))
count := atomic.AddInt32(val.(*int32), 1)
return count <= 5
}
```
---
## Переменные окружения
```env
BOT_TOKEN=123456:ABC-DEF...
BOT_INTERNAL_SECRET=случайная-строка-минимум-32-символа
FRONTEND_URL=https://dexarmarket.ru
SESSION_TTL=24h
REDIS_URL=localhost:6379
```
`BOT_INTERNAL_SECRET` должен совпадать в env сервера и env бота.
---
## Тестирование
### curl-тесты
**1. Создание токена:**
```bash
curl -X POST https://api.dexarmarket.ru:445/auth/qr/create \
-H "Origin: https://dexarmarket.ru"
# → { "token": "dG9r...", "url": "https://t.me/DexarSupport_bot?start=login_dG9r..." }
```
**2. Поллинг (до подтверждения):**
```bash
curl "https://api.dexarmarket.ru:445/auth/qr/poll?token=dG9r..."
# → { "status": "pending" }
```
**3. Подтверждение (имитация бота):**
```bash
curl -X POST https://api.dexarmarket.ru:445/auth/qr/confirm \
-H "Content-Type: application/json" \
-H "X-Bot-Secret: ваш-секрет" \
-d '{"token":"dG9r...","telegram_user":{"id":123,"first_name":"Тест","last_name":"","username":"testuser"}}'
# → { "status": "ok" }
```
**4. Поллинг (после подтверждения):**
```bash
curl -v "https://api.dexarmarket.ru:445/auth/qr/poll?token=dG9r..."
# → { "status": "confirmed", "session": {...} } + Set-Cookie: dx_session=...
```
**5. E2E:**
1. Открыть маркетплейс → добавить товар в корзину
2. Нажать "Оформить заказ" → появляется диалог с QR
3. Отсканировать QR телефоном → Telegram → бот: "✅ Вы вошли!"
4. Через 3 сек диалог закрывается → авторизован
5. Корзина синхронизирована (`POST /websession/{sessionId}`)
### Отладка
| Проблема | Где смотреть |
|----------|-------------|
| QR не показывается | `POST /auth/qr/create` — ошибка? CORS? |
| QR отсканирован, ничего не происходит | Бот получил `/start login_...`? Бот вызвал `confirm`? |
| Бот пишет "❌ QR устарел" | Токен expired? 5 минут прошло? |
| Поллинг "pending" бесконечно | Бот не вызвал `confirm`. Логи бота |
| Поллинг "confirmed" но cookie нет | `SameSite`, `Secure`, `Domain`, CORS |
---
## Чеклист
### Бэкенд (Go)
- [ ] Структура `Session` + `AuthToken`, функции save/get/delete
- [ ] `POST /auth/qr/create` — генерация токена
- [ ] `GET /auth/qr/poll?token=...` — статус + cookie при confirmed
- [ ] `POST /auth/qr/confirm` — приём от бота с `X-Bot-Secret`
- [ ] `GET /auth/session` — чтение cookie, JSON сессии
- [ ] `GET /auth/telegram/callback?token=...` — cookie + редирект
- [ ] `POST /auth/logout` — удаление сессии и cookie
- [ ] TTL 5 мин для токенов, 24ч для сессий
- [ ] Rate limiting `/auth/qr/create` (5/мин/IP)
- [ ] Очистка устаревших токенов
- [ ] CORS middleware
- [ ] `BOT_INTERNAL_SECRET` в env
### Telegram бот
- [ ] Обработка `/start login_{token}``POST /auth/qr/confirm`
- [ ] Обработка `/start auth` → создание сессии + кнопка "Войти"
- [ ] Сообщения: "✅ Вы вошли" / "❌ QR устарел"
- [ ] `BOT_INTERNAL_SECRET` в env (совпадает с сервером)
- [ ] `BOT_TOKEN` в env

View File

@@ -0,0 +1,327 @@
# Telegram UserAuth Backend Contract
This document extracts the existing Telegram login flow into a repo-neutral contract for reuse in other projects.
The UI behavior, payloads, polling cadence, and session model stay the same. Only route names and cookie naming are generalized.
## Endpoint Renaming
| Current app contract | Reusable contract |
|---|---|
| `GET /auth/session` | `GET /userauth/session` |
| `POST /auth/qr/create` | `POST /userauth/qr/create` |
| `GET /auth/qr/poll?token=...` | `GET /userauth/qr/poll?token=...` |
| `POST /auth/qr/confirm` | `POST /userauth/qr/confirm` |
| `GET /auth/telegram/callback` | `GET /userauth/telegram/callback` |
| `POST /auth/logout` | `POST /userauth/logout` |
| `POST /websession/{sessionId}` | `POST /usersession/{sessionId}` |
| Cookie `dx_session` | Cookie `userauth_session` |
## Flow Summary
There are two supported flows.
### 1. Direct login from button
1. Frontend opens `https://t.me/{botUsername}?start=auth_{callbackUrl}`.
2. Telegram bot creates a session and sends the user a login button.
3. The button points to `GET /userauth/telegram/callback?token={sessionId}`.
4. Backend sets `userauth_session` cookie and redirects back to the storefront.
5. Frontend calls `GET /userauth/session` and becomes authenticated.
### 2. QR login from desktop
1. Frontend opens dialog.
2. Frontend calls `POST /userauth/qr/create`.
3. Backend returns `{ token, url }` where `url` is a Telegram deep link.
4. Frontend renders a QR from that URL.
5. User scans QR and bot calls `POST /userauth/qr/confirm`.
6. Frontend polls `GET /userauth/qr/poll?token=...` every 3 seconds.
7. When status becomes `confirmed`, backend returns session payload and sets the cookie.
8. Frontend syncs local cart using `POST /usersession/{sessionId}`.
## Session Shape
The frontend expects this exact response shape for the authenticated session.
```json
{
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"telegramUserId": 123456789,
"username": "ivan_petrov",
"displayName": "Ivan Petrov",
"active": true,
"expiresAt": "2026-05-21T14:30:00Z"
}
```
| Field | Type | Required | Notes |
|---|---|---|---|
| `sessionId` | string | yes | Session identifier used in cart sync |
| `telegramUserId` | number | yes | Telegram user ID |
| `username` | string or null | no | Telegram username |
| `displayName` | string | yes | User-facing full name |
| `active` | boolean | yes | `false` means expired session |
| `expiresAt` | ISO 8601 string | yes | Used by frontend refresh scheduling |
Recommended TTL:
- Session TTL: 24 hours
- QR token TTL: 5 minutes
## HTTP Contract
### `POST /userauth/qr/create`
Creates a one-time QR login token when the dialog opens.
Request body:
```json
{}
```
Response `200`:
```json
{
"token": "dG9rZW4tYWJjMTIz",
"url": "https://t.me/userauth_bot?start=login_dG9rZW4tYWJjMTIz"
}
```
Requirements:
- Generate a cryptographically secure token.
- Save token with status `pending`.
- Return a Telegram deep link in `url`.
- Rate limit to 5 requests per minute per IP.
### `GET /userauth/qr/poll?token={token}`
Called every 3 seconds until confirmation or expiration.
Possible responses:
Pending:
```json
{ "status": "pending" }
```
Confirmed:
```json
{
"status": "confirmed",
"session": {
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"telegramUserId": 123456789,
"username": "ivan_petrov",
"displayName": "Ivan Petrov",
"active": true,
"expiresAt": "2026-05-21T14:30:00Z"
}
}
```
Expired:
```json
{ "status": "expired" }
```
Behavior:
- If confirmed, set cookie `userauth_session` in the response.
- Delete or invalidate the QR token after the first successful confirmed poll.
- If token is unknown or expired, return `status: "expired"`.
### `POST /userauth/qr/confirm`
Internal endpoint called by the Telegram bot after the user scans the QR code.
Required header:
```text
X-Bot-Secret: <shared secret between bot and backend>
```
Request body:
```json
{
"token": "dG9rZW4tYWJjMTIz",
"telegram_user": {
"id": 123456789,
"first_name": "Ivan",
"last_name": "Petrov",
"username": "ivan_petrov"
}
}
```
Response `200`:
```json
{ "status": "ok" }
```
Behavior:
- Validate `X-Bot-Secret`.
- Validate token exists and is still `pending`.
- Create a user session.
- Store session ID on the QR token.
- Mark QR token as `confirmed`.
### `GET /userauth/session`
Returns the currently active session based on the cookie.
Frontend behavior depends on this endpoint in two places:
- initial auth check on app startup
- fallback polling if QR token creation fails
Response `200`:
```json
{
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"telegramUserId": 123456789,
"username": "ivan_petrov",
"displayName": "Ivan Petrov",
"active": true,
"expiresAt": "2026-05-21T14:30:00Z"
}
```
Error handling:
- Any non-200 response is treated by the frontend as unauthenticated.
### `GET /userauth/telegram/callback?token={sessionId}`
Used for direct Telegram login from the primary button flow.
Behavior:
- Read the `token` query param.
- Resolve it to a valid active session.
- Set cookie `userauth_session`.
- Redirect user to the storefront URL.
### `POST /userauth/logout`
Clears the backend session and expires the cookie.
Request body:
```json
{}
```
Response `200`:
```json
{ "message": "ok" }
```
### `POST /usersession/{sessionId}`
Synchronizes local cart immediately after successful login.
Request body:
```json
[
{
"itemID": 123,
"quantity": 2,
"colour": "#ff0000",
"size": "XL",
"price": 1500
}
]
```
Notes:
- This payload is unchanged from the existing implementation.
- `price` is already discounted on the frontend side.
- The frontend skips the call if cart is empty.
## Telegram Deep Link Format
Direct login link format:
```text
https://t.me/{botUsername}?start=auth_{urlEncodedCallbackUrl}
```
QR login link format:
```text
https://t.me/{botUsername}?start=login_{qrToken}
```
Important limit:
- Telegram limits the `start` payload to 64 characters.
- A base64url encoding of 32 random bytes plus `login_` fits safely.
## Cookie Requirements
Use these cookie settings for the frontend to work correctly across site and API origins.
| Property | Value |
|---|---|
| Name | `userauth_session` |
| Path | `/` |
| HttpOnly | `true` |
| Secure | `true` |
| SameSite | `None` |
| MaxAge | `86400` |
| Domain | your shared parent domain, for example `.example.com` |
## CORS Requirements
Because the frontend sends credentials, backend must return an explicit origin.
Required headers:
```text
Access-Control-Allow-Origin: https://your-frontend.example
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
```
Do not use `*` for `Access-Control-Allow-Origin` together with credentials.
## Frontend Runtime Expectations
The current dialog behavior is fixed and should be preserved by backend responses.
- QR polling interval: every 3 seconds
- QR expiration on frontend: after 100 checks
- If QR creation fails, frontend falls back to direct login URL and session polling
- After login, frontend closes the dialog and re-checks session
## Minimal Backend Checklist
- Implement all six `userauth` endpoints and the `usersession` sync endpoint.
- Store sessions for 24 hours.
- Store QR tokens for 5 minutes.
- Protect `POST /userauth/qr/confirm` with `X-Bot-Secret`.
- Set `userauth_session` cookie on confirmed QR poll and direct callback.
- Return the exact session JSON shape.
- Support credentialed CORS.
## Bot Checklist
- Handle `/start login_{token}` and call `POST /userauth/qr/confirm`.
- Handle `/start auth_{callbackUrl}` and provide a button that opens the callback URL.
- Send success and expiration messages back to the user.
- Share the same `X-Bot-Secret` value with backend.

View File

@@ -0,0 +1,551 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Telegram Login Dialog</title>
<style>
:root {
--bg-page: linear-gradient(135deg, #f4f7fb 0%, #e8eef4 100%);
--bg-card: #ffffff;
--bg-hover: #f0f0f0;
--text-primary: #1a1a1a;
--text-secondary: #666666;
--accent-color: #497671;
--accent-light: rgba(73, 118, 113, 0.1);
--telegram: #2aabee;
--telegram-hover: #229ed9;
--border: #e8e8e8;
--shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
color: var(--text-primary);
background: var(--bg-page);
}
.page {
min-height: 100vh;
display: grid;
grid-template-columns: minmax(320px, 448px) minmax(320px, 560px);
gap: 32px;
padding: 40px 32px;
align-items: center;
justify-content: center;
}
.panel {
background: rgba(255, 255, 255, 0.72);
border: 1px solid rgba(255, 255, 255, 0.8);
border-radius: 28px;
padding: 24px;
box-shadow: 0 18px 50px rgba(38, 52, 73, 0.12);
backdrop-filter: blur(14px);
}
.info h1 {
margin: 0 0 12px;
font-size: 32px;
line-height: 1.1;
}
.info p {
margin: 0 0 18px;
color: var(--text-secondary);
line-height: 1.6;
}
.state-switcher {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 20px 0 24px;
}
.state-switcher button {
border: 1px solid #cfd8e3;
border-radius: 999px;
background: #fff;
color: var(--text-primary);
padding: 10px 14px;
font-size: 14px;
cursor: pointer;
transition: 0.2s ease;
}
.state-switcher button.active {
border-color: var(--accent-color);
background: var(--accent-light);
color: var(--accent-color);
}
.api-grid {
display: grid;
gap: 12px;
margin-top: 20px;
}
.api-card {
background: #fff;
border: 1px solid #eef2f7;
border-radius: 16px;
padding: 14px 16px;
}
.api-card strong {
display: block;
margin-bottom: 6px;
font-size: 14px;
}
.api-card code {
display: inline-block;
padding: 2px 8px;
border-radius: 999px;
background: #f3f7fb;
color: #21425f;
font-size: 13px;
}
.api-card p {
margin: 8px 0 0;
font-size: 13px;
}
.login-overlay {
position: relative;
min-height: 700px;
border-radius: 28px;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
display: flex;
align-items: center;
justify-content: center;
animation: fadeIn 0.2s ease;
padding: 16px;
}
.login-dialog {
position: relative;
background: var(--bg-card);
border-radius: 20px;
padding: 32px 28px;
max-width: 400px;
width: 100%;
text-align: center;
box-shadow: var(--shadow);
animation: scaleIn 0.25s ease;
}
.close-btn {
position: absolute;
top: 12px;
right: 12px;
width: 32px;
height: 32px;
border: none;
border-radius: 50%;
background: var(--bg-hover);
color: var(--text-secondary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
}
.close-btn:hover {
background: #e0e0e0;
color: #333;
}
.login-icon {
margin: 0 auto 16px;
width: 72px;
height: 72px;
border-radius: 50%;
background: var(--accent-light);
color: var(--accent-color);
display: flex;
align-items: center;
justify-content: center;
}
.login-dialog h2 {
margin: 0 0 8px;
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
}
.login-desc {
margin: 0 0 24px;
font-size: 14px;
color: var(--text-secondary);
line-height: 1.5;
}
.telegram-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
padding: 14px 24px;
border: none;
border-radius: 12px;
background: var(--telegram);
color: #fff;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
.telegram-btn:hover {
background: var(--telegram-hover);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(42, 171, 238, 0.3);
}
.telegram-btn:active {
transform: translateY(0);
}
.tg-icon {
flex-shrink: 0;
}
.qr-section {
margin-top: 20px;
}
.qr-hint {
margin: 0 0 12px;
font-size: 13px;
color: #999;
}
.qr-container {
display: inline-flex;
padding: 12px;
background: #fff;
border-radius: 12px;
border: 1px solid var(--border);
}
.qr-container img {
display: block;
border-radius: 4px;
}
.qr-loading {
align-items: center;
justify-content: center;
width: 204px;
height: 204px;
}
.qr-loading .spinner,
.login-status .spinner {
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
.qr-loading .spinner {
width: 32px;
height: 32px;
border: 3px solid #e0e0e0;
border-top-color: var(--accent-color);
}
.qr-expired {
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
width: 204px;
height: 204px;
cursor: pointer;
color: #999;
transition: color 0.2s ease;
}
.qr-expired:hover {
color: var(--accent-color);
}
.qr-expired span {
font-size: 13px;
}
.login-note {
margin: 16px 0 0;
font-size: 12px;
color: #999;
line-height: 1.4;
}
.login-status {
display: none;
align-items: center;
justify-content: center;
gap: 10px;
padding: 16px;
color: var(--text-secondary);
font-size: 14px;
}
.login-status .spinner {
width: 20px;
height: 20px;
border: 2px solid #e0e0e0;
border-top-color: var(--accent-color);
}
.dialog-content[data-state="checking"] .login-status {
display: flex;
}
.dialog-content[data-state="checking"] .action-block,
.dialog-content[data-state="loading"] .qr-ready,
.dialog-content[data-state="loading"] .qr-expired,
.dialog-content[data-state="expired"] .qr-ready,
.dialog-content[data-state="expired"] .qr-loading,
.dialog-content[data-state="error"] .qr-loading,
.dialog-content[data-state="error"] .qr-expired,
.dialog-content[data-state="checking"] .qr-section,
.dialog-content[data-state="checking"] .login-note {
display: none;
}
.dialog-content[data-state="ready"] .qr-loading,
.dialog-content[data-state="ready"] .qr-expired,
.dialog-content[data-state="ready"] .qr-error,
.dialog-content[data-state="loading"] .qr-ready,
.dialog-content[data-state="loading"] .qr-expired,
.dialog-content[data-state="loading"] .qr-error,
.dialog-content[data-state="expired"] .qr-loading,
.dialog-content[data-state="expired"] .qr-ready,
.dialog-content[data-state="expired"] .qr-error,
.dialog-content[data-state="error"] .qr-loading,
.dialog-content[data-state="error"] .qr-expired {
display: none;
}
.dialog-content[data-state="error"] .qr-ready {
display: inline-flex;
}
.metadata {
margin-top: 22px;
padding-top: 18px;
border-top: 1px solid #e9edf2;
font-size: 13px;
color: var(--text-secondary);
}
.metadata ul {
margin: 10px 0 0;
padding-left: 18px;
}
.metadata li + li {
margin-top: 6px;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@media (max-width: 980px) {
.page {
grid-template-columns: 1fr;
padding: 24px 16px 32px;
}
.login-overlay {
min-height: 560px;
}
}
@media (max-width: 480px) {
.panel {
border-radius: 22px;
padding: 18px;
}
.login-dialog {
padding: 24px 20px;
border-radius: 16px;
}
.qr-container img {
width: 140px;
height: 140px;
}
.qr-loading,
.qr-expired {
width: 164px;
height: 164px;
}
}
</style>
</head>
<body>
<main class="page">
<section class="panel info">
<h1>Telegram Login Dialog</h1>
<p>
Standalone extraction of the current login popup: same layout, same visual states,
same QR flow, but with reusable neutral endpoint names for moving into a separate repo.
</p>
<div class="state-switcher" aria-label="Dialog state switcher">
<button class="active" data-state-btn="ready" type="button">Ready</button>
<button data-state-btn="loading" type="button">QR Loading</button>
<button data-state-btn="checking" type="button">Checking</button>
<button data-state-btn="expired" type="button">Expired</button>
<button data-state-btn="error" type="button">Fallback</button>
</div>
<div class="api-grid">
<div class="api-card">
<strong>Start QR session</strong>
<code>POST /userauth/qr/create</code>
<p>Returns a one-time token and Telegram deeplink for the QR image.</p>
</div>
<div class="api-card">
<strong>Poll QR confirmation</strong>
<code>GET /userauth/qr/poll?token=...</code>
<p>Returns pending, confirmed, or expired. On confirmed, also returns the user session.</p>
</div>
<div class="api-card">
<strong>Read current session</strong>
<code>GET /userauth/session</code>
<p>Cookie-based session lookup used for initial auth check and fallback polling.</p>
</div>
<div class="api-card">
<strong>Sync cart after login</strong>
<code>POST /usersession/{sessionId}</code>
<p>Existing cart payload is preserved. Only the namespace is generalized for reuse.</p>
</div>
</div>
<div class="metadata">
<strong>Behavior kept intact</strong>
<ul>
<li>Open Telegram directly from the primary button.</li>
<li>Show QR immediately and poll every 3 seconds.</li>
<li>Expire the QR after 100 checks and allow manual refresh.</li>
<li>Re-check cookie session if QR creation fails.</li>
</ul>
</div>
</section>
<section class="panel">
<div class="login-overlay">
<div class="login-dialog">
<button class="close-btn" type="button" aria-label="Close dialog">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 6L6 18M6 6l12 12"></path>
</svg>
</button>
<div class="dialog-content" data-state="ready" id="dialog-content">
<div class="login-icon">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path>
</svg>
</div>
<h2>Login required</h2>
<p class="login-desc">Please log in via Telegram to proceed with your order.</p>
<div class="login-status checking">
<div class="spinner"></div>
<span>Checking...</span>
</div>
<div class="action-block">
<button class="telegram-btn" type="button">
<svg class="tg-icon" width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"></path>
</svg>
Log in with Telegram
</button>
<div class="qr-section">
<p class="qr-hint">Or scan the QR code</p>
<div class="qr-container qr-loading">
<div class="spinner"></div>
</div>
<div class="qr-container qr-ready">
<img
src="https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=https%3A%2F%2Ft.me%2Fuserauth_bot%3Fstart%3Dlogin_sample_token"
alt="QR Code"
width="180"
height="180"
loading="eager"
/>
</div>
<div class="qr-container qr-expired" role="button" tabindex="0" aria-label="Refresh QR code">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M1 4v6h6M23 20v-6h-6"></path>
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path>
</svg>
<span>QR code expired. Click to refresh</span>
</div>
</div>
<p class="login-note">You will be redirected back after login.</p>
</div>
</div>
</div>
</div>
</section>
</main>
<script>
const content = document.getElementById('dialog-content');
const buttons = document.querySelectorAll('[data-state-btn]');
buttons.forEach((button) => {
button.addEventListener('click', () => {
const state = button.getAttribute('data-state-btn');
content.setAttribute('data-state', state);
buttons.forEach((candidate) => candidate.classList.remove('active'));
button.classList.add('active');
});
});
</script>
</body>
</html>

View File

@@ -1,11 +1,24 @@
bro we need to do changes, that client required
1. we need to add location logic
1.1 the catalogs will come or for global or for exact region
1.2 need to add a place where the user can choose his region like city if choosed moscow the country is set russian
1.3 can we try to understand what country is user logged or whach city by global ip and set it?
2. we need to add somekind of user login logic
2.1 user can add to cart, look the items and etc without logged in, but when he is going to buy/pay ->
at first he have to login with telegram, i will send you the bots adress.
2.1.1 if is not logged -> will see the QR or link for logging via telegram
2.1.2 if logged we need to ping server to check if he is active user. the expiration date (like day or 5 days) we will get from bakcend with session id
2.2 and when user is logged, that time he can do a payment
bro please read carefully.
this must be for all projects.
At first here is the API for only auth process:
https://users.vitanova.network:456/ping
and here are other stuff regarding it:
//Logout user by sessionID
r.DELETE("/users/sessions/:webSessionID", Logout)
//creates new session for user and send code for activation
r.POST("/users/sessions", newWebSession)
r.GET("/users/sessions/:webSessionID", getWebSession)
As you got all the info, keep all the structure of api above.
Now when the user clicks on login, we must show the QR and the link of the telegram bot, which we already have (btw sho me, so i see wheter it is true or not)
and add a query param "?start=GUID" and generate a guid there.
after we post it ad a websession, we have to get it like this " r.GET("/users/sessions/:webSessionID", getWebSession)" every 5 secs untill we get a status true
if we will be loged in, we have to keep that webSessionID in the cookies for an hour
1. if we open our website, we have to check the cookies and do a request for that websession
2. if we are not loged in, then we will loge in one more time
any questions?

View File

@@ -36,9 +36,24 @@ server {
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://telegram.org; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https:; frame-src https://telegram.org;" always;
# Brotli compression (if available)
# brotli on;
# brotli_comp_level 6;
# brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
}
server {
listen 80;
server_name lovero.store www.lovero.store;
location / {
proxy_pass http://127.0.0.1:4202;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View File

@@ -30,7 +30,9 @@
{
"name": "api-cache",
"urls": [
"/api/**"
"/api/**",
"https://api.dexarmarket.ru:445/**",
"https://api.novo.market:444/**"
],
"cacheConfig": {
"maxSize": 100,

73
package-lock.json generated
View File

@@ -8,11 +8,15 @@
"name": "dexarmarket",
"version": "0.0.0",
"dependencies": {
"@angular/animations": "^21.1.5",
"@angular/cdk": "^21.1.5",
"@angular/common": "^21.0.6",
"@angular/compiler": "^21.0.6",
"@angular/core": "^21.0.6",
"@angular/forms": "^21.0.6",
"@angular/material": "^21.1.5",
"@angular/platform-browser": "^21.0.6",
"@angular/platform-browser-dynamic": "^21.1.5",
"@angular/router": "^21.0.6",
"@angular/service-worker": "^21.0.6",
"primeicons": "^7.0.0",
@@ -324,6 +328,21 @@
"yarn": ">= 1.13.0"
}
},
"node_modules/@angular/animations": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.1.5.tgz",
"integrity": "sha512-gsqHX8lCYV8cgVtHs0iLwrX8SVlmcjUF44l/xCc/jBC/TeKWRl2e6Jqrn1Wcd0NDlGiNsm+mYNyqMyy5/I7kjw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/core": "21.1.5"
}
},
"node_modules/@angular/build": {
"version": "21.1.0",
"resolved": "https://registry.npmjs.org/@angular/build/-/build-21.1.0.tgz",
@@ -472,6 +491,22 @@
"dev": true,
"license": "MIT"
},
"node_modules/@angular/cdk": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.1.5.tgz",
"integrity": "sha512-AlQPgqe3LLwXCyrDwYSX3m/WKnl2ppCMW7Gb+7bJpIcpMdWYEpSOSQF318jXGYIysKg43YbdJ1tWhJWY/cbn3w==",
"license": "MIT",
"dependencies": {
"parse5": "^8.0.0",
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/common": "^21.0.0 || ^22.0.0",
"@angular/core": "^21.0.0 || ^22.0.0",
"@angular/platform-browser": "^21.0.0 || ^22.0.0",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/cli": {
"version": "21.1.0",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.1.0.tgz",
@@ -613,6 +648,23 @@
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/material": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-21.1.5.tgz",
"integrity": "sha512-D6JvFulPvIKhPJ52prMV7DxwYMzcUpHar11ZcMb7r9WQzUfCS3FDPXfMAce5n3h+3kFccfmmGpnyBwqTlLPSig==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/cdk": "21.1.5",
"@angular/common": "^21.0.0 || ^22.0.0",
"@angular/core": "^21.0.0 || ^22.0.0",
"@angular/forms": "^21.0.0 || ^22.0.0",
"@angular/platform-browser": "^21.0.0 || ^22.0.0",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/platform-browser": {
"version": "21.0.6",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.0.6.tgz",
@@ -635,6 +687,24 @@
}
}
},
"node_modules/@angular/platform-browser-dynamic": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.1.5.tgz",
"integrity": "sha512-Pd8nPbJSIONnze1WS9wLBAtaFw4TYIH+ZGjKHS9G1E9l09tDWtHWyB7dY82Sc//Nc8iR4V7dcsbUmFjOJHThww==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/common": "21.1.5",
"@angular/compiler": "21.1.5",
"@angular/core": "21.1.5",
"@angular/platform-browser": "21.1.5"
}
},
"node_modules/@angular/router": {
"version": "21.0.6",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-21.0.6.tgz",
@@ -7687,7 +7757,6 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz",
"integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==",
"dev": true,
"license": "MIT",
"dependencies": {
"entities": "^6.0.0"
@@ -7741,7 +7810,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
@@ -9512,3 +9580,4 @@
}
}
}

View File

@@ -5,22 +5,29 @@
"ng": "ng",
"start": "ng serve",
"dexar": "ng serve --configuration=development --port 4200",
"novo": "ng serve --configuration=novo --port 4201",
"novo": "ng serve --configuration=novo --port 4201 --proxy-config proxy.conf.novo.json",
"start:dexar": "ng serve --configuration=development --port 4200",
"start:novo": "ng serve --configuration=novo --port 4201",
"build": "ng build",
"build:dexar": "ng build --configuration=production",
"build:novo": "ng build --configuration=novo-production",
"watch": "ng build --watch --configuration development",
"test": "ng test"
"test": "ng test",
"lavero": "ng serve --configuration=lavero --port 4202 --proxy-config proxy.conf.lavero.json",
"start:lavero": "ng serve --configuration=lavero --port 4202",
"build:lavero": "ng build --configuration=lavero-production"
},
"private": true,
"dependencies": {
"@angular/animations": "^21.1.5",
"@angular/cdk": "^21.1.5",
"@angular/common": "^21.0.6",
"@angular/compiler": "^21.0.6",
"@angular/core": "^21.0.6",
"@angular/forms": "^21.0.6",
"@angular/material": "^21.1.5",
"@angular/platform-browser": "^21.0.6",
"@angular/platform-browser-dynamic": "^21.1.5",
"@angular/router": "^21.0.6",
"@angular/service-worker": "^21.0.6",
"primeicons": "^7.0.0",
@@ -42,4 +49,4 @@
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.9.3"
}
}
}

11
proxy.conf.lavero.json Normal file
View File

@@ -0,0 +1,11 @@
{
"/api": {
"target": "https://api.lovero.store:555",
"secure": false,
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
},
"logLevel": "debug"
}
}

View File

@@ -0,0 +1,11 @@
{
"/api": {
"target": "https://api.lavero.store:555",
"secure": false,
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
},
"logLevel": "debug"
}
}

11
proxy.conf.novo.json Normal file
View File

@@ -0,0 +1,11 @@
{
"/api": {
"target": "https://api.novo.market:444",
"secure": false,
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
},
"logLevel": "debug"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,5 +1,4 @@
{
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"name": "Novo Market - Интернет-магазин",
"short_name": "Novo",
"description": "Novo Market - ваш онлайн магазин качественных товаров с доставкой",
@@ -12,34 +11,10 @@
"categories": ["shopping", "lifestyle"],
"icons": [
{
"src": "icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "maskable any"
"src": "assets/images/novo-favicon.svg",
"sizes": "any",
"type": "image/svg+xml",
"purpose": "any"
},
{
"src": "icons/icon-192x192.png",
@@ -47,12 +22,6 @@
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-512x512.png",
"sizes": "512x512",

View File

@@ -11,34 +11,10 @@
"categories": ["shopping", "marketplace"],
"icons": [
{
"src": "icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "maskable any"
"src": "assets/images/dexar-favicon.svg",
"sizes": "any",
"type": "image/svg+xml",
"purpose": "any"
},
{
"src": "icons/icon-192x192.png",
@@ -46,12 +22,6 @@
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "icons/icon-512x512.png",
"sizes": "512x512",

View File

@@ -4,6 +4,8 @@ import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { routes } from './app.routes';
import { cacheInterceptor } from './interceptors/cache.interceptor';
import { apiHeadersInterceptor } from './interceptors/api-headers.interceptor';
import { mockDataInterceptor } from './interceptors/mock-data.interceptor';
import { provideServiceWorker } from '@angular/service-worker';
export const appConfig: ApplicationConfig = {
@@ -15,7 +17,7 @@ export const appConfig: ApplicationConfig = {
withInMemoryScrolling({ scrollPositionRestoration: 'top' })
),
provideHttpClient(
withInterceptors([cacheInterceptor])
withInterceptors([mockDataInterceptor, apiHeadersInterceptor, cacheInterceptor])
),
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),

View File

@@ -12,12 +12,12 @@
</div>
} @else {
<app-header></app-header>
@if (!isHomePage()) {
<app-back-button />
}
<main class="main-content">
@if (!isHomePage()) {
<app-back-button />
}
<router-outlet></router-outlet>
</main>
<app-footer></app-footer>
<app-telegram-login />
<!-- <app-telegram-login /> -->
}

View File

@@ -1,18 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { App } from './app';
import { provideRouter } from '@angular/router';
describe('App', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [App],
providers: [provideRouter([])]
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
});

View File

@@ -5,7 +5,6 @@ import { Title } from '@angular/platform-browser';
import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component';
import { BackButtonComponent } from './components/back-button/back-button.component';
import { TelegramLoginComponent } from './components/telegram-login/telegram-login.component';
import { ApiService } from './services';
import { interval, concat } from 'rxjs';
import { filter, first } from 'rxjs/operators';
@@ -17,7 +16,7 @@ import { TranslateService } from './i18n/translate.service';
@Component({
selector: 'app-root',
imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, TelegramLoginComponent, TranslatePipe],
imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, TranslatePipe],
templateUrl: './app.html',
styleUrl: './app.scss'
})
@@ -92,13 +91,5 @@ export class App implements OnInit {
console.error('Update check failed:', err);
}
});
this.swUpdate.versionUpdates
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(event => {
if (event.type === 'VERSION_READY') {
console.log('New app version ready');
}
});
}
}

View File

@@ -0,0 +1,49 @@
// Lavero brand routes
// Loaded via angular.json fileReplacements when building for novo
import { Routes } from '@angular/router';
export const brandInfoRoutes: Routes = [
{
path: 'about',
loadComponent: () => import('./lavero/pages/info/about/about.component').then(m => m.AboutLaveroComponent)
},
{
path: 'contacts',
loadComponent: () => import('./lavero/pages/info/contacts/contacts.component').then(m => m.ContactsLaveroComponent)
},
{
path: 'faq',
loadComponent: () => import('./lavero/pages/info/faq/faq.component').then(m => m.FaqLaveroComponent)
},
{
path: 'delivery',
loadComponent: () => import('./lavero/pages/info/delivery/delivery.component').then(m => m.DeliveryLaveroComponent)
},
{
path: 'guarantee',
loadComponent: () => import('./lavero/pages/info/guarantee/guarantee.component').then(m => m.GuaranteeLaveroComponent)
}
];
export const brandLegalRoutes: Routes = [
{
path: 'company-details',
loadComponent: () => import('./lavero/pages/legal/company-details/company-details.component').then(m => m.CompanyDetailsLaveroComponent)
},
{
path: 'payment-terms',
loadComponent: () => import('./lavero/pages/legal/payment-terms/payment-terms.component').then(m => m.PaymentTermsLaveroComponent)
},
{
path: 'return-policy',
loadComponent: () => import('./lavero/pages/legal/return-policy/return-policy.component').then(m => m.ReturnPolicyLaveroComponent)
},
{
path: 'public-offer',
loadComponent: () => import('./lavero/pages/legal/public-offer/public-offer.component').then(m => m.PublicOfferLaveroComponent)
},
{
path: 'privacy-policy',
loadComponent: () => import('./lavero/pages/legal/privacy-policy/privacy-policy.component').then(m => m.PrivacyPolicyLaveroComponent)
}
];

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-about-lavero-ru /> }
@case ('en') { <app-about-lavero-en /> }
@case ('hy') { <app-about-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { AboutLaveroRuComponent } from './ru/about-ru.component';
import { AboutLaveroEnComponent } from './en/about-en.component';
import { AboutLaveroHyComponent } from './hy/about-hy.component';
@Component({
selector: 'app-about-lavero',
imports: [AboutLaveroRuComponent, AboutLaveroEnComponent, AboutLaveroHyComponent],
templateUrl: './about.component.html',
styleUrls: ['../../../../../pages/info/about/about.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AboutLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,98 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>About Us</h1>
<p class="subtitle">A modern marketplace for your convenience</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🚀</div>
<h3>Who We Are</h3>
<p>We are a rapidly growing marketplace connecting sellers and buyers from different countries. Our platform creates convenient conditions for safe trading of various goods and services.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🎯</div>
<h3>Our Mission</h3>
<p>To create a simple and profitable ecosystem for businesses and buyers, where everyone finds the best deals.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🌍</div>
<h3>Geography</h3>
<p>We operate in Russia, Armenia, UAE, Turkey, China, Kazakhstan, Kyrgyzstan, and other countries.</p>
</div>
<div class="info-card wide">
<div class="card-icon">💼</div>
<h3>For Business</h3>
<ul class="compact-list">
<li>Easy product listing</li>
<li>Ready-made audience</li>
<li>Convenient tools</li>
<li>Technical support</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🛍️</div>
<h3>For Buyers</h3>
<ul class="compact-list">
<li>Wide selection of products</li>
<li>Competitive prices</li>
<li>Safe purchases</li>
<li>Fast delivery</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🔒</div>
<h3>Our Values</h3>
<div class="features-list">
<div class="feature">✓ Transparency</div>
<div class="feature">✓ Reliability</div>
<div class="feature">✓ Innovation</div>
<div class="feature">✓ Customer Service</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📈</div>
<h3>Our Journey</h3>
<div class="timeline">
<div class="timeline-item">
<strong>2024</strong>
<p>Platform launch in Armenia</p>
</div>
<div class="timeline-item">
<strong>2025</strong>
<p>Expansion to the Russian market</p>
</div>
<div class="timeline-item">
<strong>Today</strong>
<p>International expansion</p>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">🏢</div>
<h3>Company Details</h3>
<p><strong>Company:</strong> «LAVERO» LLC</p>
<p><strong>Director:</strong> GEVORG MATEVOSYAN</p>
<p><strong>TIN (ՀVHH):</strong> 03590442</p>
<p><strong>Registration No.:</strong> 999.110.1583686</p>
<p><strong>Address:</strong> ARMENIA, KOTAYK, ABOVYAN, VERIN PTGHNI, 3rd Street, 28</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Contact Us</h3>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="support-note">We are always in touch</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-about-lavero-en',
templateUrl: './about-en.component.html',
styleUrls: ['../../../../../../pages/info/about/about.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AboutLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,98 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Մեր մասին</h1>
<p class="subtitle">Զամանակակից մարկեթփլեյս ձեր հարմարության համար</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🚀</div>
<h3>Ովքեր ենք</h3>
<p>Մենք դինամիկ զարգացող մարկեթփլեյս ենք, որը միավորում է վաճառողներին և գնորդներին տարբեր երկրներից։ Մեր հարթակը ստեղծում է հարմար պայմաններ տարբեր ապրանքների և ծառայությունների անվտանգ առևտրի համար։</p>
</div>
<div class="info-card wide">
<div class="card-icon">🎯</div>
<h3>Մեր առաքելությունը</h3>
<p>Ստեղծել պարզ և շահավետ էկոհամակարգ բիզնեսի և գնորդների համար, որտեղ բոլորը գտնեն լավագույն առաջարկները։</p>
</div>
<div class="info-card wide">
<div class="card-icon">🌍</div>
<h3>Աշխարհագրություն</h3>
<p>Մենք աշխատում ենք Ռուսաստանում, Հայաստանում, ԱՀԷ-ում, Թուրքիայում, Չինաստանում, Ղազախստանում, Ղրղզստանում և այլ երկրներում։</p>
</div>
<div class="info-card wide">
<div class="card-icon">💼</div>
<h3>Բիզնեսի համար</h3>
<ul class="compact-list">
<li>Ապրանքների հեշտ տեղադրում</li>
<li>Պատրաստ լսարան</li>
<li>Հարմար գործիքներ</li>
<li>Տեխնիկական աջակցություն</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🛍️</div>
<h3>Գնորդների համար</h3>
<ul class="compact-list">
<li>Ապրանքների լայն ընտրություն</li>
<li>Մրցունակելի գներ</li>
<li>Անվտանգ գնումներ</li>
<li>Արագ առաքում</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🔒</div>
<h3>Մեր արժեքները</h3>
<div class="features-list">
<div class="feature">✓ Թափանցիկություն</div>
<div class="feature">✓ Հուսալիություն</div>
<div class="feature">✓ Նորարարություն</div>
<div class="feature">✓ Հաճախորդային սպասարկում</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📈</div>
<h3>Մեր ճանապարհը</h3>
<div class="timeline">
<div class="timeline-item">
<strong>2024</strong>
<p>Հարթակի գործարկումը Հայաստանում</p>
</div>
<div class="timeline-item">
<strong>2025</strong>
<p>Մուտք ռուսական շուկա</p>
</div>
<div class="timeline-item">
<strong>Այսօր</strong>
<p>Միջազգային ընդլայնում</p>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">🏢</div>
<h3>Ինկերության տվյալները</h3>
<p><strong>Ընկерություն՝</strong> «ԼАВЕРО» ՍՊԸ</p>
<p><strong>Տнօрен՝</strong> ГЕВORG МАТЕВОСЯН (GEVORG MATEVOSYAN)</p>
<p><strong>ՀВHH՝</strong> 03590442</p>
<p><strong>Гранцман h/h՝</strong> 999.110.1583686</p>
<p><strong>Hasцe՝</strong> ՀАЙАСТАН, КОТАЙК, АБОВЯН, ВЕРИН ПТГНИ, 3-рд ПOЛOC, 28</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Կապվել մեզ հետ</h3>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="support-note">Մենք միշտ կապի մեջ ենք</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-about-lavero-hy',
templateUrl: './about-hy.component.html',
styleUrls: ['../../../../../../pages/info/about/about.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AboutLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,98 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>О нас</h1>
<p class="subtitle">Современный маркетплейс для вашего удобства</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🚀</div>
<h3>Кто мы</h3>
<p>Мы - динамично развивающийся маркетплейс, объединяющий продавцов и покупателей из разных стран. Наша платформа создает удобные условия для безопасной торговли различными товарами и услугами.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🎯</div>
<h3>Наша миссия</h3>
<p>Создавать простую и выгодную экосистему для бизнеса и покупателей, где каждый находит лучшие предложения.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🌍</div>
<h3>География</h3>
<p>Мы работаем в России, Армении, ОАЭ, Турции, Китае, Казахстане, Кыргызстане и других странах.</p>
</div>
<div class="info-card wide">
<div class="card-icon">💼</div>
<h3>Для бизнеса</h3>
<ul class="compact-list">
<li>Простое размещение товаров</li>
<li>Готовая аудитория</li>
<li>Удобные инструменты</li>
<li>Техническая поддержка</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🛍️</div>
<h3>Для покупателей</h3>
<ul class="compact-list">
<li>Широкий выбор товаров</li>
<li>Выгодные цены</li>
<li>Безопасные покупки</li>
<li>Быстрая доставка</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🔒</div>
<h3>Наши ценности</h3>
<div class="features-list">
<div class="feature">✓ Прозрачность</div>
<div class="feature">✓ Надежность</div>
<div class="feature">✓ Инновации</div>
<div class="feature">✓ Клиентский сервис</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📈</div>
<h3>Наш путь</h3>
<div class="timeline">
<div class="timeline-item">
<strong>2024</strong>
<p>Запуск платформы в Армении</p>
</div>
<div class="timeline-item">
<strong>2025</strong>
<p>Выход на российский рынок</p>
</div>
<div class="timeline-item">
<strong>Сегодня</strong>
<p>Международная экспансия</p>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">🏢</div>
<h3>Реквизиты компании</h3>
<p><strong>Компания:</strong> «ЛАВЕРО» ООО</p>
<p><strong>Директор:</strong> ГЕВОРГ МАТЕВОСЯН</p>
<p><strong>ՀВՀՀ (ИНН):</strong> 03590442</p>
<p><strong>Рег. номер:</strong> 999.110.1583686</p>
<p><strong>Адрес:</strong> АРМЕНИЯ, КОТАЙК, АБОВЯН, ВЕРИН ПТГНИ, ул. 3-я, 28</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Связаться с нами</h3>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="support-note">Мы всегда на связи</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-about-lavero-ru',
templateUrl: './about-ru.component.html',
styleUrls: ['../../../../../../pages/info/about/about.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AboutLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-contacts-lavero-ru /> }
@case ('en') { <app-contacts-lavero-en /> }
@case ('hy') { <app-contacts-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { ContactsLaveroRuComponent } from './ru/contacts-ru.component';
import { ContactsLaveroEnComponent } from './en/contacts-en.component';
import { ContactsLaveroHyComponent } from './hy/contacts-hy.component';
@Component({
selector: 'app-contacts-lavero',
imports: [ContactsLaveroRuComponent, ContactsLaveroEnComponent, ContactsLaveroHyComponent],
templateUrl: './contacts.component.html',
styleUrls: ['../../../../../pages/info/contacts/contacts.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ContactsLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,49 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Contacts</h1>
<p class="subtitle">Get in touch with us</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🏢</div>
<h3>Organization</h3>
<p class="org-name">LLC «ELECTROMOTORS»</p>
<p><strong>TIN:</strong> 03590442</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Phone</h3>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
</div>
<div class="info-card wide">
<div class="card-icon">✉️</div>
<h3>Email</h3>
<p><a href="mailto:info@lavero.store">info&#64;lavero.store</a></p>
<p class="note">Response within 24 hours</p>
</div>
<div class="info-card wide">
<div class="card-icon">📍</div>
<h3>Address</h3>
<p>Armenia, 0501, Aragatsotn region, Talin, 12 Gaya St.</p>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Working Hours</h3>
<p><strong>Support:</strong> 9:00 - 21:00</p>
<p><strong>Days off:</strong> Saturday - Sunday</p>
</div>
<div class="info-card wide">
<div class="card-icon">💬</div>
<h3>Contact Us</h3>
<p>If you experience technical issues with the website or have questions about placing an order, please contact us at <a href="mailto:info@lavero.store">info&#64;lavero.store</a> with a detailed description of the problem.</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-contacts-lavero-en',
templateUrl: './contacts-en.component.html',
styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ContactsLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,49 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Կապ</h1>
<p class="subtitle">Կապվեք մեզ հետ</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🏢</div>
<h3>Կազմակերպություն</h3>
<p class="org-name">ՍՊԸ «ԷԼԵԿՏՌՈՄՈՏՈՌՍ»</p>
<p><strong>ՀՎՀՀ՝</strong> 03590442</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Հեռախոս</h3>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
</div>
<div class="info-card wide">
<div class="card-icon">✉️</div>
<h3>Էլ. փոստ</h3>
<p><a href="mailto:info@lavero.store">info&#64;lavero.store</a></p>
<p class="note">Պատասխանը 24 ժամվա ընթացքում</p>
</div>
<div class="info-card wide">
<div class="card-icon">📍</div>
<h3>Հասցե</h3>
<p>Հայաստան, 0501, Արագածոտնի մարզ, ք. Տալին, Գայայի փող. 12</p>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Աշխատանքային ժամեր</h3>
<p><strong>Աջակցություն՝</strong> 9:00 - 21:00</p>
<p><strong>Հանգստյան օրեր՝</strong> Շաբաթ - Կիրակի</p>
</div>
<div class="info-card wide">
<div class="card-icon">💬</div>
<h3>Կապվել մեզ հետ</h3>
<p>Կայքի տեխնիկական խնդիրների դեպքում կամ պատվերի ձևակերպման հարցերի դեպքում դիմեք <a href="mailto:info@lavero.store">info&#64;lavero.store</a> խնդրի մանրամասն նկարագրությամբ։</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-contacts-lavero-hy',
templateUrl: './contacts-hy.component.html',
styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ContactsLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,49 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Контакты</h1>
<p class="subtitle">Свяжитесь с нами</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🏢</div>
<h3>Организация</h3>
<p class="org-name">ООО «ЛАВЕРО»</p>
<p><strong>ИНН:</strong> 03590442</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Телефон</h3>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
</div>
<div class="info-card wide">
<div class="card-icon">✉️</div>
<h3>Email</h3>
<p><a href="mailto:info@lavero.store">info&#64;lavero.store</a></p>
<p class="note">Ответ в течение 24 часов</p>
</div>
<div class="info-card wide">
<div class="card-icon">📍</div>
<h3>Адрес</h3>
<p>АРМЕНИЯ, КОТАЙК, АБОВЯН, ВЕРИН ПТГНИ, ул. 3-я, 28</p>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Часы работы</h3>
<p><strong>Поддержка:</strong> 9:00 - 21:00</p>
<p><strong>Выходные:</strong> Суббота - Воскресенье</p>
</div>
<div class="info-card wide">
<div class="card-icon">💬</div>
<h3>Связаться с нами</h3>
<p>При возникновении технических проблем с работой сайта или вопросов по оформлению заказа обращайтесь на <a href="mailto:info@lavero.store">info&#64;lavero.store</a> с подробным описанием проблемы.</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-contacts-lavero-ru',
templateUrl: './contacts-ru.component.html',
styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ContactsLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-delivery-lavero-ru /> }
@case ('en') { <app-delivery-lavero-en /> }
@case ('hy') { <app-delivery-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { DeliveryLaveroRuComponent } from './ru/delivery-ru.component';
import { DeliveryLaveroEnComponent } from './en/delivery-en.component';
import { DeliveryLaveroHyComponent } from './hy/delivery-hy.component';
@Component({
selector: 'app-delivery-lavero',
imports: [DeliveryLaveroRuComponent, DeliveryLaveroEnComponent, DeliveryLaveroHyComponent],
templateUrl: './delivery.component.html',
styleUrls: ['../../../../../pages/info/delivery/delivery.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeliveryLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,78 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Delivery</h1>
<p class="subtitle">Fast and convenient to your door</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">📧</div>
<h3>Digital Products</h3>
<div class="features-list">
<div class="feature">⚡ Instant delivery</div>
<div class="feature">📨 To your email</div>
<div class="feature">💰 Free</div>
<div class="feature">🔒 Secure</div>
</div>
<p class="note important" style="margin-top: 12px;">⚠️ The platform is not responsible for digital products. The seller is responsible for quality and functionality.</p>
</div>
<div class="info-card wide">
<div class="card-icon">📦</div>
<h3>Physical Products</h3>
<ul class="compact-list">
<li>СДЭК (2-7 days)</li>
<li>Почта России (5-14 days)</li>
<li>Boxberry (2-5 days)</li>
<li>DPD (1-3 days)</li>
<li>Яндекс.Доставка (same day*)</li>
</ul>
<p class="note">*If available in your city</p>
<p class="note important" style="margin-top: 12px;">⚠️ The platform is not responsible for the actions of shipping companies. Delivery is handled by СДЭК, Почта России, Boxberry, DPD, and other carriers.</p>
</div>
<div class="info-card wide">
<div class="card-icon">💰</div>
<h3>Delivery Cost</h3>
<div class="delivery-cost">
<div class="cost-item">
<strong>Digital Products</strong>
<span class="free">Free</span>
</div>
<div class="cost-item">
<strong>Physical Products</strong>
<span>Depends on weight and region</span>
</div>
</div>
<p class="note">Exact cost is calculated at checkout</p>
</div>
<div class="info-card wide">
<div class="card-icon">🔍</div>
<h3>Tracking</h3>
<p>After shipping, you will receive a tracking number by email. Track your package on the delivery service website or in your account.</p>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Check upon receipt</h3>
<div class="check-grid">
<div class="check-item">✓ Packaging integrity</div>
<div class="check-item">✓ Product match</div>
<div class="check-item">✓ Completeness</div>
<div class="check-item">✓ No damage</div>
</div>
<p class="note important">If there are issues - file a report with the courier</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Questions about delivery?</h3>
<p>Contact the seller or us:</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-delivery-lavero-en',
templateUrl: './delivery-en.component.html',
styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeliveryLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,78 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Առաքում</h1>
<p class="subtitle">Արագ և հարմար՝ մինչև ձեր դուռը</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">📧</div>
<h3>Թվային ապրանքներ</h3>
<div class="features-list">
<div class="feature">⚡ Ակնթարթային առաքում</div>
<div class="feature">📨 Ձեր email-ին</div>
<div class="feature">💰 Անվճար</div>
<div class="feature">🔒 Անվտանգ</div>
</div>
<p class="note important" style="margin-top: 12px;">⚠️ Հարթակը պատասխանատվություն չի կրում թվային ապրանքների համար։ Որակի և գործունակության համար պատասխանատու է վաճառողը։</p>
</div>
<div class="info-card wide">
<div class="card-icon">📦</div>
<h3>Ֆիզիկական ապրանքներ</h3>
<ul class="compact-list">
<li>СДЭК (2-7 օր)</li>
<li>Почта России (5-14 օր)</li>
<li>Boxberry (2-5 օր)</li>
<li>DPD (1-3 օր)</li>
<li>Яндекс.Доставка (պատվերի օրը*)</li>
</ul>
<p class="note">*Եթե հասանելի է ձեր քաղաքում</p>
<p class="note important" style="margin-top: 12px;">⚠️ Հարթակը պատասխանատվություն չի կրում տրանսպորտային ընկերությունների գործողությունների համար։ Առաքման համար պատասխանատու են СДЭК, Почта России, Boxberry, DPD և այլ փոխադրողներ։</p>
</div>
<div class="info-card wide">
<div class="card-icon">💰</div>
<h3>Առաքման արժեքը</h3>
<div class="delivery-cost">
<div class="cost-item">
<strong>Թվային ապրանքներ</strong>
<span class="free">Անվճար</span>
</div>
<div class="cost-item">
<strong>Ֆիզիկական ապրանքներ</strong>
<span>Կախված է քաշից և տարածաշրջանից</span>
</div>
</div>
<p class="note">Ճիշտ արժեքը հաշվարկվում է ձևակերպման ժամանակ</p>
</div>
<div class="info-card wide">
<div class="card-icon">🔍</div>
<h3>Հետագծում</h3>
<p>Ուղարկմանից հետո դուք կստանաք թրեք-համար email-ով։ Հետևեք ծանրութը առաքման ծառայության կայքում կամ անձնական էջում։</p>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Ստանալիս ստուգեք</h3>
<div class="check-grid">
<div class="check-item">✓ Փաթեթավորման ամբողջականությունը</div>
<div class="check-item">✓ Ապրանքի համապատասխանությունը</div>
<div class="check-item">✓ Լրիվությունը</div>
<div class="check-item">✓ Վնասվածների բացակայությունը</div>
</div>
<p class="note important">Եթե խնդիրներ կան - կազմեք ակտ սուրհանդեսի հետ</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Առաքման հարցեր՞</h3>
<p>Կապվեք վաճառողի կամ մեզ հետ՝</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-delivery-lavero-hy',
templateUrl: './delivery-hy.component.html',
styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeliveryLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,78 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Доставка</h1>
<p class="subtitle">Быстро и удобно до вашей двери</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">📧</div>
<h3>Цифровые товары</h3>
<div class="features-list">
<div class="feature">⚡ Мгновенная доставка</div>
<div class="feature">📨 На ваш email</div>
<div class="feature">💰 Бесплатно</div>
<div class="feature">🔒 Безопасно</div>
</div>
<p class="note important" style="margin-top: 12px;">⚠️ Платформа не несет ответственности за цифровые товары. За качество и работоспособность отвечает продавец.</p>
</div>
<div class="info-card wide">
<div class="card-icon">📦</div>
<h3>Физические товары</h3>
<ul class="compact-list">
<li>СДЭК (2-7 дней)</li>
<li>Почта России (5-14 дней)</li>
<li>Boxberry (2-5 дней)</li>
<li>DPD (1-3 дня)</li>
<li>Яндекс.Доставка (в день заказа*)</li>
</ul>
<p class="note">*При наличии в вашем городе</p>
<p class="note important" style="margin-top: 12px;">⚠️ Платформа не несет ответственности за действия транспортных компаний. За доставку отвечают СДЭК, Почта России, Boxberry, DPD и другие перевозчики.</p>
</div>
<div class="info-card wide">
<div class="card-icon">💰</div>
<h3>Стоимость доставки</h3>
<div class="delivery-cost">
<div class="cost-item">
<strong>Цифровые товары</strong>
<span class="free">Бесплатно</span>
</div>
<div class="cost-item">
<strong>Физические товары</strong>
<span>Зависит от веса и региона</span>
</div>
</div>
<p class="note">Точная стоимость рассчитывается при оформлении</p>
</div>
<div class="info-card wide">
<div class="card-icon">🔍</div>
<h3>Отслеживание</h3>
<p>После отправки вы получите трек-номер на email. Отслеживайте посылку на сайте службы доставки или в личном кабинете.</p>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>При получении проверьте</h3>
<div class="check-grid">
<div class="check-item">✓ Целостность упаковки</div>
<div class="check-item">✓ Соответствие товара</div>
<div class="check-item">✓ Комплектность</div>
<div class="check-item">✓ Отсутствие повреждений</div>
</div>
<p class="note important">Если есть проблемы - составьте акт с курьером</p>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Вопросы по доставке?</h3>
<p>Свяжитесь с продавцом или нами:</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-delivery-lavero-ru',
templateUrl: './delivery-ru.component.html',
styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeliveryLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,93 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Frequently Asked Questions</h1>
<p class="subtitle">Quick answers to popular questions</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🛍️</div>
<h3>How to place an order?</h3>
<div class="process-steps-compact">
<p>1. Add the product to your cart</p>
<p>2. Enter your delivery details</p>
<p>3. Choose a payment method</p>
<p>4. Confirm your order</p>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">💳</div>
<h3>Payment Methods</h3>
<ul class="compact-list">
<li>Bank cards</li>
<li>SBP</li>
<li>E-wallets</li>
<li>Cash on delivery*</li>
</ul>
<p class="note">*Depends on the seller</p>
</div>
<div class="info-card wide">
<div class="card-icon">🚚</div>
<h3>Delivery</h3>
<div class="delivery-info">
<div class="delivery-item">
<strong>Digital products</strong>
<p>Instantly via email</p>
</div>
<div class="delivery-item">
<strong>Physical products</strong>
<p>СДЭК, Почта России, DPD</p>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">↩️</div>
<h3>Product Returns</h3>
<p>You can return a product in good condition within 7 days, provided it has not been used and the packaging is intact.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🔒</div>
<h3>Security</h3>
<div class="features-list">
<div class="feature">✓ Secure payments</div>
<div class="feature">✓ Verified sellers</div>
<div class="feature">✓ Return guarantee</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">⏱️</div>
<h3>Order Processing</h3>
<p>Your order is processed immediately after payment. The seller ships the product within 1-3 business days.</p>
</div>
<div class="info-card wide">
<div class="card-icon">💬</div>
<h3>Customer Support</h3>
<div class="contacts-grid">
<div class="contact-item">
<strong>Email</strong>
<a href="mailto:info@lavero.store">info@lavero.store</a>
</div>
<div class="contact-item">
<strong>Phone</strong>
<a [href]="env.phoneTel">{{ env.phones.support }}</a>
</div>
<div class="contact-item">
<strong>Working Hours</strong>
<p>24/7 support</p>
</div>
<div class="contact-item">
<strong>Response Time</strong>
<p>Up to 2 hours during business hours</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-faq-lavero-en',
templateUrl: './faq-en.component.html',
styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FaqLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-faq-lavero-ru /> }
@case ('en') { <app-faq-lavero-en /> }
@case ('hy') { <app-faq-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { FaqLaveroRuComponent } from './ru/faq-ru.component';
import { FaqLaveroEnComponent } from './en/faq-en.component';
import { FaqLaveroHyComponent } from './hy/faq-hy.component';
@Component({
selector: 'app-faq-lavero',
imports: [FaqLaveroRuComponent, FaqLaveroEnComponent, FaqLaveroHyComponent],
templateUrl: './faq.component.html',
styleUrls: ['../../../../../pages/info/faq/faq.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FaqLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,93 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Հաճախ տրվող հարցեր</h1>
<p class="subtitle">Արագ պատասխաններ տարածված հարցերին</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🛍️</div>
<h3>Ինչպես կատարել պատվեր՞</h3>
<div class="process-steps-compact">
<p>1. Ավելացրեք ապրանքը զամբյուղին</p>
<p>2. Նշեց առաքման տվյալները</p>
<p>3. Ընտրեք վճարման եղանակը</p>
<p>4. Հաստատեք պատվերը</p>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">💳</div>
<h3>Վճարման եղանակներ</h3>
<ul class="compact-list">
<li>Բանկային քարտեր</li>
<li>ՍԲՊ</li>
<li>Էլեկտրոնային դրամապանակներ</li>
<li>Կանխիկ ստանալիս*</li>
</ul>
<p class="note">*Կախված է վաճառողից</p>
</div>
<div class="info-card wide">
<div class="card-icon">🚚</div>
<h3>Առաքում</h3>
<div class="delivery-info">
<div class="delivery-item">
<strong>Թվային ապրանքներ</strong>
<p>Ակնթարթային email-ին</p>
</div>
<div class="delivery-item">
<strong>Ֆիզիկական ապրանքներ</strong>
<p>СДЭК, Почта России, DPD</p>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">↩️</div>
<h3>Ապրանքի վերադարձ</h3>
<p>Կարելի է վերադարձել որակյալ ապրանքը 7 օրվա ընթացքում, եթե այն չի օգտագործվել և փաթեթավորումը պահպանված է։</p>
</div>
<div class="info-card wide">
<div class="card-icon">🔒</div>
<h3>Անվտանգություն</h3>
<div class="features-list">
<div class="feature">✓ Պաշտպանված վճարումներ</div>
<div class="feature">✓ Ստուգված վաճառողներ</div>
<div class="feature">✓ Վերադարձի երաշխիք</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">⏱️</div>
<h3>Պատվերի մշակում</h3>
<p>Պատվերը մշակվում է վճարումից անմիջապես հետո։ Վաճառողը ապրանքը ուղարկում է 1-3 աշխատանքային օրվա ընթացքում։</p>
</div>
<div class="info-card wide">
<div class="card-icon">💬</div>
<h3>Աջակցության ծառայություն</h3>
<div class="contacts-grid">
<div class="contact-item">
<strong>Email</strong>
<a href="mailto:info@lavero.store">info@lavero.store</a>
</div>
<div class="contact-item">
<strong>Հեռախոս</strong>
<a [href]="env.phoneTel">{{ env.phones.support }}</a>
</div>
<div class="contact-item">
<strong>Աշխատանքային ժամեր</strong>
<p>24/7 տեխնիկական աջակցություն</p>
</div>
<div class="contact-item">
<strong>Պատասխանի ժամանակ</strong>
<p>Մինչև 2 ժամ աշխատանքային ժամերին</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-faq-lavero-hy',
templateUrl: './faq-hy.component.html',
styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FaqLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,93 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Частые вопросы</h1>
<p class="subtitle">Быстрые ответы на популярные вопросы</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🛍️</div>
<h3>Как сделать заказ?</h3>
<div class="process-steps-compact">
<p>1. Добавьте товар в корзину</p>
<p>2. Укажите данные для доставки</p>
<p>3. Выберите способ оплаты</p>
<p>4. Подтвердите заказ</p>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">💳</div>
<h3>Способы оплаты</h3>
<ul class="compact-list">
<li>Банковские карты</li>
<li>СБП</li>
<li>Электронные кошельки</li>
<li>Наличные при получении*</li>
</ul>
<p class="note">*Зависит от продавца</p>
</div>
<div class="info-card wide">
<div class="card-icon">🚚</div>
<h3>Доставка</h3>
<div class="delivery-info">
<div class="delivery-item">
<strong>Цифровые товары</strong>
<p>Мгновенно на email</p>
</div>
<div class="delivery-item">
<strong>Физические товары</strong>
<p>СДЭК, Почта России, DPD</p>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">↩️</div>
<h3>Возврат товара</h3>
<p>Можно вернуть качественный товар в течение 7 дней, если он не использовался и сохранена упаковка.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🔒</div>
<h3>Безопасность</h3>
<div class="features-list">
<div class="feature">✓ Защищенные платежи</div>
<div class="feature">✓ Проверка продавцов</div>
<div class="feature">✓ Гарантия возврата</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">⏱️</div>
<h3>Обработка заказа</h3>
<p>Заказ обрабатывается сразу после оплаты. Продавец отправляет товар в течение 1-3 рабочих дней.</p>
</div>
<div class="info-card wide">
<div class="card-icon">💬</div>
<h3>Служба поддержки</h3>
<div class="contacts-grid">
<div class="contact-item">
<strong>Email</strong>
<a href="mailto:info@lavero.store">info@lavero.store</a>
</div>
<div class="contact-item">
<strong>Телефон</strong>
<a [href]="env.phoneTel">{{ env.phones.support }}</a>
</div>
<div class="contact-item">
<strong>Время работы</strong>
<p>24/7 техподдержка</p>
</div>
<div class="contact-item">
<strong>Время ответа</strong>
<p>До 2 часов в рабочее время</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-faq-lavero-ru',
templateUrl: './faq-ru.component.html',
styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FaqLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,92 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Guarantee</h1>
<p class="subtitle">Protecting your purchases</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🏷️</div>
<h3>Warranty Periods</h3>
<div class="warranty-periods">
<div class="warranty-item">
<strong>Electronics</strong>
<span>12-24 months</span>
</div>
<div class="warranty-item">
<strong>Computer Equipment</strong>
<span>12-36 months</span>
</div>
<div class="warranty-item">
<strong>Clothing and Footwear</strong>
<span>30 days - 6 months</span>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Warranty Conditions</h3>
<ul class="compact-list">
<li>Used as intended</li>
<li>No unauthorized repairs</li>
<li>Seals preserved</li>
<li>No mechanical damage</li>
<li>Warranty card available</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🛠️</div>
<h3>Your Rights for Defects</h3>
<ul class="compact-list">
<li>Free repair</li>
<li>Product replacement</li>
<li>Money refund</li>
<li>Price reduction</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">⏱️</div>
<h3>Repair Timeframe</h3>
<p>Maximum 45 days by law. If the deadline is violated, you can request a replacement or a refund.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🚫</div>
<h3>Warranty Does Not Apply</h3>
<div class="noguar-grid">
<div class="noguar-item">Mechanical damage</div>
<div class="noguar-item">Improper use</div>
<div class="noguar-item">Liquid exposure</div>
<div class="noguar-item">Unauthorized repair</div>
<div class="noguar-item">Force majeure</div>
<div class="noguar-item">Natural wear and tear</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📝</div>
<h3>How to File a Claim</h3>
<div class="process-steps-compact">
<p>1. Contact the seller</p>
<p>2. Describe the issue</p>
<p>3. Get the service address</p>
<p>4. Send the product</p>
<p>5. Receive the acceptance report</p>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Need Help?</h3>
<p>In case of disputes:</p>
<a href="mailto:info@lavero.store" class="contact-email">info&#64;lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="note">Subject: "Warranty Issue - Order #..."</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-guarantee-lavero-en',
templateUrl: './guarantee-en.component.html',
styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GuaranteeLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-guarantee-lavero-ru /> }
@case ('en') { <app-guarantee-lavero-en /> }
@case ('hy') { <app-guarantee-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { GuaranteeLaveroRuComponent } from './ru/guarantee-ru.component';
import { GuaranteeLaveroEnComponent } from './en/guarantee-en.component';
import { GuaranteeLaveroHyComponent } from './hy/guarantee-hy.component';
@Component({
selector: 'app-guarantee-lavero',
imports: [GuaranteeLaveroRuComponent, GuaranteeLaveroEnComponent, GuaranteeLaveroHyComponent],
templateUrl: './guarantee.component.html',
styleUrls: ['../../../../../pages/info/guarantee/guarantee.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GuaranteeLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,92 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Երաշխիք</h1>
<p class="subtitle">Ձեր գնումների պաշտպանություն</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🏷️</div>
<h3>Երաշխիքի ժամկետներ</h3>
<div class="warranty-periods">
<div class="warranty-item">
<strong>Էլեկտրոնիկա</strong>
<span>12-24 ամիս</span>
</div>
<div class="warranty-item">
<strong>Համակարգչային տեխնիկա</strong>
<span>12-36 ամիս</span>
</div>
<div class="warranty-item">
<strong>Հագուստ և կոշիկ</strong>
<span>30 օր - 6 ամիս</span>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Երաշխիքի պայմաններ</h3>
<ul class="compact-list">
<li>Օգտագործում ըստ նշանակության</li>
<li>Առանց ինքնուրույն նորոգման</li>
<li>Կապարանները պահպանված են</li>
<li>Մեխանիկական վնասներ չկան</li>
<li>Երաշխիքային տոմսը առկա է</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🛠️</div>
<h3>Ձեր իրավունքները թերության դեպքում</h3>
<ul class="compact-list">
<li>Անվճար նորոգում</li>
<li>Ապրանքի փոխարինում</li>
<li>Գումարի վերադարձ</li>
<li>Գնի նվազեցում</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">⏱️</div>
<h3>Նորոգման ժամկետ</h3>
<p>Օրենքով առավելագույնը 45 օր։ Եթե ժամկետը խախտվի ՝ կարող եք պահանջել փոխարինում կամ գումարի վերադարձ։</p>
</div>
<div class="info-card wide">
<div class="card-icon">🚫</div>
<h3>Երաշխիքը չի գործում</h3>
<div class="noguar-grid">
<div class="noguar-item">Մեխանիկական վնասներ</div>
<div class="noguar-item">Սխալ շահագործում</div>
<div class="noguar-item">Հեղուկի ներթափանցում</div>
<div class="noguar-item">Ինքնուրույն նորոգում</div>
<div class="noguar-item">Ֆորս-մաժոր</div>
<div class="noguar-item">Բնական մաշվածություն</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📝</div>
<h3>Ինչպես դիմել հայտ</h3>
<div class="process-steps-compact">
<p>1. Կապվեք վաճառողի հետ</p>
<p>2. Նկարագրեք խնդիրը</p>
<p>3. Ստացեք սերվիսի հասցեը</p>
<p>4. Ուղարկեք ապրանքը</p>
<p>5. Ստացեք ընդունման ակտը</p>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Օգնությու՞ն պետք է՞</h3>
<p>Վեճերի դեպքում՝</p>
<a href="mailto:info@lavero.store" class="contact-email">info&#64;lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="note">Թեմա՝ “Երաշխիքային հարց - Պատվեր №...”</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-guarantee-lavero-hy',
templateUrl: './guarantee-hy.component.html',
styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GuaranteeLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,92 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Гарантия</h1>
<p class="subtitle">Защита ваших покупок</p>
</div>
<div class="lavero-cards">
<div class="info-card wide">
<div class="card-icon">🏷️</div>
<h3>Сроки гарантии</h3>
<div class="warranty-periods">
<div class="warranty-item">
<strong>Электроника</strong>
<span>12-24 месяца</span>
</div>
<div class="warranty-item">
<strong>Компьютерная техника</strong>
<span>12-36 месяцев</span>
</div>
<div class="warranty-item">
<strong>Одежда и обувь</strong>
<span>30 дней - 6 месяцев</span>
</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon"></div>
<h3>Условия гарантии</h3>
<ul class="compact-list">
<li>Использование по назначению</li>
<li>Без самостоятельного ремонта</li>
<li>Сохранены пломбы</li>
<li>Нет механических повреждений</li>
<li>Есть гарантийный талон</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">🛠️</div>
<h3>Ваши права при браке</h3>
<ul class="compact-list">
<li>Бесплатный ремонт</li>
<li>Замена товара</li>
<li>Возврат денег</li>
<li>Снижение цены</li>
</ul>
</div>
<div class="info-card wide">
<div class="card-icon">⏱️</div>
<h3>Срок ремонта</h3>
<p>Максимум 45 дней по закону. Если срок нарушен - можно требовать замену или возврат денег.</p>
</div>
<div class="info-card wide">
<div class="card-icon">🚫</div>
<h3>Гарантия не действует</h3>
<div class="noguar-grid">
<div class="noguar-item">Механические повреждения</div>
<div class="noguar-item">Неправильная эксплуатация</div>
<div class="noguar-item">Попадание жидкости</div>
<div class="noguar-item">Самостоятельный ремонт</div>
<div class="noguar-item">Форс-мажор</div>
<div class="noguar-item">Естественный износ</div>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📝</div>
<h3>Как подать заявку</h3>
<div class="process-steps-compact">
<p>1. Свяжитесь с продавцом</p>
<p>2. Опишите проблему</p>
<p>3. Получите адрес сервиса</p>
<p>4. Отправьте товар</p>
<p>5. Получите акт приема</p>
</div>
</div>
<div class="info-card wide">
<div class="card-icon">📞</div>
<h3>Нужна помощь?</h3>
<p>При возникновении споров:</p>
<a href="mailto:info@lavero.store" class="contact-email">info&#64;lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="note">Тема: "Гарантийный вопрос - Заказ №..."</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-guarantee-lavero-ru',
templateUrl: './guarantee-ru.component.html',
styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GuaranteeLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-company-details-lavero-ru /> }
@case ('en') { <app-company-details-lavero-en /> }
@case ('hy') { <app-company-details-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { CompanyDetailsLaveroRuComponent } from './ru/company-details-ru.component';
import { CompanyDetailsLaveroEnComponent } from './en/company-details-en.component';
import { CompanyDetailsLaveroHyComponent } from './hy/company-details-hy.component';
@Component({
selector: 'app-company-details-lavero',
imports: [CompanyDetailsLaveroRuComponent, CompanyDetailsLaveroEnComponent, CompanyDetailsLaveroHyComponent],
templateUrl: './company-details.component.html',
styleUrls: ['../../../../../pages/legal/company-details/company-details.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CompanyDetailsLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,54 @@
<div class="legal-page">
<div class="legal-container">
<h1>Реквизиты организации / Company Details</h1>
<section class="legal-section">
<h2>Полное наименование / Full Name</h2>
<p>«ԼԱՎԵՐՈ» Սահմանափակ պատասխանատվությամբ ընկերություն</p>
<p>«ЛАВЕРО» Общество с Ограниченной Ответственностью</p>
<p>«LAVERO» LIMITED LIABILITY COMPANY</p>
</section>
<section class="legal-section">
<h2>Юридический адрес / Legal Address</h2>
<p>ՀԱՅԱՍՏԱՆ, ԿՈՏԱՅՔ, ԱԲՈՎՅԱՆ, ՎԵՐԻՆ ՊՏՂՆԻ, 3-րդ փողոց, 28, Տ Փ/Դ՝ 2228</p>
</section>
<section class="legal-section">
<h2>Основные реквизиты / Core Details</h2>
<div class="details-grid">
<div class="detail-item">
<strong>ՀՎՀՀ (ИНН/TIN):</strong>
<span>03590442</span>
</div>
<div class="detail-item">
<strong>Գրանցման համար (Registration Number):</strong>
<span>999.110.1583686</span>
</div>
<div class="detail-item">
<strong>Գրանցման ամսաթիվ (Date of Registration):</strong>
<span>18.05.2026</span>
</div>
</div>
</section>
<section class="legal-section">
<h2>Контактная информация / Contact Information</h2>
<div class="details-grid">
<div class="detail-item">
<strong>Email:</strong>
<span><a href="mailto:info@lavero.store">info@lavero.store</a></span>
</div>
<div class="detail-item">
<strong>Сайт / Website:</strong>
<span><a href="https://lavero.store" target="_blank">lavero.store</a></span>
</div>
</div>
</section>
<section class="legal-section">
<h2>Руководство / Management</h2>
<p><strong>Տնօրեն (Director):</strong> ԳԵՎՈՐԳ ՄԱԹԵՎՈՍՅԱՆ (GEVORG MATEVOSYAN)</p>
</section>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-company-details-lavero-en',
templateUrl: './company-details-en.component.html',
styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CompanyDetailsLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,54 @@
<div class="legal-page">
<div class="legal-container">
<h1>Реквизиты организации / Company Details</h1>
<section class="legal-section">
<h2>Полное наименование / Full Name</h2>
<p>«ԼԱՎԵՐՈ» Սահմանափակ պատասխանատվությամբ ընկերություն</p>
<p>«ЛАВЕРО» Общество с Ограниченной Ответственностью</p>
<p>«LAVERO» LIMITED LIABILITY COMPANY</p>
</section>
<section class="legal-section">
<h2>Юридический адрес / Legal Address</h2>
<p>ՀԱՅԱՍՏԱՆ, ԿՈՏԱՅՔ, ԱԲՈՎՅԱՆ, ՎԵՐԻՆ ՊՏՂՆԻ, 3-րդ փողոց, 28, Տ Փ/Դ՝ 2228</p>
</section>
<section class="legal-section">
<h2>Основные реквизиты / Core Details</h2>
<div class="details-grid">
<div class="detail-item">
<strong>ՀՎՀՀ (ИНН/TIN):</strong>
<span>03590442</span>
</div>
<div class="detail-item">
<strong>Գրանցման համար (Registration Number):</strong>
<span>999.110.1583686</span>
</div>
<div class="detail-item">
<strong>Գրանցման ամսաթիվ (Date of Registration):</strong>
<span>18.05.2026</span>
</div>
</div>
</section>
<section class="legal-section">
<h2>Контактная информация / Contact Information</h2>
<div class="details-grid">
<div class="detail-item">
<strong>Email:</strong>
<span><a href="mailto:info@lavero.store">info@lavero.store</a></span>
</div>
<div class="detail-item">
<strong>Сайт / Website:</strong>
<span><a href="https://lavero.store" target="_blank">lavero.store</a></span>
</div>
</div>
</section>
<section class="legal-section">
<h2>Руководство / Management</h2>
<p><strong>Տնօրեն (Director):</strong> ԳԵՎՈՐԳ ՄԱԹԵՎՈՍՅԱՆ (GEVORG MATEVOSYAN)</p>
</section>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-company-details-lavero-hy',
templateUrl: './company-details-hy.component.html',
styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CompanyDetailsLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,54 @@
<div class="legal-page">
<div class="legal-container">
<h1>Реквизиты организации / Company Details</h1>
<section class="legal-section">
<h2>Полное наименование / Full Name</h2>
<p>«ԼԱՎԵՐՈ» Սահմանափակ պատասխանատվությամբ ընկերություն</p>
<p>«ЛАВЕРО» Общество с Ограниченной Ответственностью</p>
<p>«LAVERO» LIMITED LIABILITY COMPANY</p>
</section>
<section class="legal-section">
<h2>Юридический адрес / Legal Address</h2>
<p>ՀԱՅԱՍՏԱՆ, ԿՈՏԱՅՔ, ԱԲՈՎՅԱՆ, ՎԵՐԻՆ ՊՏՂՆԻ, 3-րդ փողոց, 28, Տ Փ/Դ՝ 2228</p>
</section>
<section class="legal-section">
<h2>Основные реквизиты / Core Details</h2>
<div class="details-grid">
<div class="detail-item">
<strong>ՀՎՀՀ (ИНН/TIN):</strong>
<span>03590442</span>
</div>
<div class="detail-item">
<strong>Գրանցման համար (Registration Number):</strong>
<span>999.110.1583686</span>
</div>
<div class="detail-item">
<strong>Գրանցման ամսաթիվ (Date of Registration):</strong>
<span>18.05.2026</span>
</div>
</div>
</section>
<section class="legal-section">
<h2>Контактная информация / Contact Information</h2>
<div class="details-grid">
<div class="detail-item">
<strong>Email:</strong>
<span><a href="mailto:info@lavero.store">info@lavero.store</a></span>
</div>
<div class="detail-item">
<strong>Сайт / Website:</strong>
<span><a href="https://lavero.store" target="_blank">lavero.store</a></span>
</div>
</div>
</section>
<section class="legal-section">
<h2>Руководство / Management</h2>
<p><strong>Տնօրեն (Director):</strong> ԳԵՎՈՐԳ ՄԱԹԵՎՈՍՅԱՆ (GEVORG MATEVOSYAN)</p>
</section>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-company-details-lavero-ru',
templateUrl: './company-details-ru.component.html',
styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CompanyDetailsLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,162 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Payment Terms</h1>
<p class="subtitle">All payment methods and transaction conditions</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. General Provisions</h2>
<p>1.1. These Terms define the payment procedure for Goods and Services purchased by Buyers through the Lavero Store Marketplace.</p>
<p>1.2. Payment is made for Goods/Services listed by independent Sellers. The Marketplace acts as an information intermediary and provides the technical infrastructure for processing payments.</p>
<p>1.3. Payment for goods and services on the Marketplace is made in Russian rubles (RUB).</p>
<p>1.4. Prices for Goods/Services are set by Sellers independently and are indicated on the corresponding Goods/Services page.</p>
</section>
<section class="info-card wide">
<div class="card-icon">💳</div>
<h2>2. Payment Methods</h2>
<p>2.1. The Marketplace supports the following payment methods:</p>
<div class="payment-methods-grid">
<div class="method-item">
<span class="method-icon">🏦</span>
<div>
<strong>Bank Cards</strong>
<p>Visa, Mastercard, МИР</p>
</div>
</div>
<div class="method-item">
<span class="method-icon"></span>
<div>
<strong>SBP</strong>
<p>Fast Payment System - instant transfer via mobile banking app</p>
</div>
</div>
<div class="method-item">
<span class="method-icon">👛</span>
<div>
<strong>E-Wallets</strong>
<p>ЮMoney, QIWI (if available)</p>
</div>
</div>
<div class="method-item">
<span class="method-icon">🔗</span>
<div>
<strong>Payment by Link</strong>
<p>Generation of a unique payment link for each order</p>
</div>
</div>
</div>
<p>2.2. Available payment methods may vary depending on the Seller and the type of Goods/Services.</p>
<p>2.3. All payments are processed through certified payment systems in compliance with PCI DSS security standards.</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>3. Payment Process</h2>
<p>3.1. The order payment procedure includes the following steps:</p>
<ol class="compact-list">
<li>Selection of Goods/Services and adding them to the cart</li>
<li>Placing an order with contact details and delivery method</li>
<li>Choosing a payment method from the available options</li>
<li>Redirect to the secure payment system page</li>
<li>Entering payment details and confirming the payment</li>
<li>Receiving a successful payment notification</li>
</ol>
<p>3.2. When paying by bank card, the Buyer may be redirected to the issuing bank's page for additional authentication (3D-Secure).</p>
<p>3.3. The Buyer's payment obligation is considered fulfilled from the moment the funds are received in the payment system account.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>4. Payment Security</h2>
<p>4.1. All payments are processed through a secure HTTPS connection using TLS 1.2 protocol and above.</p>
<p>4.2. The Marketplace does not store full bank card data of Buyers. Payment data processing is carried out by certified payment aggregators.</p>
<div class="features-list">
<div class="feature">✓ TLS 1.2+ Encryption</div>
<div class="feature">✓ 3D-Secure Technology</div>
<div class="feature">✓ Fraud Protection</div>
<div class="feature">✓ Data Confidentiality</div>
</div>
<p>4.3. To protect against fraud, 3D-Secure technology is used, requiring payment confirmation via SMS code or push notification from the bank.</p>
<p>4.4. In case of suspicious activity, the payment system has the right to request additional identity verification of the Buyer.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>5. Payment Confirmation</h2>
<p>5.1. After successful payment, the Buyer receives a confirmation to the email address provided during checkout.</p>
<p>5.2. The confirmation contains the following information:</p>
<ul class="compact-list">
<li>Order number</li>
<li>Payment date and time</li>
<li>Payment amount</li>
<li>Order contents</li>
<li>Seller contact details</li>
</ul>
<p>5.3. Order information is also displayed in the Buyer's personal account on the Marketplace (if registered).</p>
<p>5.4. A fiscal receipt is sent by the Seller in accordance with the requirements of the legislation of the Russian Federation.</p>
</section>
<section class="info-card wide">
<div class="card-icon">↩️</div>
<h2>6. Refunds</h2>
<p>6.1. The refund procedure is governed by the <a [routerLink]="'/return-policy' | langRoute">Return Policy</a> and depends on the type of purchased Goods/Services.</p>
<p>6.2. Refunds are made to the same payment instrument from which the payment was made.</p>
<p>6.3. The refund processing time is:</p>
<div class="refund-times">
<div class="refund-item">
<strong>Bank Card</strong>
<span>3-30 days</span>
</div>
<div class="refund-item">
<strong>E-Wallet</strong>
<span>1-5 days</span>
</div>
<div class="refund-item">
<strong>SBP</strong>
<span>1-3 days</span>
</div>
</div>
<p class="note">Refunds are made to the same payment instrument used for the original payment</p>
<p>6.4. The Marketplace does not charge a fee for processing refunds. Payment system and bank fees may apply in accordance with their tariffs.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>7. Failed Payments</h2>
<p>7.1. A payment may be declined for the following reasons:</p>
<ul class="compact-list">
<li>Insufficient funds in the account</li>
<li>Incorrectly entered payment details</li>
<li>Card is blocked or expired</li>
<li>Transaction limits set by the bank have been exceeded</li>
<li>Transaction rejected by the security system</li>
</ul>
<p>7.2. In case of an unsuccessful payment, the Buyer receives a notification indicating the reason for the decline.</p>
<p>7.3. If you experience payment issues, it is recommended to:</p>
<ul class="compact-list">
<li>Check the accuracy of the entered data</li>
<li>Contact the card issuing bank to clarify the reason for the decline</li>
<li>Try an alternative payment method</li>
<li>Contact support: <a href="mailto:info@lavero.store">info@lavero.store</a></li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📧</div>
<h2>8. Payment Inquiries Contact</h2>
<p>For questions related to order payments, you can contact us:</p>
<ul class="compact-list">
<li><strong>Email:</strong> <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></li>
<li><strong>Phone:</strong> <a [href]="env.phoneTel">{{ env.phones.support }}</a></li>
<li><strong>Working hours:</strong> 24/7 (technical support)</li>
<li><strong>Average response time:</strong> Up to 24 hours on business days</li>
</ul>
<p>When contacting us, please include your order number and a brief description of the issue for faster resolution.</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
import { RouterLink } from '@angular/router';
import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe';
@Component({
selector: 'app-payment-terms-lavero-en',
imports: [RouterLink, LangRoutePipe],
templateUrl: './payment-terms-en.component.html',
styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PaymentTermsLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,162 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Վճարման պայմաններ</h1>
<p class="subtitle">Վճարման բոլոր եղանակները և գործարքների իրականացման պայմանները</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. Ընդհանուր դրույթներ</h2>
<p>1.1. Սույն Կանոնները սահմանում են Lavero Store Մարկեթպլեյսի միջոցով Գնորդների կողմից ձեռք բերվող Ապրանքների և Ծառայությունների վճարման կարգը։</p>
<p>1.2. Վճարումը կատարվում է անկախ Վաճառողների կողմից տեղադրված Ապրանքների/Ծառայությունների համար։ Մարկեթպլեյսը հանդես է գալիս որպես տեղեկատվական միջնորդ և ապահովում է տեխնիկական ենթակառուցվածք վճարումների իրականացման համար։</p>
<p>1.3. Մարկեթպլեյսում ապրանքների և ծառայությունների վճարումը կատարվում է ռուսական ռուբլով (RUB)։</p>
<p>1.4. Ապրանքների/Ծառայությունների գները սահմանվում են Վաճառողների կողմից ինքնուրույն և նշված են համապատասխան Ապրանքի/Ծառայության էջում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">💳</div>
<h2>2. Վճարման եղանակներ</h2>
<p>2.1. Մարկեթպլեյսը աջակցում է վճարման հետևյալ եղանակները՝</p>
<div class="payment-methods-grid">
<div class="method-item">
<span class="method-icon">🏦</span>
<div>
<strong>Բանկային քարտեր</strong>
<p>Visa, Mastercard, ՄИР</p>
</div>
</div>
<div class="method-item">
<span class="method-icon"></span>
<div>
<strong>Արագ վճարման համակարգ (ՍБП)</strong>
<p>Արագ վճարման համակարգ - ակնթարծային փոխանցում բանկի բջջային հավելվածի միջոցով</p>
</div>
</div>
<div class="method-item">
<span class="method-icon">👛</span>
<div>
<strong>Էլեկտրոնային դրամապանակներ</strong>
<p>ЮMoney, QIWI (առկայության դեպքում)</p>
</div>
</div>
<div class="method-item">
<span class="method-icon">🔗</span>
<div>
<strong>Վճարում հղման միջոցով</strong>
<p>Յուրաքանչյուր պատվերի համար յուրահատուկ վճարման հղման ստեղծում</p>
</div>
</div>
</div>
<p>2.2. Հասանելի վճարման եղանակները կարող են տարբերվել կախված Վաճառողից և Ապրանքի/Ծառայության տեսակից։</p>
<p>2.3. Բոլոր վճարումները մշակվում են սերտիֆիկացված վճարման համակարգերի միջոցով՝ PCI DSS անվտանգության ստանդարտներին համապատասխան։</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>3. Վճարման գործընթացը</h2>
<p>3.1. Պատվերի վճարման գործընթացը ներառում է հետևյալ քայլերը՝</p>
<ol class="compact-list">
<li>Ապրանքների/Ծառայությունների ընտրություն և դրանց զամբյուղին ավելացնել</li>
<li>Պատվերի ձևակերպում՝ կոնտակտային տվյալների և առաքման եղանակի նշումով</li>
<li>Վճարման եղանակի ընտրությունը հասանելի տարբերակներից</li>
<li>Վերահղում վճարման համակարգի պաշտպանված էջին</li>
<li>Վճարման տվյալների մուտքագրում և վճարման հաստատում</li>
<li>Հաջող վճարման մասին ծանուցման ստացում</li>
</ol>
<p>3.2. Բանկային քարտով վճարելիս Գնորդը կարող է վերահղվել թողարկող բանկի էջ լրացուցիչ նույնականացման համար (3D-Secure)։</p>
<p>3.3. Գնորդի վճարման պարտավորությունը համարվում է կատարված վճարման համակարգի հաշվին դրամական միջոցների մուտքագրման պահից։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>4. Վճարումների անվտանգություն</h2>
<p>4.1. Բոլոր վճարումները մշակվում են պաշտպանված HTTPS կապակցով՝ TLS 1.2 և ավելի բարձր արթանագրի օգտագործմամբ։</p>
<p>4.2. Մարկեթպլեյսը չի պահպանում Գնորդների բանկային քարտերի լիարժեք տվյալները։ Վճարման տվյալների մշակումը իրականացվում է սերտիֆիկացված վճարման ագրեգատորների կողմից։</p>
<div class="features-list">
<div class="feature">✓ TLS 1.2+ գաղտնագրում</div>
<div class="feature">✓ 3D-Secure տեխնոլոգիա</div>
<div class="feature">✓ Խաբեությունից պաշտպանություն</div>
<div class="feature">✓ Տվյալների գաղտնիություն</div>
</div>
<p>4.3. Խաբեությունից պաշտպանության համար կիրառվում է 3D-Secure տեխնոլոգիան՝ պահանջելով վճարման հաստատումը SMS կոդի կամ բանկի push ծանուցման միջոցով։</p>
<p>4.4. Կասկածելի գործունեության դեպքում վճարման համակարգը իրավունք ունի պահանջել Գնորդի ինքնության լրացուցիչ ստուգում։</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>5. Վճարման հաստատում</h2>
<p>5.1. Հաջող վճարմանից հետո Գնորդը ստանում է հաստատում պատվերի ձևակերպման թելադրված էլ. փոստի հասցեին։</p>
<p>5.2. Հաստատումը պարունակում է հետևյալ տեղեկությունը՝</p>
<ul class="compact-list">
<li>Պատվերի համար</li>
<li>Վճարման ամսաթիվ և ժամ</li>
<li>Վճարման գումար</li>
<li>Պատվերի կազմը</li>
<li>Վաճառողի կոնտակտային տվյալներ</li>
</ul>
<p>5.3. Պատվերի տեղեկությունը նաև ցուցադրվում է Գնորդի անձնական ընթացում Մարկեթպլեյսում (գրանցման դեպքում)։</p>
<p>5.4. Հարկային կտրոնը ուղարկվում է Վաճառողի կողմից՝ Ռուսաստանի Դաշնության օրենսդրության պահանջներին համապատասխան։</p>
</section>
<section class="info-card wide">
<div class="card-icon">↩️</div>
<h2>6. Միջոցների վերադարձ</h2>
<p>6.1. Դրամական միջոցների վերադարձի կարգը կարգավորվում է <a [routerLink]="'/return-policy' | langRoute">Վերադարձի քաղաքականությամբ</a> և կախված է ձեռք բերված Ապրանքի/Ծառայության տեսակից։</p>
<p>6.2. Միջոցների վերադարձը կատարվում է նույն վճարման գործիքին՝ որից կատարվել էր վճարումը։</p>
<p>6.3. Դրամական միջոցների վերադարձի ժամկետը կազմում է՝</p>
<div class="refund-times">
<div class="refund-item">
<strong>Բանկային քարտ</strong>
<span>3-30 օր</span>
</div>
<div class="refund-item">
<strong>Էլեկտրոնային դրամապանակ</strong>
<span>1-5 օր</span>
</div>
<div class="refund-item">
<strong>Արագ վճարման համակարգ (ՍБП)</strong>
<span>1-3 օր</span>
</div>
</div>
<p class="note">Վերադարձը կատարվում է նույն վճարման գործիքին՝ որը օգտագործվել է վճարման ժամանակ</p>
<p>6.4. Միջոցների վերադարձի մշակման համար Մարկեթպլեյսը միջնորդավճար չի գանձում։ Վճարման համակարգերի և բանկերի միջնորդավճարները կարող են կիրառվել դրանց սակագներին համապատասխան։</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>7. Անհաջող վճարումներ</h2>
<p>7.1. Վճարումը կարող է մերժվել հետևյալ պատճառներով՝</p>
<ul class="compact-list">
<li>Հաշվին անբավարար միջոցներ</li>
<li>Վճարման տվյալները սխալ են մուտքագրված</li>
<li>Քարտը արգելափակված է կամ ժամկետը լրացել է</li>
<li>Բանկի կողմից սահմանված գործարքների սահմանաչափերը գերազանցված է</li>
<li>Անվտանգության համակարգի կողմից գործարքի մերժում</li>
</ul>
<p>7.2. Անհաջող վճարման դեպքում Գնորդը ստանում է ծանուցում՝ մերժման պատճառի նշումով։</p>
<p>7.3. Վճարման խնդիրների դեպքում խորհուրդ է տրվում՝</p>
<ul class="compact-list">
<li>Ստուգել մուտքագրված տվյալների ճշտությունը</li>
<li>Կապվել քարտ թողարկող բանկի հետ մերժման պատճառը պարզելու համար</li>
<li>Փորձել այլընտրանքային վճարման եղանակ</li>
<li>Դիմել աջակցության ծառայությանը՝ <a href="mailto:info@lavero.store">info@lavero.store</a></li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📧</div>
<h2>8. Վճարման հարցերի կապակցության կոնտակտներ</h2>
<p>Պատվերների վճարման հետ կապված հարցերի համար կարող եք դիմել՝</p>
<ul class="compact-list">
<li><strong>Email:</strong> <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></li>
<li><strong>Հեռախոս՝</strong> <a [href]="env.phoneTel">{{ env.phones.support }}</a></li>
<li><strong>Աշխատանքի ժամերը՝</strong> Հստակետ (տեխնիկական աջակցություն)</li>
<li><strong>Պատասխանի միջին ժամանակը՝</strong> Մինչև 24 ժամ աշխատանքային օրերին</li>
</ul>
<p>Դիմելիս նշեք պատվերի համարը և խնդրի հակիրճ նկարագրությունը՝ հարցի ավելի արագ լուծման համար։</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
import { RouterLink } from '@angular/router';
import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe';
@Component({
selector: 'app-payment-terms-lavero-hy',
imports: [RouterLink, LangRoutePipe],
templateUrl: './payment-terms-hy.component.html',
styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PaymentTermsLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-payment-terms-lavero-ru /> }
@case ('en') { <app-payment-terms-lavero-en /> }
@case ('hy') { <app-payment-terms-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { PaymentTermsLaveroRuComponent } from './ru/payment-terms-ru.component';
import { PaymentTermsLaveroEnComponent } from './en/payment-terms-en.component';
import { PaymentTermsLaveroHyComponent } from './hy/payment-terms-hy.component';
@Component({
selector: 'app-payment-terms-lavero',
imports: [PaymentTermsLaveroRuComponent, PaymentTermsLaveroEnComponent, PaymentTermsLaveroHyComponent],
templateUrl: './payment-terms.component.html',
styleUrls: ['../../../../../pages/legal/payment-terms/payment-terms.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PaymentTermsLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,162 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Правила оплаты</h1>
<p class="subtitle">Все способы оплаты и условия проведения платежей</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. Общие положения</h2>
<p>1.1. Настоящие Правила определяют порядок оплаты Товаров и Услуг, приобретаемых Покупателями через Маркетплейс Lavero Store.</p>
<p>1.2. Оплата производится за Товары/Услуги, размещенные независимыми Продавцами. Маркетплейс выступает в качестве информационного посредника и обеспечивает техническую инфраструктуру для проведения платежей.</p>
<p>1.3. Оплата товаров и услуг на Маркетплейсе осуществляется в российских рублях (RUB).</p>
<p>1.4. Цены на Товары/Услуги устанавливаются Продавцами самостоятельно и указываются на странице соответствующего Товара/Услуги.</p>
</section>
<section class="info-card wide">
<div class="card-icon">💳</div>
<h2>2. Способы оплаты</h2>
<p>2.1. Маркетплейс поддерживает следующие способы оплаты:</p>
<div class="payment-methods-grid">
<div class="method-item">
<span class="method-icon">🏦</span>
<div>
<strong>Банковские карты</strong>
<p>Visa, Mastercard, МИР</p>
</div>
</div>
<div class="method-item">
<span class="method-icon"></span>
<div>
<strong>СБП</strong>
<p>Система быстрых платежей - мгновенный перевод через мобильное приложение банка</p>
</div>
</div>
<div class="method-item">
<span class="method-icon">👛</span>
<div>
<strong>Электронные кошельки</strong>
<p>ЮMoney, QIWI (при наличии)</p>
</div>
</div>
<div class="method-item">
<span class="method-icon">🔗</span>
<div>
<strong>Оплата по ссылке</strong>
<p>Генерация уникальной платежной ссылки для каждого заказа</p>
</div>
</div>
</div>
<p>2.2. Доступные способы оплаты могут различаться в зависимости от Продавца и типа Товара/Услуги.</p>
<p>2.3. Все платежи обрабатываются через сертифицированные платежные системы с соблюдением стандартов безопасности PCI DSS.</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>3. Процесс оплаты</h2>
<p>3.1. Процедура оплаты заказа включает следующие этапы:</p>
<ol class="compact-list">
<li>Выбор Товаров/Услуг и добавление их в корзину</li>
<li>Оформление заказа с указанием контактных данных и способа доставки</li>
<li>Выбор способа оплаты из доступных вариантов</li>
<li>Перенаправление на защищенную страницу платежной системы</li>
<li>Ввод платежных данных и подтверждение оплаты</li>
<li>Получение уведомления об успешной оплате</li>
</ol>
<p>3.2. При оплате банковской картой Покупатель может быть перенаправлен на страницу банка-эмитента для прохождения дополнительной аутентификации (3D-Secure).</p>
<p>3.3. Обязательство Покупателя по оплате считается исполненным с момента поступления денежных средств на счет платежной системы.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>4. Безопасность платежей</h2>
<p>4.1. Все платежи обрабатываются через защищенное HTTPS-соединение с использованием протокола TLS 1.2 и выше.</p>
<p>4.2. Маркетплейс не хранит полные данные банковских карт Покупателей. Обработка платежных данных осуществляется сертифицированными платежными агрегаторами.</p>
<div class="features-list">
<div class="feature">✓ Шифрование TLS 1.2+</div>
<div class="feature">✓ Технология 3D-Secure</div>
<div class="feature">✓ Защита от мошенничества</div>
<div class="feature">✓ Конфиденциальность данных</div>
</div>
<p>4.3. Для защиты от мошенничества применяется технология 3D-Secure, требующая подтверждения платежа через SMS-код или push-уведомление от банка.</p>
<p>4.4. В случае подозрительной активности платежная система имеет право запросить дополнительную верификацию личности Покупателя.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>5. Подтверждение оплаты</h2>
<p>5.1. После успешной оплаты Покупатель получает подтверждение на указанный при оформлении заказа адрес электронной почты.</p>
<p>5.2. Подтверждение содержит следующую информацию:</p>
<ul class="compact-list">
<li>Номер заказа</li>
<li>Дата и время оплаты</li>
<li>Сумма платежа</li>
<li>Состав заказа</li>
<li>Контактные данные Продавца</li>
</ul>
<p>5.3. Информация о заказе также отображается в личном кабинете Покупателя на Маркетплейсе (при наличии регистрации).</p>
<p>5.4. Фискальный чек направляется Продавцом в соответствии с требованиями законодательства РФ.</p>
</section>
<section class="info-card wide">
<div class="card-icon">↩️</div>
<h2>6. Возврат средств</h2>
<p>6.1. Порядок возврата денежных средств регулируется <a [routerLink]="'/return-policy' | langRoute">Политикой возврата</a> и зависит от типа приобретенного Товара/Услуги.</p>
<p>6.2. Возврат средств производится на тот же платежный инструмент, с которого была произведена оплата.</p>
<p>6.3. Срок возврата денежных средств составляет:</p>
<div class="refund-times">
<div class="refund-item">
<strong>Банковская карта</strong>
<span>3-30 дней</span>
</div>
<div class="refund-item">
<strong>Электронный кошелек</strong>
<span>1-5 дней</span>
</div>
<div class="refund-item">
<strong>СБП</strong>
<span>1-3 дня</span>
</div>
</div>
<p class="note">Возврат производится на тот же платежный инструмент, который использовался при оплате</p>
<p>6.4. За обработку возврата средств Маркетплейс комиссию не взимает. Комиссии платежных систем и банков могут применяться в соответствии с их тарифами.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>7. Неуспешные платежи</h2>
<p>7.1. Платеж может быть отклонен по следующим причинам:</p>
<ul class="compact-list">
<li>Недостаточно средств на счете</li>
<li>Неверно введены платежные данные</li>
<li>Карта заблокирована или просрочена</li>
<li>Превышены лимиты на операции, установленные банком</li>
<li>Отказ в проведении транзакции системой безопасности</li>
</ul>
<p>7.2. В случае неуспешной оплаты Покупатель получает уведомление с указанием причины отказа.</p>
<p>7.3. При возникновении проблем с оплатой рекомендуется:</p>
<ul class="compact-list">
<li>Проверить правильность введенных данных</li>
<li>Связаться с банком-эмитентом карты для уточнения причины отказа</li>
<li>Попробовать альтернативный способ оплаты</li>
<li>Обратиться в службу поддержки: <a href="mailto:info@lavero.store">info@lavero.store</a></li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📧</div>
<h2>8. Контакты для вопросов по оплате</h2>
<p>По вопросам, связанным с оплатой заказов, вы можете обратиться:</p>
<ul class="compact-list">
<li><strong>Email:</strong> <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></li>
<li><strong>Телефон:</strong> <a [href]="env.phoneTel">{{ env.phones.support }}</a></li>
<li><strong>Время работы:</strong> Круглосуточно (техническая поддержка)</li>
<li><strong>Среднее время ответа:</strong> До 24 часов в рабочие дни</li>
</ul>
<p>При обращении указывайте номер заказа и краткое описание проблемы для более быстрого решения вопроса.</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
import { RouterLink } from '@angular/router';
import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe';
@Component({
selector: 'app-payment-terms-lavero-ru',
imports: [RouterLink, LangRoutePipe],
templateUrl: './payment-terms-ru.component.html',
styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PaymentTermsLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,277 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Privacy Policy</h1>
<p class="subtitle">Protection of your personal data</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. GENERAL PROVISIONS</h2>
<p>1.1. This Privacy Policy (hereinafter — the Policy) defines the obligations of the Limited Liability Company «ЛАВЕРО» (hereinafter — the Operator) regarding the processing, use, storage, and protection of personal data (hereinafter PD, Personal Data) of users (hereinafter — the User).</p>
<p>1.2. The Operator undertakes to strictly observe the rights and freedoms of individuals when processing their personal data, including the protection of the right to privacy, personal and family confidentiality.</p>
<p>1.3. The Personal Data Processing Policy (hereinafter — the Policy) has been developed in accordance with Federal Law No. 152-FZ dated July 27, 2006 «On Personal Data» (hereinafter — FZ-152).</p>
<p>1.4. The Policy can be reviewed on the Operator's website on the Internet at: <a href="https://lavero.store">https://lavero.store</a>.</p>
<p>1.5. Applies to all activities related to the processing of personal data on the website <a href="https://lavero.store">https://lavero.store</a> and in the Operator's information systems.</p>
<p>1.6. A User who places an order, opens a personal account, or otherwise interacts with the Operator expresses consent to the processing of their personal data in accordance with the Policy and the legislation of the Russian Federation. Continued use of the website indicates agreement with the provisions of the Policy. A User who is not willing to agree to the terms should refrain from using the resource.</p>
<p><strong>Additionally:</strong> This Policy applies to personal data collected both before and after the document comes into effect.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📖</div>
<h2>2. TERMS AND DEFINITIONS</h2>
<p>The following main terms and definitions are used in this Policy:</p>
<div class="compact-list">
<p><strong>Personal Data (PD)</strong> — any information directly or indirectly related to a specific individual (personal data subject).</p>
<p><strong>Personal Data Information System (PDIS)</strong> — a set of personal data stored in databases, as well as technologies and tools for their processing.</p>
<p><strong>Automated PD Processing</strong> — data processing using computer tools.</p>
<p><strong>PD Blocking</strong> — temporary suspension of data processing (except in cases of data clarification).</p>
<p><strong>PD Anonymization</strong> — actions that make it impossible to determine the ownership of data to a specific person without additional information.</p>
<p><strong>Website (Site)</strong> — an automated information system available on the Internet at: <a href="https://lavero.store">https://lavero.store</a>.</p>
<p><strong>PD Processing</strong> — any actions with personal data, including collection, recording, storage, updating, use, transfer, destruction, and other operations.</p>
<p><strong>Operator</strong> — a state or private body that independently or jointly organizes the processing of personal data.</p>
<p><strong>PD Provision</strong> — transfer of data to a specific person or group of persons.</p>
<p><strong>PD Distribution</strong> — disclosure of data to an indefinite number of persons, including publication in the media or on the Internet.</p>
<p><strong>Cross-border PD Transfer</strong> — transfer of data to foreign authorities, companies, or individuals.</p>
<p><strong>PD Destruction</strong> — actions leading to the loss of the ability to recover data or the destruction of physical media.</p>
<p><strong>PD Subject</strong> — an individual whose information is being processed.</p>
<p><strong>PD Confidentiality</strong> — the Operator's obligation to protect data from distribution without the consent of the subject or a legal basis.</p>
<p><strong>Seller (Contractor)</strong> — a person offering goods or services on the website <a href="https://lavero.store">https://lavero.store</a>.</p>
<p><strong>User</strong> — a person visiting or using resources managed by the Operator, including the website <a href="https://lavero.store">https://lavero.store</a>.</p>
<p><strong>Order</strong> — an order for goods or services placed by the User on the website.</p>
<p><strong>Cookies</strong> — small files saved on the user's device to remember preferences and actions during subsequent visits to the website.</p>
</div>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>3. LEGAL BASIS FOR PERSONAL DATA PROCESSING</h2>
<p>3.1. The legal basis for PD Processing, depending on the purposes of the process involving PD Processing, may be:</p>
<h3>3.1.1. The Constitution of the Russian Federation, as well as a set of legal acts:</h3>
<ul class="compact-list">
<li>Tax Code of the Russian Federation;</li>
<li>Civil Code of the Russian Federation;</li>
<li>Articles 8690 of the Labor Code of the Russian Federation;</li>
<li>Federal Law No. 115-FZ dated August 7, 2001 «On Countering the Legalization (Laundering) of Proceeds from Crime and the Financing of Terrorism»;</li>
<li>Federal Law No. 152-FZ dated July 27, 2006 «On Personal Data»;</li>
<li>Federal Law No. 39-FZ dated April 22, 1996 «On the Securities Market»;</li>
<li>Federal Law No. 208-FZ dated December 26, 1995 «On Joint-Stock Companies»;</li>
<li>Federal Law No. 149-FZ dated July 27, 2006 «On Information, Information Technologies and Information Protection»;</li>
<li>Federal Law No. 27-FZ dated April 1, 1996 «On Individual (Personalized) Accounting in the Mandatory Pension Insurance System»;</li>
<li>Federal Law No. 63-FZ dated April 6, 2011 «On Electronic Signatures»;</li>
<li>Federal Law No. 402-FZ dated December 6, 2011 «On Accounting»;</li>
<li>Federal Law No. 161-FZ dated June 27, 2011 «On the National Payment System»;</li>
<li>Decree of the Government of the Russian Federation No. 687 dated September 15, 2008 «On Approval of the Regulation on the Specifics of Personal Data Processing Carried Out Without the Use of Automation Tools»;</li>
<li>Decree of the Government of the Russian Federation No. 1119 dated November 1, 2012 "On Approval of Requirements for the Protection of Personal Data During Their Processing in Personal Data Information Systems"</li>
<li>other regulatory legal acts of the Russian Federation and regulatory documents of executive government bodies.</li>
</ul>
<p>3.1.2. The Operator's Charter.</p>
<p>3.1.3. Agreements concluded between the Operator and the Personal Data Subject, including in the case of the Operator exercising its right to assign rights (claims) under such agreements, between the Operator and another person who has entrusted the Operator with PD Processing, as well as for concluding agreements in which Personal Data Subjects are parties.</p>
<p>3.1.4. Consent to PD Processing (in cases not directly provided for by the legislation of the Russian Federation, but corresponding to the Operator's authority), including consent of applicants for vacant positions to PD Processing, consent of interns to PD Processing, consent of employees to PD Processing; consent of clients to PD Processing, consent of Users of the respective Website, consent of other Personal Data Subjects.</p>
<p>3.1.5. An agreement between the Operator and a third party, where the latter entrusts the Operator with the processing of personal data of the Personal Data Subject or transfers personal data of the Personal Data Subject based on the concluded agreement.</p>
</section>
<section class="info-card wide">
<div class="card-icon">👥</div>
<h2>4. CATEGORIES OF PERSONAL DATA SUBJECTS</h2>
<p>4.1. The Operator processes PD obtained in accordance with the law, belonging to:</p>
<ul class="compact-list">
<li>Job candidates and employees of the Operator;</li>
<li>Former employees of the Operator;</li>
<li>Close relatives/family members of the Operator's employees, interns;</li>
<li>Potential clients, individual clients, individual entrepreneur clients;</li>
<li>Individuals who have entered into civil law contracts with the Operator;</li>
<li>Users of the Operator's Websites, Order recipients;</li>
<li>Clients of other legal entities;</li>
<li>Owners of the Operator;</li>
<li>Other subjects who have entered into or intend to enter into contractual relationships with the Operator.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📝</div>
<h2>5. CATEGORIES OF PROCESSED PERSONAL DATA</h2>
<p>5.1. The Operator processes the following categories of User PD:</p>
<ul class="compact-list">
<li>Information obtained during registration and/or placing an Order (last name, first name, actual address, phone number, email address, cookies);</li>
<li>Information obtained during interaction with Users (last name, first name, patronymic, gender, place of birth, date of birth, passport data, address, contacts);</li>
<li>Information about the method of delivery and payment of the Order;</li>
<li>Information about User complaints;</li>
<li>Geolocation (location) information.</li>
</ul>
<p>5.2. Personal data may be obtained by the Operator through:</p>
<ul class="compact-list">
<li>Submission by Subjects through forms on the Website or by email;</li>
<li>Receipt from third parties (Sellers, counterparties) in accordance with the legislation of the Russian Federation.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>6. PRINCIPLES, PROCEDURES, AND CONDITIONS OF PROCESSING</h2>
<h3>6.1. Principles of Personal Data Processing</h3>
<p>PD Processing by the Operator is carried out based on the following principles:</p>
<ul class="compact-list">
<li>legality and fair basis;</li>
<li>limiting PD Processing to achieving specific, predetermined, and legitimate purposes;</li>
<li>preventing PD Processing incompatible with the purposes of PD collection;</li>
<li>ensuring accuracy, sufficiency, and relevance of PD;</li>
<li>storing PD no longer than required by the purposes of Processing;</li>
<li>destroying or anonymizing PD upon achieving the purposes of their Processing.</li>
</ul>
<h3>6.2. Obligations of the Operator's Employees</h3>
<p>Employees of the Operator authorized to process Personal Data are required to:</p>
<ul class="compact-list">
<li>Know and comply with the provisions of the legislation of the Russian Federation in the field of PD;</li>
<li>Know and comply with the provisions of this Policy;</li>
<li>Process PD only within the scope of their job responsibilities;</li>
<li>Not disclose PD processed by the Operator;</li>
<li>Report actions that may lead to violations of the Policy.</li>
</ul>
<h3>6.3-6.24. Additional Conditions</h3>
<p>Include conditions for processing, storage, cross-border data transfer, work with publicly available sources, special and biometric data, as well as the procedure for obtaining clarifications in accordance with the legislation of the Russian Federation.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>7. RIGHTS OF THE PERSONAL DATA SUBJECT</h2>
<h3>7.1. Subject's Consent</h3>
<p>The PD Subject gives consent to Processing freely, of their own will and in their own interest.</p>
<h3>7.2. Subject's Rights</h3>
<p>The PD Subject has the right to receive information about:</p>
<ul class="compact-list">
<li>confirmation of the fact of PD Processing;</li>
<li>legal grounds and purposes of Processing;</li>
<li>methods of Processing used;</li>
<li>terms of Processing and data storage;</li>
<li>clarification, blocking, or destruction of data;</li>
</ul>
<p><strong>The PD Subject has the right to withdraw their Consent</strong> and request the deletion of their PD by sending a message to: <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></p>
<p>The Subject also has the right to protect their rights, recover damages, and receive compensation for moral harm.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>8. OPERATOR'S OBLIGATIONS</h2>
<p>8.1. The Operator is obliged to provide the Subject with information about the processing of their data upon request.</p>
<p>8.2. The Operator ensures the storage of data of citizens of the Russian Federation on the territory of the Russian Federation.</p>
<p>8.3. The Operator bears other obligations established by FZ-152.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>9. SECURITY ASSURANCE</h2>
<p>9.1-9.3. Security is ensured through a set of organizational and technical measures:</p>
<ul class="compact-list">
<li>appointment of responsible persons;</li>
<li>restriction of access to PD;</li>
<li>employee training;</li>
<li>accounting and storage of PD media;</li>
<li>use of antivirus tools;</li>
<li>encryption and firewall tools;</li>
<li>physical protection of premises;</li>
<li>security measures control.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">⚠️</div>
<h2>10. LIABILITY</h2>
<p>10.1. Persons guilty of violating the norms of processing and protection of Personal Data bear liability in accordance with the legislation of the Russian Federation.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🎯</div>
<h2>11. PURPOSES OF PROCESSING</h2>
<p>11.1. The Operator processes PD for the following purposes:</p>
<ul class="compact-list">
<li>Providing access to the Website and personal account;</li>
<li>Fulfillment of purchase and sale agreements and provision of services;</li>
<li>Delivery of goods;</li>
<li>Resolution of complaints;</li>
<li>Payment processing;</li>
<li>Improvement of service quality;</li>
<li>Obtaining feedback;</li>
<li>Conducting marketing research;</li>
<li>Sending promotional messages;</li>
<li>In other cases provided for by the legislation of the Russian Federation.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">🍪</div>
<h2>12. AUTOMATICALLY COLLECTED INFORMATION</h2>
<p>12.1. The Operator collects and processes:</p>
<ul class="compact-list">
<li>information about interests based on search queries;</li>
<li>information for rating formation (reviews, data on Order fulfillment);</li>
<li>statistics on Website usage.</li>
</ul>
<p>12.2. The Operator uses cookies, web beacons, and other monitoring technologies. These technologies do not allow automatic collection of PD.</p>
<p>12.3. If the collected information can be associated with the User's personal account, it may be processed together with PD.</p>
</section>
<div class="info-card wide contact-card">
<div class="card-icon">📧</div>
<h3>Contact Information</h3>
<p>For all questions regarding personal data processing, please contact:</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="note">We will respond within 30 days in accordance with the legislation of the Russian Federation</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-privacy-policy-lavero-en',
templateUrl: './privacy-policy-en.component.html',
styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PrivacyPolicyLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,8 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Գաղdelays delays delays delays</h1>
<p class="subtitle"> Delays delays delays delays delays delays</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-privacy-policy-lavero-hy',
templateUrl: './privacy-policy-hy.component.html',
styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PrivacyPolicyLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-privacy-policy-lavero-ru /> }
@case ('en') { <app-privacy-policy-lavero-en /> }
@case ('hy') { <app-privacy-policy-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { PrivacyPolicyLaveroRuComponent } from './ru/privacy-policy-ru.component';
import { PrivacyPolicyLaveroEnComponent } from './en/privacy-policy-en.component';
import { PrivacyPolicyLaveroHyComponent } from './hy/privacy-policy-hy.component';
@Component({
selector: 'app-privacy-policy-lavero',
imports: [PrivacyPolicyLaveroRuComponent, PrivacyPolicyLaveroEnComponent, PrivacyPolicyLaveroHyComponent],
templateUrl: './privacy-policy.component.html',
styleUrls: ['../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PrivacyPolicyLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,277 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Политика конфиденциальности</h1>
<p class="subtitle">Защита ваших персональных данных</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. ОБЩИЕ ПОЛОЖЕНИЯ</h2>
<p>1.1. Настоящая Политика конфиденциальности (далее — Политика) определяет обязательства Общества с ограниченной ответственностью «ЛАВЕРО» (далее - Оператор) по обработке, использованию, хранению и защите персональных данных (далее ПДн, Персональные данные) пользователей (далее - Пользователь).</p>
<p>1.2. Оператор берет на себя обязательство строго соблюдать права и свободы человека и гражданина при обработке его персональных данных, включая защиту прав на неприкосновенность частной жизни, личную и семейную тайну.</p>
<p>1.3. Политика обработки персональных данных (далее — Политика) разработана в соответствии с Федеральным законом от 27.07.2006. №152-ФЗ «О персональных данных» (далее — ФЗ-152).</p>
<p>1.4. Ознакомиться с Политикой возможно на сайте Оператора в информационно-телекоммуникационной сети «Интернет» по адресу: <a href="https://lavero.store">https://lavero.store</a>.</p>
<p>1.5. Действует в отношении всех действий, связанных с обработкой персональных данных на сайте <a href="https://lavero.store">https://lavero.store</a> и в информационных системах Оператора.</p>
<p>1.6. Пользователь, оформляющий заказ, открывающий личный кабинет или иным образом взаимодействующий с Оператором, выражает согласие на обработку своих персональных данных в соответствии с Политикой и законодательством РФ. Продолжительное использование сайта свидетельствует о согласии с Положениями Политики. Пользователь, не готовый согласиться с условиями, должен воздержаться от использования ресурса.</p>
<p><strong>Дополнительно:</strong> Настоящая Политика распространяется на персональные данные, собранные как до вступления документа в силу, так и после.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📖</div>
<h2>2. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ</h2>
<p>В данной Политике используются следующие основные термины и определения:</p>
<div class="compact-list">
<p><strong>Персональные данные (ПДн)</strong> — любая информация, прямо или косвенно относящаяся к определённому физическому лицу (субъекту персональных данных).</p>
<p><strong>Информационная система персональных данных (ИСПДн)</strong> — совокупность персональных данных, хранимых в базах данных, а также технологий и средств для их обработки.</p>
<p><strong>Автоматизированная обработка ПДн</strong> — обработка данных с использованием компьютерных средств.</p>
<p><strong>Блокировка ПДн</strong> — временная приостановка обработки данных (за исключением случаев уточнения данных).</p>
<p><strong>Обезличивание ПДн</strong> — действия, ведущие к невозможности установления принадлежности данных конкретному лицу без дополнительной информации.</p>
<p><strong>Интернет-сайт (Сайт)</strong> — автоматизированная информационная система, доступная в сети Интернет по адресу: <a href="https://lavero.store">https://lavero.store</a>.</p>
<p><strong>Обработка ПДн</strong> — любые действия с персональными данными, включая сбор, запись, хранение, обновление, использование, передачу, уничтожение и другие операции.</p>
<p><strong>Оператор</strong> — государственный или частный орган, самостоятельно или совместно организующий обработку персональных данных.</p>
<p><strong>Предоставление ПДн</strong> — передача данных определённому лицу или группе лиц.</p>
<p><strong>Распространение ПДн</strong> — открытие данных неопределённому кругу лиц, включая публикацию в СМИ или сети Интернет.</p>
<p><strong>Трансграничная передача ПДн</strong> — передача данных зарубежным властям, компаниям или физическим лицам.</p>
<p><strong>Уничтожение ПДн</strong> — действия, приводящие к утрате возможности восстановления данных или уничтожения материальных носителей.</p>
<p><strong>Субъект ПДн</strong> — физическое лицо, чья информация обрабатывается.</p>
<p><strong>Конфиденциальность ПДн</strong> — обязанность Оператора защищать данные от распространения без согласия субъекта или законного основания.</p>
<p><strong>Продавец (Исполнитель)</strong> — лицо, предлагающее товары или услуги на сайте <a href="https://lavero.store">https://lavero.store</a>.</p>
<p><strong>Пользователь</strong> — лицо, посещающее или использующее ресурсы, управляемые Оператором, включая сайт <a href="https://lavero.store">https://lavero.store</a>.</p>
<p><strong>Заказ</strong> — оформленный Пользователем заказ товаров или услуг на сайте.</p>
<p><strong>Файлы cookie</strong> — небольшие файлы, сохраняемые на устройстве пользователя для запоминания предпочтений и действий при последующих посещениях сайта.</p>
</div>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>3. ПРАВОВЫЕ ОСНОВАНИЯ ОБРАБОТКИ ПЕРСОНАЛЬНЫХ ДАННЫХ</h2>
<p>3.1. Правовым основанием Обработки ПДн в зависимости от целей процесса, предусматривающего Обработку ПДн может являться:</p>
<h3>3.1.1. Конституция Российской Федерации, а также совокупность правовых актов:</h3>
<ul class="compact-list">
<li>Налоговый кодекс Российской Федерации;</li>
<li>Гражданский Кодекс Российской Федерации;</li>
<li>ст. 86 - 90 Трудового кодекса Российской Федерации;</li>
<li>Федеральный закон от 07.08.2001 № 115-ФЗ «О противодействии легализации (отмыванию) доходов, полученных преступным путем, и финансированию терроризма»;</li>
<li>Федеральный закон от 27.07.2006 г. № 152-ФЗ «О персональных данных»;</li>
<li>Федеральный закон от 22.04.1996 № 39-ФЗ «О рынке ценных бумаг»;</li>
<li>Федеральный закон от 26.12.1995 №208-ФЗ «Об акционерных обществах»;</li>
<li>Федеральный закон от 27.07.2006 № 149-ФЗ «Об информации, информационных технологиях и о защите информации»;</li>
<li>Федеральный закон от 01.04.1996 № 27-ФЗ «Об индивидуальном (персонифицированном) учете в системе обязательного пенсионного страхования»;</li>
<li>Федеральный закон от 06.04.2011 № 63-ФЗ «Об электронной подписи»;</li>
<li>Федеральный закон от 06.12.2011 № 402-ФЗ «О бухгалтерском учете»;</li>
<li>Федеральный закон от 27.06.2011 № 161-ФЗ «О национальной платежной системе»;</li>
<li>Постановление Правительства Российской Федерации от 15.09.2008 № 687 «Об утверждении положения об особенностях обработки персональных данных, осуществляемой без использования средств автоматизации»;</li>
<li>Постановлением Правительства РФ от 01.11.2012 № 1119 "Об утверждении требований к защите персональных данных при их обработке в информационных системах персональных данных"</li>
<li>иные нормативные правовые акты Российской Федерации и нормативные документы исполнительных органов государственной власти.</li>
</ul>
<p>3.1.2. Устав Оператора.</p>
<p>3.1.3. Договоры, заключаемые между Оператором и Субъектом Персональных данных, в том числе в случае реализации Оператором своего права на уступку прав (требований) по таким договорам, между Оператором и иным лицом, поручившим Оператору Обработку ПДн, а также для заключения договоров, стороной которых являются Субъекты Персональных данных.</p>
<p>3.1.4. Согласие на Обработку ПДн (в случаях, прямо не предусмотренных законодательством Российской Федерации, но соответствующих полномочиям Оператора), в т.ч. согласие соискателей на замещение вакантных должностей на Обработку ПДн, согласие практиканта на Обработку ПДн, согласие работников на Обработку ПДн; согласие клиентов на Обработку ПДн, согласие Пользователей соответствующего Сайта, согласие иных Субъектов Персональных данных.</p>
<p>3.1.5. Договор между оператором и третьим лицом, где последнее поручает Оператору обработку персональных данных Субъекта Персональных данных или передает на основании заключенного договора персональные данные Субъекта Персональных данных.</p>
</section>
<section class="info-card wide">
<div class="card-icon">👥</div>
<h2>4. КАТЕГОРИИ СУБЪЕКТОВ ПЕРСОНАЛЬНЫХ ДАННЫХ</h2>
<p>4.1. Оператором осуществляется Обработка полученных в установленном законом порядке ПДн, принадлежащих:</p>
<ul class="compact-list">
<li>Кандидатам на работу и работникам Оператора;</li>
<li>Уволенным работникам Оператора;</li>
<li>Близким родственникам/членам семьи работников Оператора, практикантам;</li>
<li>Потенциальным клиентам, клиентам - физическим лицам, клиентам - индивидуальным предпринимателям;</li>
<li>Физическим лицам, заключившим с Оператором гражданско-правовые договоры;</li>
<li>Пользователям Сайтов Оператора, получателям Заказов;</li>
<li>Клиентам других юридических лиц;</li>
<li>Собственникам Оператора;</li>
<li>Иным субъектам, вступившим или намеревающимися вступить в договорные отношения с Оператором.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📝</div>
<h2>5. КАТЕГОРИИ ОБРАБАТЫВАЕМЫХ ПЕРСОНАЛЬНЫХ ДАННЫХ</h2>
<p>5.1. Оператор обрабатывает следующие категории ПДн Пользователей:</p>
<ul class="compact-list">
<li>Сведения, полученные при регистрации и/или оформлении Заказа (фамилию, имя, фактический адрес, номер телефона, адрес электронной почты, cookie);</li>
<li>Сведения, полученные при взаимодействии с Пользователями (фамилия, имя, отчество, пол, место рождения, дата рождения, паспортные данные, адрес, контакты);</li>
<li>Сведения о способе доставки и оплаты Заказа;</li>
<li>Сведения о претензиях Пользователя;</li>
<li>Сведения о геолокации (местонахождении).</li>
</ul>
<p>5.2. Персональные данные могут быть получены Оператором путем:</p>
<ul class="compact-list">
<li>Предоставления Субъектами через формы на Сайте или по email;</li>
<li>Получения от третьих лиц (Продавцов, контрагентов) в рамках законодательства РФ.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>6. ПРИНЦИПЫ, ПОРЯДОК И УСЛОВИЯ ОБРАБОТКИ</h2>
<h3>6.1. Принципы обработки Персональных данных</h3>
<p>Обработка ПДн у Оператора осуществляется на основе следующих принципов:</p>
<ul class="compact-list">
<li>законности и справедливой основы;</li>
<li>ограничения Обработки ПДн достижением конкретных, заранее определенных и законных целей;</li>
<li>недопущения Обработки ПДн, несовместимой с целями сбора ПДн;</li>
<li>обеспечения точности, достаточности и актуальности ПДн;</li>
<li>хранение ПДн не дольше, чем этого требуют цели Обработки;</li>
<li>уничтожения либо обезличивания ПДн по достижении целей их Обработки.</li>
</ul>
<h3>6.2. Обязанности работников Оператора</h3>
<p>Работники Оператора, допущенные к Обработке Персональных данных, обязаны:</p>
<ul class="compact-list">
<li>Знать и выполнять положения законодательства РФ в области ПДн;</li>
<li>Знать и выполнять положения настоящей Политики;</li>
<li>Обрабатывать ПДн только в рамках должностных обязанностей;</li>
<li>Не разглашать ПДн, обрабатываемые Оператором;</li>
<li>Сообщать о действиях, которые могут привести к нарушению Политики.</li>
</ul>
<h3>6.3-6.24. Дополнительные условия</h3>
<p>Включают условия обработки, хранения, трансграничной передачи данных, работы с общедоступными источниками, специальными и биометрическими данными, а также порядок получения разъяснений согласно законодательству РФ.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>7. ПРАВА СУБЪЕКТА ПЕРСОНАЛЬНЫХ ДАННЫХ</h2>
<h3>7.1. Согласие Субъекта</h3>
<p>Субъект ПДн дает согласие на Обработку свободно, своей волей и в своем интересе.</p>
<h3>7.2. Права Субъекта</h3>
<p>Субъект ПДн имеет право на получение информации о:</p>
<ul class="compact-list">
<li>подтверждение факта Обработки ПДн;</li>
<li>правовые основания и цели Обработки;</li>
<li>применяемые способы Обработки;</li>
<li>сроки Обработки и хранения данных;</li>
<li>уточнение, блокирование или уничтожение данных;</li>
</ul>
<p><strong>Субъект ПДн имеет право отозвать свое Согласие</strong> и потребовать удалить свои ПДн, направив сообщение на: <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></p>
<p>Субъект также имеет право на защиту своих прав, возмещение убытков и компенсацию морального вреда.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>8. ОБЯЗАННОСТИ ОПЕРАТОРА</h2>
<p>8.1. Оператор обязан предоставить Субъекту информацию о обработке его данных при обращении.</p>
<p>8.2. Оператор обеспечивает хранение данных граждан РФ на территории Российской Федерации.</p>
<p>8.3. Оператор несет иные обязанности, установленные ФЗ-152.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>9. ОБЕСПЕЧЕНИЕ БЕЗОПАСНОСТИ</h2>
<p>9.1-9.3. Безопасность обеспечивается комплексом организационных и технических мер:</p>
<ul class="compact-list">
<li>назначение ответственных лиц;</li>
<li>ограничение доступа к ПДн;</li>
<li>обучение сотрудников;</li>
<li>учет и хранение носителей с ПДн;</li>
<li>использование антивирусных средств;</li>
<li>средства шифрования и межсетевого экранирования;</li>
<li>физическая защита помещений;</li>
<li>контроль мер безопасности.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">⚠️</div>
<h2>10. ОТВЕТСТВЕННОСТЬ</h2>
<p>10.1. Лица, виновные в нарушении норм обработки и защиты Персональных данных, несут ответственность согласно законодательству РФ.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🎯</div>
<h2>11. ЦЕЛИ ОБРАБОТКИ</h2>
<p>11.1. Оператор обрабатывает ПДн для следующих целей:</p>
<ul class="compact-list">
<li>Предоставления доступа к Сайту и личному кабинету;</li>
<li>Исполнения договоров купли-продажи и оказания услуг;</li>
<li>Доставки товаров;</li>
<li>Урегулирования претензий;</li>
<li>Обработки платежей;</li>
<li>Улучшения качества обслуживания;</li>
<li>Получения обратной связи;</li>
<li>Проведения маркетинговых исследований;</li>
<li>Направления рекламных сообщений;</li>
<li>В иных случаях, предусмотренных законодательством РФ.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">🍪</div>
<h2>12. АВТОМАТИЧЕСКИ СОБИРАЕМАЯ ИНФОРМАЦИЯ</h2>
<p>12.1. Оператор собирает и обрабатывает:</p>
<ul class="compact-list">
<li>информацию об интересах на основе поисковых запросов;</li>
<li>информацию для формирования рейтинга (отзывы, данные об исполнении Заказов);</li>
<li>статистику об использовании Сайта.</li>
</ul>
<p>12.2. Оператор использует cookies, веб-отметки и другие технологии мониторинга. Эти технологии не дают возможность автоматически получать ПДн.</p>
<p>12.3. Если собранные сведения можно соотнести с личным кабинетом Пользователя, они могут обрабатываться совместно с ПДн.</p>
</section>
<div class="info-card wide contact-card">
<div class="card-icon">📧</div>
<h3>Контакты для связи</h3>
<p>По всем вопросам обработки персональных данных обращайтесь:</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="note">Мы ответим в течение 30 дней согласно законодательству РФ</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-privacy-policy-lavero-ru',
templateUrl: './privacy-policy-ru.component.html',
styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PrivacyPolicyLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,269 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>User Agreement</h1>
<p class="subtitle">Platform usage rules</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📚</div>
<h2>Key Terms</h2>
<ul class="compact-list">
<li><strong>Platform</strong> — the software and technical complex lavero.store. We provide the infrastructure for trading without being sellers ourselves.</li>
<li><strong>Client</strong> — an individual using the website after registration and acceptance of these terms.</li>
<li><strong>Account</strong> — the client's individual area with authorization via email or phone.</li>
<li><strong>Customer</strong> — a client who has made a purchase through the platform.</li>
<li><strong>Operator</strong> — the company LLC "LAVERO", TIN 03590442.</li>
<li><strong>Supplier</strong> — individuals, legal entities, and sole proprietors selling goods through the platform.</li>
<li><strong>Products</strong> — physical, electronic goods and services in the catalog.</li>
<li><strong>Electronic Products</strong> — software, courses, subscriptions, media content in digital form.</li>
<li><strong>Purchase</strong> — a completed client application for acquisition.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. Basic Rules</h2>
<p>1.1. This text defines the rules of interaction with our resources.</p>
<p>1.2. The agreement is binding for the client and the platform operator.</p>
<p>1.3. The document qualifies as a public offer under Art. 435 and Clause 2 of Art. 437 of the Civil Code of the Russian Federation.</p>
<p>1.4. Acceptance occurs automatically with any action: visiting, registering, or placing an order.</p>
<p>1.5. Signing a paper contract is not required — the electronic form is legally valid.</p>
<p>1.6. Disagreement with the terms means the obligation to leave the website.</p>
<p>1.7. The <a [routerLink]="'/privacy-policy' | langRoute">Privacy Policy</a> also applies.</p>
<p>1.8. We may update the terms unilaterally.</p>
<p>1.9. Promotional campaigns may have special rules.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🎯</div>
<h2>2. Subject of the Agreement</h2>
<p>2.1. The purpose is to provide users with the ability to purchase goods and services presented on the resource.</p>
<p>2.2. The agreement regulates the use of the website and provided features.</p>
<p>2.3. It applies to all types of goods, services, and products on the website.</p>
<p>2.4. The Marketplace is an agent acting under agency agreements with Sellers (Third Parties). The Marketplace does not acquire ownership rights to the Goods/Services sold through the Platform and only provides the technical ability to conclude a transaction between the Seller and the Buyer.</p>
<p>2.5. The Seller is an independent business entity and bears full responsibility for the quality, safety, conformity of the Goods/Services to the stated characteristics, and fulfillment of obligations to the Buyer (warranties, returns, claims).</p>
<p>2.6. The Marketplace is not a party to the sale and purchase agreement between the Seller and the Buyer. All claims regarding the Goods/Services are submitted by the Buyer directly to the Seller.</p>
<p>2.7. The Marketplace's agency remuneration is withheld from the amount paid by the Buyer and does not increase the price for the Buyer beyond the price set by the Seller.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛒</div>
<h2>3. Terms of Sale of Goods and Services</h2>
<p><strong>3.1. Acceptance of terms:</strong> By placing an order, the user agrees to the terms.</p>
<p><strong>3.2. Conclusion of contracts:</strong> The contract is concluded between the seller and the buyer. The marketplace is an information intermediary, not a party to the transaction.</p>
<p><strong>3.3. Processing of contacts:</strong> The user consents to the use of contact information for fulfilling obligations.</p>
<p><strong>3.4. Third parties:</strong> The seller may engage third parties to fulfill the contract.</p>
<p><strong>3.5. Rights and obligations:</strong> Rights and obligations arise with the seller. The website owner is the marketplace operator and is not responsible for the actions of sellers.</p>
<p><strong>3.6. Owner's functions:</strong> Information and technical support, coordination of interactions, assistance in dispute resolution.</p>
<p><strong>3.7. Assignment of rights:</strong> The seller may assign rights to third parties.</p>
<p><strong>3.8. Applicable laws:</strong> Governed by Federal Law "On Consumer Rights Protection" No. 2300-1 and the Civil Code of the Russian Federation.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📱</div>
<h2>4. Registration and Personal Account</h2>
<p><strong>4.1. Procedure:</strong> Registration is not required for ordering but provides access to the personal account.</p>
<p><strong>4.2. Obligations:</strong> Provide accurate information and keep it up to date.</p>
<p><strong>4.3. Identification:</strong> Actions performed using login and password are considered user actions.</p>
<p><strong>4.4. Confidentiality:</strong> Keep login and password confidential. If a breach is suspected, notify <a href="mailto:info@lavero.store">info@lavero.store</a>.</p>
<p><strong>4.5. Data verification:</strong> The owner may request verification of information.</p>
<p><strong>4.6. Session termination:</strong> Log out of the personal account independently ("Log Out").</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>5. Rights and Obligations of the Website Owner</h2>
<p><strong>Owner's rights:</strong></p>
<ul class="compact-list">
<li>Set restrictions on the use of the resource</li>
<li>Send information about updates</li>
<li>Change the supplier of goods and/or delivery company without prior consent of the Buyer</li>
<li>Change promotion terms unilaterally</li>
<li>Restrict actions of users who create risks</li>
<li>Perform technical maintenance without prior notice</li>
<li>Use statistics for its own purposes</li>
<li>Change the product list, prices, and terms</li>
<li>Refuse service if violations are suspected</li>
</ul>
<p><strong>Obligations:</strong> Provision of services as specified in clause 2.1 of the agreement.</p>
</section>
<section class="info-card wide">
<div class="card-icon">👤</div>
<h2>6. Rights and Obligations of the User</h2>
<p><strong>User obligations:</strong></p>
<ul class="compact-list">
<li>Read the agreement before concluding the contract</li>
<li>Behave ethically when writing reviews</li>
<li>Communicate politely and respectfully</li>
<li>Do not use profanity</li>
<li>Do not interfere with the website's operation</li>
<li>Do not upload viruses or malware</li>
<li>Do not use automated programs without permission</li>
<li>Do not attempt to access others' data</li>
<li>Use website content lawfully</li>
<li>Register only on your own behalf</li>
<li>Pay for orders on time</li>
<li>Use goods for personal needs</li>
<li>Protect the information security of the resource</li>
</ul>
<p><strong>Prohibited:</strong></p>
<ul class="compact-list">
<li>Uploading content that violates the law, contains viruses, or false information</li>
<li>Violating the rights of other users</li>
<li>Behavior that violates Russian legislation</li>
</ul>
<p><strong>Rights:</strong> Opt out of advertising messages through the website or by writing to <a href="mailto:info@lavero.store">info@lavero.store</a>.</p>
</section>
<section class="info-card wide">
<div class="card-icon">©</div>
<h2>7. Exclusive Rights to Content</h2>
<p><strong>7.1. Intellectual property:</strong> All content (design, texts, graphics, video, software, databases) is subject to the copyright of the owner and rights holders.</p>
<p><strong>7.2. Usage:</strong> Permitted only within the functionality of the website. Any other use without permission is prohibited.</p>
<p><strong>7.3. Personal use:</strong> For personal non-commercial use while preserving copyright notices.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🔗</div>
<h2>8. Third-Party Websites and Content</h2>
<p><strong>8.1. External links:</strong> The website may contain links to third-party resources. The website owner is not responsible for their content.</p>
<p><strong>8.2. Nature of links:</strong> Links do not imply endorsement or recommendation.</p>
<p><strong>8.3. Citation:</strong> When reproducing materials, an active link to the source is required.</p>
<p><strong>8.4. Branding:</strong> The logo, name, and design belong to the owner. Use without permission is prohibited.</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>9. Liability of the Parties</h2>
<p><strong>9.1. General:</strong> The website is an information technology resource that ensures the placement of information about goods and services, as well as the security of transactions. The website owner assumes responsibility for preventing the placement of prohibited goods on the resource, as well as for the quality and accuracy of information about goods and services presented on the platform.</p>
<p><strong>9.2. Limitations:</strong> The owner does not guarantee constant availability or absence of errors.</p>
<p><strong>9.3. Information:</strong> The user is responsible for the consequences of using the information.</p>
<p><strong>9.4. Identification and control:</strong> The buyer is identified by phone number and data provided through Telegram. Each Seller undergoes a full identification procedure (onboarding), and their data is available in case of disputes. The website owner verifies and monitors the activities of Sellers on the platform.</p>
<p><strong>9.5. Account security:</strong> The user is responsible for keeping login and password secure.</p>
<p><strong>9.6. Seller's liability:</strong> The seller is responsible for the quality, safety, and compliance of goods.</p>
<p><strong>9.7. Owner's liability:</strong> The owner is responsible for the quality, safety, and accuracy of information about goods and services on the platform. However, the Owner is not liable for:</p>
<ul class="compact-list">
<li>Fulfillment of sellers' obligations</li>
<li>Violation of third-party rights</li>
<li>Delivery, completeness, and condition of goods</li>
</ul>
<p><strong>9.8. Delivery:</strong> Delivery responsibility lies with transport companies.</p>
<p><strong>9.9. Third parties:</strong> The user is liable to third parties for their actions.</p>
<p><strong>9.10. Force majeure:</strong> Operations may be suspended due to unforeseen circumstances.</p>
<p><strong>9.11. Advertising:</strong> Sellers are responsible for advertising.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛍️</div>
<h2>10. Goods and Purchase Procedure</h2>
<p><strong>10.1. Placing an order:</strong> Orders are placed according to the procedure on the website.</p>
<p><strong>10.2. Incorrect data:</strong> The buyer assumes the risk of non-delivery if incorrect information is provided.</p>
<p><strong>10.3. Delivery notification:</strong> After the order is placed, the buyer receives delivery information.</p>
<p><strong>10.4. Time confirmation:</strong> Before delivery, a representative will contact to confirm the time.</p>
<p><strong>10.5. Product availability:</strong> The seller does not guarantee constant availability of goods in stock.</p>
<p><strong>10.6. Legislation:</strong> Delivery is carried out in accordance with the laws of the Russian Federation.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🚚</div>
<h2>11. Order Delivery</h2>
<p><strong>11.1. Methods and terms:</strong> Listed on the website. Actual delivery times are confirmed upon order confirmation.</p>
<p><strong>11.2. Digital goods:</strong> Confirmed by sending an email with a file or code. Physical goods — by actual delivery.</p>
<p><strong>11.3. Territory:</strong> Delivery boundaries are published on the website.</p>
<p><strong>11.4. Receiving goods:</strong> Goods are delivered to the buyer or the designated person.</p>
<p><strong>11.5. Identity verification:</strong> Prepaid orders may require identity verification.</p>
<p><strong>11.6. Risk transfer:</strong> Risk transfers to the buyer upon delivery of goods.</p>
<p><strong>11.7. Delivery cost:</strong> Calculated individually.</p>
<p><strong>11.8. Fulfillment of obligations:</strong> The seller has fulfilled obligations upon delivery of goods.</p>
<p><strong>11.9. Inspection of goods:</strong> The buyer may inspect goods upon receipt.</p>
<p><strong>11.10. Verification:</strong> Quantity, assortment, and completeness can be verified.</p>
<p><strong>11.11. Courier time:</strong> Maximum 20 minutes at the address.</p>
<p><strong>11.12. Certification:</strong> Goods comply with GOST and TU standards.</p>
</section>
<section class="info-card wide">
<div class="card-icon">💳</div>
<h2>12. Payment for Goods</h2>
<p><strong>12.1. Currency and price:</strong> In Russian rubles, including taxes and fees.</p>
<p><strong>12.2. Price errors:</strong> If discovered, the seller notifies the buyer. The buyer may confirm or cancel the order.</p>
<p><strong>12.3. Price changes:</strong> The seller may change prices, but not for paid goods.</p>
<p><strong>12.4. Payment methods:</strong> Listed on the website during checkout.</p>
<p><strong>12.5. Bank cards:</strong></p>
<ul class="compact-list">
<li>Payments by the cardholder or authorized person</li>
<li>Authorization through the bank</li>
<li>Identity document may be required</li>
<li>Electronic receipt sent to email</li>
<li>Order verification to prevent fraud</li>
<li>Card data is not stored</li>
</ul>
<p><strong>12.6. Discounts and bonuses:</strong> Set by the seller and published on the website.</p>
<p><strong>12.7. Cash:</strong> Cash payment is not available.</p>
<p><strong>12.8. Refunds:</strong> Within 10 days from the date of the claim.</p>
</section>
<section class="info-card wide">
<div class="card-icon">↩️</div>
<h2>13. Returns and Exchanges</h2>
<p><strong>13.1. General rules:</strong> Digital goods are non-refundable. Physical goods — according to the <a [routerLink]="'/return-policy' | langRoute">Return Policy</a> and consumer protection laws.</p>
<p><strong>13.2. Return procedure:</strong> In accordance with the agreement and the legislation of the Russian Federation.</p>
<p><strong>13.3. Promotional sets:</strong> Returns only as a complete set; individual items cannot be returned.</p>
<p><strong>13.4. Delivery costs:</strong> When returning a quality product, the seller may charge delivery costs.</p>
<p><strong>13.5. Timeframes:</strong> Claims are processed within 10 days.</p>
<p><strong>13.6. Documents for return:</strong></p>
<ul class="compact-list">
<li>Return application</li>
<li>Copy of receipt or check</li>
<li>Copy of acceptance certificate</li>
</ul>
<p><strong>13.7. Return method:</strong> The return method is specified in the application.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>14. Term of the Agreement</h2>
<p><strong>14.1. Commencement and termination:</strong> The agreement is active from the moment of acceptance by the user until revocation of acceptance.</p>
<p><strong>14.2. Right of revocation:</strong> The owner may revoke the offer pursuant to Art. 436 of the Civil Code of the Russian Federation.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>15. Dispute Resolution Procedure</h2>
<p><strong>15.1. Voluntary settlement:</strong> Mandatory pre-trial dispute resolution procedure.</p>
<p><strong>15.2. Claims procedure:</strong></p>
<ul class="compact-list">
<li>The user submits a claim</li>
<li>25 business days for the owner's response</li>
<li>If no compromise is reached — judicial proceedings</li>
</ul>
<p><strong>15.3. Anonymous claims:</strong> Are not accepted for consideration.</p>
<p><strong>15.4. Judicial proceedings:</strong> At the location of the website owner.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📝</div>
<h2>16. Other Terms</h2>
<p><strong>16.1. Effect:</strong> This document supersedes all previous agreements.</p>
<p><strong>16.2. Consent:</strong> By continuing to use the website, the user agrees to the terms.</p>
<p><strong>16.3. Legislation:</strong> Issues are resolved under the legislation of Armenia.</p>
<p><strong>16.4. The term "Legislation":</strong> Refers to the laws of Armenia.</p>
<p><strong>16.5. Free services:</strong> Do not imply the application of consumer protection regulations.</p>
<p><strong>16.6. Absence of relationships:</strong> Except for the agency model under clause 2.4, the terms do not establish partnership, joint venture, or employment relationships.</p>
<p><strong>16.7. Invalidity of clauses:</strong> Does not affect the legal force of the remaining provisions.</p>
<p><strong>16.8. Response to violations:</strong> Non-intervention does not prevent subsequent protective measures.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📞</div>
<h2>Contact Us</h2>
<p>Questions about the agreement:</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="support-note">We are always happy to help</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
import { RouterLink } from '@angular/router';
import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe';
@Component({
selector: 'app-public-offer-lavero-en',
imports: [RouterLink, LangRoutePipe],
templateUrl: './public-offer-en.component.html',
styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PublicOfferLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,269 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Օգտագործողի համաձայնագիր</h1>
<p class="subtitle">Հարթակի օգտագործման կանոններ</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📚</div>
<h2>Հիմնական հասկացություններ</h2>
<ul class="compact-list">
<li><strong>Հարթակ</strong> — lavero.store ծրագրային-տեխնիկական համակարգ։ Մենք տրամադրում ենք ենթակառուցվածք առևտրի համար՝ առանց վաճառող հանդիսանալու։</li>
<li><strong>Հաճախորդ</strong> — ֆիզիկական անձ՝ գրանցվելուց և սույն պայմաններն ընդունելուց հետո օգտվող կայքը։</li>
<li><strong>Հաշիվ</strong> — հաճախորդի անհատական գոտի՝ էլ. ֆոստի կամ հեռախոսի միճոցով մուտք գործելով։</li>
<li><strong>Պատվիրատու</strong> — հաճախորդ՝ հարթակի միճոցով գնում կատարած։</li>
<li><strong>Օպերատոր</strong> — «ԷԼԵԿՏՐՎՍՏՎՐՍ» ՍՊԸ՝ ՀՀՀ 03590442։</li>
<li><strong>Մատակարար</strong> — ֆիզ./իրավաբանական անձինք և անհատ ձեռներեցներ՝ հարթակի միճոցով ապրանքներ վաճառող։</li>
<li><strong>Ապրանքներ</strong> — ֆիզիկական՝ էլեկտրոնային ապրանքներ և ծառայություններ կատալոգում։</li>
<li><strong>Էլեկտրոնային ապրանքներ</strong> — ծրագրեր՝ դասընթացներ՝ բաժանորդագրություններ՝ մեդիաբովանդակություն թվային տեսքով։</li>
<li><strong>Գնում</strong> — հաճախորդի ձևակերպված հայտ ձեռքբերման համար։</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. Հիմնական կանոններ</h2>
<p>1.1. Սույն տեքստը սահմանում է մեր ռեսուրսների հետ փոխազդեցության կանոնները։</p>
<p>1.2. Համաձայնագիրը պարտադիր է հաճախորդի և հարթակի օպերատորի համար։</p>
<p>1.3. Փաստաթուղթը համարվում է որպես հանրային օֆերտա Ռդ 435 հոդվածի և Ռդ 437-ի 2-րդ կետի համաձայն։</p>
<p>1.4. Ընդունումը տեղի է ունենում ինքնաբերաբար ցանկացած գործողության դեպքում՝ այցելություն՝ գրանցում՝ պատվերի ձևակերպում։</p>
<p>1.5. Թղթե պայմանագրի ստորագրումը պարտադիր չէ — էլեկտրոնային ձևը իրավաբանորեն վավեր է։</p>
<p>1.6. Պայմանների հետ անհամաձայնությունը նշանակում է կայքից դուրս գալու պարտավորություն։</p>
<p>1.7. Նաև կիրառվում է <a [routerLink]="'/privacy-policy' | langRoute">Գաղտնիության քաղաքականությունը</a>։</p>
<p>1.8. Մենք կարող ենք միակողմանի կարգով թարմացնել պայմանները։</p>
<p>1.9. Գովազդային ակցիաները կարող են ունենալ հատուկ կանոններ։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🎯</div>
<h2>2. Համաձայնագրի առարկան</h2>
<p>2.1. Նպատակն է օգտագործողներին հնարավորություն տալ ռեսուրսում ներկայացված ապրանքներ և ծառայություններ ձեռք բերելու։</p>
<p>2.2. Համաձայնագիրը կարգավորում է կայքի օգտագործման և տրամադրվող գործառույթների կարգը։</p>
<p>2.3. Գործում է կայքում ներկայացված ապրանքների՝ ծառայությունների և պրոդուկտների բոլոր տեսակների նկատմամբ։</p>
<p>2.4. Մարկետփլեյսը հանդիսանում է գործակալ, որը գործում է Վաճառողների (Երրորդ անձանց) հետ կնքված գործակալության պայմանագրի հիման վրա։ Մարկետփլեյսը չի ձեռք բերում Հարթակի միջոցով իրացվող Ապրանքների/Ծառայությունների նկատմամբ սեփականության իրավունք, այլ միայն ապահովում է Վաճառողի և Գնորդի միջև գործարք կնքելու տեխնիկական հնարավորությունը։</p>
<p>2.5. Վաճառողը հանդիսանում է ինքնուրույն տնտեսվարող սուբյեկտ և կրում է ամբողջական պատասխանատվություն Ապրանքի/Ծառայության որակի, անվտանգության, հայտարարված բնութագրերին համապատասխանության, ինչպես նաև Գնորդի նկատմամբ պարտավորությունների կատարման համար (երաշխիքներ, վերադարձ, պահանջներ)։</p>
<p>2.6. Մարկետփլեյսը չի հանդիսանում Վաճառողի և Գնորդի միջև առուվաճառքի պայմանագրի կողմ։ Ապրանքի/Ծառայության վերաբերյալ բոլոր պահանջները Գնորդը ներկայացնում է անմիջապես Վաճառողին։</p>
<p>2.7. Մարկետփլեյսի գործակալական վարձատրությունը պահվում է Գնորդի վճարած գումարից և չի ավելացնում Գնորդի համար գինը Վաճառողի սահմանած գնից ավել։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛒</div>
<h2>3. Ապրանքների և ծառայությունների վաճառքի պայմաններ</h2>
<p><strong>3.1. Պայմանների ընդունում՝</strong> Պատվեր կատարելով օգտագործողը համաձայնվում է պայմաններին։</p>
<p><strong>3.2. Պայմանագրերի կնքում՝</strong> Պայմանագիրը կնքվում է վաճառողի և գնորդի միճև։ Մարկետպլեյսը տեղեկատվական միճնորդ է՝ ոչ թէ գործարքի կողմ։</p>
<p><strong>3.3. Կոնտակտների մշակում՝</strong> Օգտագործողը համաձայնում է կոնտակտային տվյալների օգտագործմանը պարտավորությունների կատարման համար։</p>
<p><strong>3.4. Երրորդ կողմեր՝</strong> Վաճառողը կարող է ներգրավել երրորդ կողմերի պայմանագրի կատարման համար։</p>
<p><strong>3.5. Իրավունքներ և պարտավորություններ՝</strong> Իրավունքներն ու պարտավորությունները ծագում են վաճառողի մոտ։ Կայքի սեփականատերը մարկետպլեյսի օպերատորն է՝ պատասխանատու չէ վաճառողների գործողությունների համար։</p>
<p><strong>3.6. Սեփականատիրոջ գործառույթներ՝</strong> Տեղեկատվական և տեխնիկական աջակցություն՝ փոխազդեցության համակարգում՝ վեճերի լուծման հարցերում օգնություն։</p>
<p><strong>3.7. Իրավունքների զիճում՝</strong> Վաճառողը կարող է իրավունքները զիճել երրորդ կողմերին։</p>
<p><strong>3.8. Կիրառվող օրենքներ՝</strong> Կարգավորվում են ՌԴ «Սպառողների իրավունքների պաշտպանության մասին» թիվ 2300-1 և ՌԴ քաղաքացիական օրենսգիրքով։</p>
</section>
<section class="info-card wide">
<div class="card-icon">📱</div>
<h2>4. Գրանցում և անձնական հաշիվ</h2>
<p><strong>4.1. Ըթացակարգ՝</strong> Գրանցումը պարտադիր չէ պատվերի համար՝ սակայն հնարավորություն է տալիս անձնական հաշիվ մուտք գործելու։</p>
<p><strong>4.2. Պարտավորություններ՝</strong> Տրամադրել ճիշտ տեղեկատվություն և թարմացնել այն։</p>
<p><strong>4.3. Նույնականացում՝</strong> Մուտքանունի և գաղտնաբառի օգտագործմամբ կատարված գործողությունները համարվում են օգտագործողի գործողություններ։</p>
<p><strong>4.4. Գաղտնիություն՝</strong> Պահել մուտքանունը և գաղտնաբառը գաղտնի։ Կասկածի խախտման դեպքում — հաղորդել <a href="mailto:info@lavero.store">info@lavero.store</a>։</p>
<p><strong>4.5. Տվյալների հաստատում՝</strong> Սեփականատերը կարող է պահանջել տեղեկատվության հաստատում։</p>
<p><strong>4.6. Նիստի ավարտ՝</strong> Ինքնուրույն ավարտել աշխատանքը անձնական հաշվում («Ելք»)։</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>5. Կայքի սեփականատիրոջ իրավունքները և պարտավորությունները</h2>
<p><strong>Սեփականատիրոջ իրավունքներ՝</strong></p>
<ul class="compact-list">
<li>Սահմանափակումներ սահմանել ռեսուրսի օգտագործման մեջ</li>
<li>Տեղեկատվություն ուղարկել նորույթների մասին</li>
<li>Փոխել ապրանքների մատակարարին և/կամ առաքման ընկերությանը առանց Գնորդի նախնական համաձայնության</li>
<li>Փոխել ակցիաների պայմանները միակողմանի կարգով</li>
<li>Սահմանափակել ռիսկեր ստեղծող օգտագործողների գործողությունները</li>
<li>Տեխնիկական աշխատանքներ իրականացնել առանց նախազգուշացման</li>
<li>Ստատիստիկան տվյալները օգտագործել սեփական նպատակների համար</li>
<li>Փոխել ապրանքների ցանկը՝ գներն ու պայմանները</li>
<li>Հրաժարվել սպասարկումը խախտումների կասկածի դեպքում</li>
</ul>
<p><strong>Պարտավորություններ՝</strong> Համաձայնագրի 2.1 կետով նախատեսված ծառայությունների մատուցում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">👤</div>
<h2>6. Օգտագործողի իրավունքները և պարտավորությունները</h2>
<p><strong>Օգտագործողի պարտավորություններ՝</strong></p>
<ul class="compact-list">
<li>Ծանոթանալ համաձայնագիրը պայմանագիր կնքելուց առաջ</li>
<li>Բարոյական վարվել կարծիքներ գրելիս</li>
<li>Հաղորդակցվել քաղաքավարի և հարգանքով</li>
<li>Չտարածել անպատշած բառապաշտություն</li>
<li>Չխանգարել կայքի աշխատանքին</li>
<li>Չբեռնել վիրուսներ և վնասակար ծրագրեր</li>
<li>Չօգտագործել ավտոմատացված ծրագրեր առանց թույլտվության</li>
<li>Չփորձել ուրիշների տվյալներին մուտք գործել</li>
<li>Կայքի բովանդակությունը օրինականորեն օգտագործել</li>
<li>Գրանցվել միայն սեփական անունով</li>
<li>Նամանակավ վճարել պատվերների համար</li>
<li>Ապրանքները օգտագործել անձնական կարիքների համար</li>
<li>Պահպանել ռեսուրսի տեղեկատվական անվտանգությունը</li>
</ul>
<p><strong>Արգելված է՝</strong></p>
<ul class="compact-list">
<li>Օրենքին հակասող բովանդակության բեռնում՝ վիրուսներով կամ կեղծ տեղեկատվությամբ</li>
<li>Այլ օգտագործողների իրավունքների խախտում</li>
<li>Ռդ օրենսդրությունը խախտող վարքագիծ</li>
</ul>
<p><strong>Իրավունքներ՝</strong> Հրաժարվել գովազդային հաղորդագրություններից կայքի միճոցով կամ նամակով <a href="mailto:info@lavero.store">info@lavero.store</a>։</p>
</section>
<section class="info-card wide">
<div class="card-icon">©</div>
<h2>7. Բովանդակության բացառիկ իրավունքներ</h2>
<p><strong>7.1. Մտավոր սեփականություն՝</strong> Բոլոր բովանդակությունը (դիզայն՝ տեքստեր՝ գրաֆիկա՝ տեսանյութ՝ ծրագրեր՝ տվյալների բազաներ) սեփականատիրոջ և իրավատերերի հեղինակային իրավունքների առարկան է։</p>
<p><strong>7.2. Օգտագործում՝</strong> Թույլատրվում է միայն կայքի ֆունկցիոնալության շրջանակներում։ Այլ օգտագործում առանց թույլտվության անթույլատրելի է։</p>
<p><strong>7.3. Անձնական օգտագործում՝</strong> Անձնական ոչ առևտրային օգտագործման համար՝ հեղինակային իրավունքների նիշերի պահպանմամբ։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🔗</div>
<h2>8. Երրորդ կողմերի կայքեր և բովանդակություն</h2>
<p><strong>8.1. Արտաքին հղումներ՝</strong> Կայքը կարող է պարունակել երրորդ կողմի ռեսուրսների հղումներ։ Կայքի սեփականատերը պատասխանատու չէ դրանց բովանդակության համար։</p>
<p><strong>8.2. Հղումների բնույթը՝</strong> Հղումները չեն նշանակում հավանություն կամ հանձնարարություն։</p>
<p><strong>8.3. Մեջբերում՝</strong> Նյութերը վերարտադրելիս պահանջվում է ակտիվ հղում աղբյուրին։</p>
<p><strong>8.4. Բրենդինգ՝</strong> Լոգոն՝ անվանումը և ձևավորումը պատկանում են սեփականատիրոջին։ Թույլտվության առանց օգտագործումը արգելված է։</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>9. Կողմերի պատասխանատվությունը</h2>
<p><strong>9.1. Ընդհանուր՝</strong> Կայքը տեղեկատվական-տեխնոլոգիական ռեսուրս է՝ որը ապահովում է ապրանքների և ծառայությունների մասին տեղեկատվության տեղադրումը՝ ինչպես նաև գործարքների անվտանգությունը։ Կայքի սեփականատերը պատասխանատվություն է կրում արգելված ապրանքների տեղադրման կանխարգելու և տեղեկատվության որակի և հավաստիության համար։</p>
<p><strong>9.2. Սահմանափակումներ՝</strong> Սեփականատերը չի երաշխավորում մշտական հասանելիություն և սխալների բացակայություն։</p>
<p><strong>9.3. Տեղեկատվություն՝</strong> Օգտագործողը պատասխանատու է տեղեկատվության օգտագործման հետևանքների համար։</p>
<p><strong>9.4. Նույնականացում և վերահսկողություն՝</strong> Գնորդը նույնականացվում է հեռախոսի համարի և Telegram-ի միճոցով տրամադրված տվյալներով։ Յուրաքանչյուր վաճառող անցնում է նույնականացման լիարժեք ընթացակարգ։ Կայքի սեփականատերը ստուգում և վերահսկում է վաճառողների գործունեությունը հարթակում։</p>
<p><strong>9.5. Հաշվի անվտանգություն՝</strong> Օգտագործողը պատասխանատու է մուտքանունի և գաղտնաբառի պահպանման համար։</p>
<p><strong>9.6. Վաճառողի պատասխանատվություն՝</strong> Վաճառողը պատասխանատու է ապրանքների որակի՝ անվտանգության և համապատասխանության համար։</p>
<p><strong>9.7. Սեփականատիրոջ պատասխանատվություն՝</strong> Սեփականատերը պատասխանատու է հարթակում ապրանքների և ծառայությունների տեղեկատվության որակի՝ անվտանգության և հավաստիության համար։ Ընդ որում՝ Սեփականատերը պատասխանատու չէ՝</p>
<ul class="compact-list">
<li>Վաճառողների պարտավորությունների կատարման համար</li>
<li>Երրորդ կողմերի իրավունքների խախտման համար</li>
<li>Առաքման՝ լրացումների և ապրանքների վիճակի համար</li>
</ul>
<p><strong>9.8. Առաքում՝</strong> Առաքման պատասխանատվությունը կրում են տրանսպորտային ընկերությունները։</p>
<p><strong>9.9. Երրորդ կողմեր՝</strong> Օգտագործողը պատասխանատու է երրորդ կողմերի առաջ իր գործողությունների համար։</p>
<p><strong>9.10. Ֆորս-մաժոր՝</strong> Աշխատանքը կարող է կասեցվել անկանխատեսելի հանգամանքներում։</p>
<p><strong>9.11. Գովազդ՝</strong> Գովազդի պատասխանատվությունը կրում են վաճառողները։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛍️</div>
<h2>10. Ապրանք և գնման կարգը</h2>
<p><strong>10.1. Ձևակերպում՝</strong> Պատվերը ձևակերպվում է կայքում նշված ընթացակարգով։</p>
<p><strong>10.2. Սխալ տվյալներ՝</strong> Գնորդը ընդունում է պատվերը չստանալու ռիսկը սխալ տեղեկատվության դեպքում։</p>
<p><strong>10.3. Առաքման ծանուցում՝</strong> Պատվերը ձևակերպելուց հետո գնորդը ստանում է առաքման տեղեկատվություն։</p>
<p><strong>10.4. Ժամանակի ճշտեցում՝</strong> Առաքմանից առաջ աշխատակիցը կկապվի ժամանակի ճշտեցման համար։</p>
<p><strong>10.5. Ապրանքի առկայություն՝</strong> Վաճառողը չի երաշխավորում ապրանքի մշտական առկայությունը պահեստում։</p>
<p><strong>10.6. Օրենսդրություն՝</strong> Մատակարարումը իրականացվում է ՌԴ օրենքներին համապատասխան։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🚚</div>
<h2>11. Պատվերի առաքում</h2>
<p><strong>11.1. Եղանակներ և ժամկետներ՝</strong> Նշված են կայքում։ Փաստացի ժամկետները ճշտեցվում են պատվերի հաստատման ձամանակ։</p>
<p><strong>11.2. Թվային ապրանքներ՝</strong> Հաստատվում են ֆայլով կամ կոդով նամակի ուղարկմամբ։ Ֆիզիկական ապրանքը — փաստացի հանձնմամբ։</p>
<p><strong>11.3. Տարածք՝</strong> Առաքման սահմանները հրապարակված են կայքում։</p>
<p><strong>11.4. Ապրանքի ընդունում՝</strong> Ապրանքը հանձնվում է գնորդին կամ նշված անձին։</p>
<p><strong>11.5. Ինքնության ստուգում՝</strong> Կանխավճարման դեպքում կարող է պահանջվել ինքնության հաստատում։</p>
<p><strong>11.6. Ռիսկի անցում՝</strong> Ռիսկը անցնում է գնորդին ապրանքի հանձնման պահին։</p>
<p><strong>11.7. Առաքման արժեք՝</strong> Հաշվարկվում է անհատական։</p>
<p><strong>11.8. Պարտավորությունների կատարում՝</strong> Վաճառողը կատարել է պարտավորությունները ապրանքի հանձնման պահին։</p>
<p><strong>11.9. Ապրանքի զննում՝</strong> Գնորդը կարող է զննել ապրանքը ստանալիս։</p>
<p><strong>11.10. Ստուգում՝</strong> Կարելի է ստուգել քանակը՝ տեսականին և լրացումները։</p>
<p><strong>11.11. Սուրհանդեսի ժամանակ՝</strong> Առավելագույնը 20 րոպե հասցեում։</p>
<p><strong>11.12. Սերտիֆիկացում՝</strong> Ապրանքները համապատասխանում են ԳՕՍՏ և ՏՊ ստանդարտներին։</p>
</section>
<section class="info-card wide">
<div class="card-icon">💳</div>
<h2>12. Ապրանքի վճարում</h2>
<p><strong>12.1. Արժույթ և գին՝</strong> Ռդ ռուբլով՝ ներառյալ հարկերն ու տուրքերը։</p>
<p><strong>12.2. Գների սխալներ՝</strong> Հայտնաբերման դեպքում վաճառողը տեղեկացնում է գնորդին։ Գնորդը կարող է հաստատել կամ չեղարկել պատվերը։</p>
<p><strong>12.3. Գների փոփոխություն՝</strong> Վաճառողը կարող է փոխել գները՝ բայց ոչ վճարված ապրանքների համար։</p>
<p><strong>12.4. Վճարման եղանակներ՝</strong> Նշված են կայքում պատվերի ձևակերպման ժամանակ։</p>
<p><strong>12.5. Բանկային քարտեր՝</strong></p>
<ul class="compact-list">
<li>Վճարումները քարտի տիրոջի կամ լիազորված անձի կողմից</li>
<li>Բանկի միճոցով ավտորիզացիա</li>
<li>Կարող է պահանջվել ինքնության փաստաթուղթ</li>
<li>Էլեկտրոնային կտրոն էլ. ֆոստին</li>
<li>Պատվերների ստուգում խաբեությունից կանխարգելու համար</li>
<li>Քարտի տվյալները չեն պահպանվում</li>
</ul>
<p><strong>12.6. Զեղչեր և բոնուսներ՝</strong> Սահմանվում են վաճառողի կողմից և հրապարակվում են կայքում։</p>
<p><strong>12.7. Կանխիկ՝</strong> Կանխիկ վճարում չի իրականացվում։</p>
<p><strong>12.8. Միջոցների վերադարձ՝</strong> Դիմումից 10 օրվա ընթացքում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">↩️</div>
<h2>13. Ապրանքի վերադարձ և փոխանակում</h2>
<p><strong>13.1. Ընդհանուր կանոններ՝</strong> Թվային ապրանքները վերադարձի ենթակա չեն։ Ֆիզիկական ապրանքները — <a [routerLink]="'/return-policy' | langRoute">Վերադարձի քաղաքականության</a> և սպառողների իրավունքների պաշտպանության օրենքներին համապատասխան։</p>
<p><strong>13.2. Վերադարձի ընթացակարգ՝</strong> Համաձայնագրին և ՌԴ օրենսդրությանը համապատասխան։</p>
<p><strong>13.3. Ակցիային հավաքածուներ՝</strong> Վերադարձը միայն ամբողջական՝ առանձին ապրանքներ վերադարձել հնարավոր չէ։</p>
<p><strong>13.4. Առաքման ծախսեր՝</strong> Որակյալ ապրանքի վերադարձի դեպքում վաճառողը կարող է գանձել առաքման ծախսերը։</p>
<p><strong>13.5. Ժամկետներ՝</strong> Դիմումները բավարարվում են 10 օրվա ընթացքում։</p>
<p><strong>13.6. Վերադարձի փաստաթղթեր՝</strong></p>
<ul class="compact-list">
<li>Վերադարձի դիմում</li>
<li>Անդագրի կամ կտրոնի պատճեն</li>
<li>Ընդունման-հանձնման ակտի պատճեն</li>
</ul>
<p><strong>13.7. Վերադարձի մեխանիզմ՝</strong> Վերադարձի եղանակը նշվում է դիմումում։</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>14. Համաձայնագրի գործողության ժամկետը</h2>
<p><strong>14.1. Սկիզբ և դադարեցում՝</strong> Համաձայնագիրը գործում է օգտագործողի ընդունման պահից մինչև ընդունման հետկանչում։</p>
<p><strong>14.2. Հետկանչման իրավունք՝</strong> Սեփականատերը կարող է օֆերտան հետ կանչել ՌԴ 436 հոդվածի համաձայն։</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>15. Վեճերի լուծման կարգը</h2>
<p><strong>15.1. Կամավոր կարգավորում՝</strong> Պարտադիր նախադատական վեճերի լուծման ընթացակարգ։</p>
<p><strong>15.2. Պրետենզիոն կարգ՝</strong></p>
<ul class="compact-list">
<li>Օգտագործողը ներկայացնում է պրետենզիա</li>
<li>25 աշխատանքային օր սեփականատիրոջ պատասխանի համար</li>
<li>Եթե համաձայնություն չի ձեռք բերվում — դատական քննություն</li>
</ul>
<p><strong>15.3. Անանուն պրետենզիաներ՝</strong> Չեն ընդունվում քննարկման։</p>
<p><strong>15.4. Դատական քննություն՝</strong> Կայքի սեփականատիրոջ գտնվելու վայրում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">📝</div>
<h2>16. Այլ պայմաններ</h2>
<p><strong>16.1. Գործողություն՝</strong> Փաստաթուղթը փոխարինում է բոլոր նախորդ պայմանավորվածությունները։</p>
<p><strong>16.2. Համաձայնություն՝</strong> Կայքի օգտագործումը շարունակելով օգտագործողը համաձայնվում է պայմաններին։</p>
<p><strong>16.3. Օրենսդրություն՝</strong> Հարցերը լուծվում են Հայաստանի օրենսդրությամբ։</p>
<p><strong>16.4. «Օրենսդրություն» տերմին՝</strong> Նշանակում է Հայաստանի օրենքները։</p>
<p><strong>16.5. Անվճար ծառայություններ՝</strong> Չեն ենթադրում սպառողների իրավունքների պաշտպանության նորմերի կիրառում։</p>
<p><strong>16.6. Հարաբերությունների բացակայություն՝</strong> Բացի 2.4 կետով նախատեսված գործակալական մոդելից՝ պայմանները չեն հաստատում գործընկերային, համատեղ ձեռնարկության կամ աշխատանքային հարաբերություններ։</p>
<p><strong>16.7. Կետերի անվավերություն՝</strong> Չի ազդում մնացած դրույթների իրավական ուժի վրա։</p>
<p><strong>16.8. Խախտումների նկատմամբ արձագանք՝</strong> Անգործունեությունը չի խանգարում հետագա պաշտպանության միջոցներին։</p>
</section>
<section class="info-card wide">
<div class="card-icon">📞</div>
<h2>Կապ</h2>
<p>Համաձայնագրի վերաբերյալ հարցեր՝</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="support-note">Մենք միշտ պատրաստ ենք օգնելու</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
import { RouterLink } from '@angular/router';
import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe';
@Component({
selector: 'app-public-offer-lavero-hy',
imports: [RouterLink, LangRoutePipe],
templateUrl: './public-offer-hy.component.html',
styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PublicOfferLaveroHyComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,5 @@
@switch (lang()) {
@case ('ru') { <app-public-offer-lavero-ru /> }
@case ('en') { <app-public-offer-lavero-en /> }
@case ('hy') { <app-public-offer-lavero-hy /> }
}

View File

@@ -0,0 +1,16 @@
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LanguageService } from '../../../../../services/language.service';
import { PublicOfferLaveroRuComponent } from './ru/public-offer-ru.component';
import { PublicOfferLaveroEnComponent } from './en/public-offer-en.component';
import { PublicOfferLaveroHyComponent } from './hy/public-offer-hy.component';
@Component({
selector: 'app-public-offer-lavero',
imports: [PublicOfferLaveroRuComponent, PublicOfferLaveroEnComponent, PublicOfferLaveroHyComponent],
templateUrl: './public-offer.component.html',
styleUrls: ['../../../../../pages/legal/public-offer/public-offer.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PublicOfferLaveroComponent {
lang = inject(LanguageService).currentLanguage;
}

View File

@@ -0,0 +1,269 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Пользовательское соглашение</h1>
<p class="subtitle">Правила работы на платформе</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📚</div>
<h2>Ключевые термины</h2>
<ul class="compact-list">
<li><strong>Платформа</strong> — программно-технический комплекс lavero.store. Мы предоставляем инфраструктуру для торговли, не являясь продавцами.</li>
<li><strong>Клиент</strong> — физическое лицо, использующее сайт после регистрации и принятия данных условий.</li>
<li><strong>Аккаунт</strong> — индивидуальная зона клиента с авторизацией через email или телефон.</li>
<li><strong>Заказчик</strong> — клиент, совершивший покупку через платформу.</li>
<li><strong>Оператор</strong> — компания ООО «ЛАВЕРО», ИНН 03590442.</li>
<li><strong>Поставщик</strong> — физ./юрлица и ИП, реализующие товары через платформу.</li>
<li><strong>Продукция</strong> — физические, электронные товары и сервисы в каталоге.</li>
<li><strong>Электронная продукция</strong> — софт, курсы, подписки, медиаконтент в цифровом виде.</li>
<li><strong>Покупка</strong> — оформленная заявка клиента на приобретение.</li>
</ul>
</section>
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. Базовые правила</h2>
<p>1.1. Этот текст определяет правила взаимодействия с нашими ресурсами.</p>
<p>1.2. Соглашение обязательно для клиента и оператора платформы.</p>
<p>1.3. Документ квалифицируется как публичная оферта по ст. 435 и п. 2 ст. 437 ГК РФ.</p>
<p>1.4. Акцепт происходит автоматически при любом действии: визите, регистрации, оформлении покупки.</p>
<p>1.5. Подписание бумажного договора не требуется — электронная форма юридически действительна.</p>
<p>1.6. Несогласие с условиями означает обязанность покинуть сайт.</p>
<p>1.7. Также применяется <a [routerLink]="'/privacy-policy' | langRoute">Политика конфиденциальности</a>.</p>
<p>1.8. Мы можем обновлять условия в одностороннем порядке.</p>
<p>1.9. Промо-кампании могут иметь специальные правила.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🎯</div>
<h2>2. Предмет соглашения</h2>
<p>2.1. Целью является предоставление пользователям возможности покупать товары и услуги, представленные на ресурсе.</p>
<p>2.2. Соглашение регулирует порядок использования сайта и предоставляемых функций.</p>
<p>2.3. Действие распространяется на все типы товаров, услуг и продуктов на сайте.</p>
<p>2.4. Маркетплейс является агентом, действующим на основании договора агентирования с Продавцами (Третьими лицами). Маркетплейс не приобретает право собственности на Товары/Услуги, реализуемые через Платформу, а лишь обеспечивает техническую возможность заключения сделки между Продавцом и Покупателем.</p>
<p>2.5. Продавец является самостоятельным хозяйствующим субъектом и несёт полную ответственность за качество, безопасность, соответствие Товара/Услуги заявленным характеристикам, а также за исполнение обязательств перед Покупателем (гарантии, возврат, претензии).</p>
<p>2.6. Маркетплейс не выступает стороной договора купли-продажи между Продавцом и Покупателем. Все претензии по Товару/Услуге Покупатель предъявляет непосредственно Продавцу.</p>
<p>2.7. Агентское вознаграждение Маркетплейса удерживается из суммы, уплаченной Покупателем, и не увеличивает цену для Покупателя сверх установленной Продавцом.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛒</div>
<h2>3. Условия продажи товаров и услуг</h2>
<p><strong>3.1. Принятие условий:</strong> Оформляя заказ, пользователь соглашается с условиями.</p>
<p><strong>3.2. Заключение договоров:</strong> Договор заключается между продавцом и покупателем. Маркетплейс — информационный посредник, не участник сделки.</p>
<p><strong>3.3. Обработка контактов:</strong> Пользователь даёт согласие на использование контактных данных для выполнения обязательств.</p>
<p><strong>3.4. Третьи лица:</strong> Продавец может привлекать третьих лиц для исполнения договора.</p>
<p><strong>3.5. Права и обязанности:</strong> Права и обязанности возникают у продавца. Владелец сайта — оператор маркетплейса, не отвечает за действия продавцов.</p>
<p><strong>3.6. Функции владельца:</strong> Информационное и техническое сопровождение, координация взаимодействия, помощь в урегулировании споров.</p>
<p><strong>3.7. Переуступка прав:</strong> Продавец может уступать права третьим сторонам.</p>
<p><strong>3.8. Применение законов:</strong> Регулируются ФЗ "О защите прав потребителей" №2300-1 и ГК РФ.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📱</div>
<h2>4. Регистрация и личный кабинет</h2>
<p><strong>4.1. Процедура:</strong> Регистрация необязательна для заказа, но открывает доступ к личному кабинету.</p>
<p><strong>4.2. Обязанности:</strong> Предоставлять точную информацию и поддерживать её актуальность.</p>
<p><strong>4.3. Идентификация:</strong> Действия с использованием логина и пароля считаются действиями пользователя.</p>
<p><strong>4.4. Конфиденциальность:</strong> Хранить логин и пароль в тайне. При подозрении на нарушение — сообщить на <a href="mailto:info@lavero.store">info@lavero.store</a>.</p>
<p><strong>4.5. Подтверждение данных:</strong> Владелец может запросить подтверждение информации.</p>
<p><strong>4.6. Завершение сеанса:</strong> Самостоятельно завершать работу в личном кабинете («Выход»).</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚙️</div>
<h2>5. Права и обязанности владельца сайта</h2>
<p><strong>Права владельца:</strong></p>
<ul class="compact-list">
<li>Устанавливать ограничения в использовании ресурса</li>
<li>Направлять информацию о нововведениях</li>
<li>Изменять поставщика товаров и/или компанию-доставщика без предварительного согласия Покупателя</li>
<li>Изменять условия акций в одностороннем порядке</li>
<li>Ограничивать действия пользователей, создающих риски</li>
<li>Проводить технические работы без предупреждения</li>
<li>Использовать статистику в собственных интересах</li>
<li>Менять список товаров, цены и условия</li>
<li>Отказывать в обслуживании при подозрении в нарушениях</li>
</ul>
<p><strong>Обязанности:</strong> Оказание услуг, предусмотренных п. 2.1 соглашения.</p>
</section>
<section class="info-card wide">
<div class="card-icon">👤</div>
<h2>6. Права и обязанности пользователя</h2>
<p><strong>Обязанности пользователя:</strong></p>
<ul class="compact-list">
<li>Ознакомиться с соглашением до заключения договора</li>
<li>Этично вести себя при написании отзывов</li>
<li>Общаться вежливо и уважительно</li>
<li>Не распространять ненормативную лексику</li>
<li>Не создавать помех работе сайта</li>
<li>Не загружать вирусы и вредоносные программы</li>
<li>Не использовать автоматизированные программы без разрешения</li>
<li>Не пытаться получить доступ к чужим данным</li>
<li>Законно использовать контент сайта</li>
<li>Регистрироваться только от собственного имени</li>
<li>Своевременно оплачивать заказы</li>
<li>Использовать товары для личных нужд</li>
<li>Беречь информационную безопасность ресурса</li>
</ul>
<p><strong>Запрещено:</strong></p>
<ul class="compact-list">
<li>Загрузка контента, противоречащего закону, с вирусами или ложной информацией</li>
<li>Нарушение прав других пользователей</li>
<li>Поведение, нарушающее российское законодательство</li>
</ul>
<p><strong>Права:</strong> Отказаться от рекламных сообщений через сайт или письмом на <a href="mailto:info@lavero.store">info@lavero.store</a>.</p>
</section>
<section class="info-card wide">
<div class="card-icon">©</div>
<h2>7. Исключительные права на контент</h2>
<p><strong>7.1. Интеллектуальная собственность:</strong> Весь контент (дизайн, тексты, графика, видео, программы, базы данных) является объектом авторских прав владельца и правообладателей.</p>
<p><strong>7.2. Использование:</strong> Разрешено только в рамках функциональности сайта. Любое другое использование без разрешения недопустимо.</p>
<p><strong>7.3. Личное использование:</strong> Для личного некоммерческого использования при сохранении обозначений авторских прав.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🔗</div>
<h2>8. Сайты и контент третьих лиц</h2>
<p><strong>8.1. Внешние ссылки:</strong> Сайт может содержать ссылки на сторонние ресурсы. Ответственность за их содержание не относится к владельцу сайта.</p>
<p><strong>8.2. Характер ссылок:</strong> Ссылки не означают одобрения или рекомендаций.</p>
<p><strong>8.3. Цитирование:</strong> При воспроизведении материалов необходима активная ссылка на источник.</p>
<p><strong>8.4. Брендинг:</strong> Логотип, название и оформление принадлежат владельцу. Использование без разрешения запрещено.</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>9. Ответственность сторон</h2>
<p><strong>9.1. Общее:</strong> Сайт является информационно-технологическим ресурсом, обеспечивающим размещение информации о товарах и услугах, а также безопасность совершения сделок. Владелец сайта принимает на себя ответственность за недопущение размещения запрещённых товаров на ресурсе, а также за качество и достоверность информации о товарах и услугах, представленных на платформе.</p>
<p><strong>9.2. Ограничения:</strong> Владелец не гарантирует постоянную доступность и отсутствие ошибок.</p>
<p><strong>9.3. Информация:</strong> Пользователь несёт ответственность за последствия использования информации.</p>
<p><strong>9.4. Идентификация и контроль:</strong> Покупатель идентифицируется по номеру телефона и данным, предоставляемым через Telegram. Каждый Продавец проходит полную процедуру идентификации (онбординг), его данные доступны при возникновении спорных ситуаций. Владелец сайта осуществляет проверку и контроль деятельности Продавцов на платформе.</p>
<p><strong>9.5. Безопасность аккаунта:</strong> Пользователь отвечает за сохранность логина и пароля.</p>
<p><strong>9.6. Ответственность продавца:</strong> Продавец отвечает за качество, безопасность и соответствие товаров.</p>
<p><strong>9.7. Ответственность владельца:</strong> Владелец несёт ответственность за качество, безопасность и достоверность информации о товарах и услугах на платформе. При этом Владелец не отвечает за:</p>
<ul class="compact-list">
<li>Выполнение продавцами обязательств</li>
<li>Нарушение прав третьих лиц</li>
<li>Доставку, комплектацию и состояние товаров</li>
</ul>
<p><strong>9.8. Доставка:</strong> Ответственность за доставку несут транспортные компании.</p>
<p><strong>9.9. Третьи лица:</strong> Пользователь отвечает перед третьими лицами за свои действия.</p>
<p><strong>9.10. Форс-мажор:</strong> Работа может быть приостановлена при непредвиденных обстоятельствах.</p>
<p><strong>9.11. Реклама:</strong> Ответственность за рекламу несут продавцы.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛍️</div>
<h2>10. Товар и порядок покупки</h2>
<p><strong>10.1. Оформление:</strong> Заказ оформляется по процедуре на сайте.</p>
<p><strong>10.2. Некорректные данные:</strong> Покупатель принимает риски неполучения заказа при ошибочной информации.</p>
<p><strong>10.3. Уведомление о доставке:</strong> После формирования заказа покупатель получает информацию о доставке.</p>
<p><strong>10.4. Уточнение времени:</strong> Перед доставкой сотрудник свяжется для уточнения времени.</p>
<p><strong>10.5. Наличие товара:</strong> Продавец не гарантирует постоянное наличие товара на складе.</p>
<p><strong>10.6. Законодательство:</strong> Поставка осуществляется в соответствии с законами РФ.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🚚</div>
<h2>11. Доставка заказа</h2>
<p><strong>11.1. Способы и сроки:</strong> Указаны на сайте. Фактические сроки уточняются при подтверждении заказа.</p>
<p><strong>11.2. Цифровые товары:</strong> Подтверждаются отправкой письма с файлом или кодом. Физический товар — реальной передачей.</p>
<p><strong>11.3. Территория:</strong> Границы доставки опубликованы на сайте.</p>
<p><strong>11.4. Приём товара:</strong> Товар передается покупателю или указанному лицу.</p>
<p><strong>11.5. Проверка личности:</strong> При предоплате может потребоваться удостоверение личности.</p>
<p><strong>11.6. Переход риска:</strong> Риск переходит к покупателю при передаче товара.</p>
<p><strong>11.7. Стоимость доставки:</strong> Рассчитывается индивидуально.</p>
<p><strong>11.8. Выполнение обязательств:</strong> Продавец выполнил обязательства при передаче товара.</p>
<p><strong>11.9. Осмотр товара:</strong> Покупатель может осмотреть товар при получении.</p>
<p><strong>11.10. Проверка:</strong> Можно проверить количество, ассортимент и комплектацию.</p>
<p><strong>11.11. Время курьера:</strong> Максимум 20 минут по адресу.</p>
<p><strong>11.12. Сертификация:</strong> Товары соответствуют ГОСТ и ТУ.</p>
</section>
<section class="info-card wide">
<div class="card-icon">💳</div>
<h2>12. Оплата товара</h2>
<p><strong>12.1. Валюта и цена:</strong> В рублях РФ, включая налоги и сборы.</p>
<p><strong>12.2. Ошибки в ценах:</strong> При обнаружении продавец уведомляет покупателя. Покупатель может подтвердить или отменить заказ.</p>
<p><strong>12.3. Изменение цен:</strong> Продавец может менять цены, но не на оплаченные товары.</p>
<p><strong>12.4. Способы оплаты:</strong> Указаны на сайте при оформлении заказа.</p>
<p><strong>12.5. Банковские карты:</strong></p>
<ul class="compact-list">
<li>Платежи держателем карты или лицом по доверенности</li>
<li>Авторизация через банк</li>
<li>Может требоваться документ личности</li>
<li>Электронный чек на email</li>
<li>Проверка заказов для предотвращения мошенничества</li>
<li>Данные карт не хранятся</li>
</ul>
<p><strong>12.6. Скидки и бонусы:</strong> Устанавливаются продавцом и публикуются на сайте.</p>
<p><strong>12.7. Наличные:</strong> Оплата наличными не осуществляется.</p>
<p><strong>12.8. Возврат средств:</strong> В течение 10 дней с момента заявления.</p>
</section>
<section class="info-card wide">
<div class="card-icon">↩️</div>
<h2>13. Возврат и обмен товара</h2>
<p><strong>13.1. Общие правила:</strong> Цифровые товары не подлежат возврату. Физические товары — согласно <a [routerLink]="'/return-policy' | langRoute">Политике возврата</a> и законам о правах потребителей.</p>
<p><strong>13.2. Процедура возврата:</strong> В соответствии с соглашением и законодательством РФ.</p>
<p><strong>13.3. Акционные наборы:</strong> Возврат только в комплексе, отдельные товары вернуть нельзя.</p>
<p><strong>13.4. Затраты на доставку:</strong> При возврате качественного товара продавец может взыскать затраты на доставку.</p>
<p><strong>13.5. Сроки:</strong> Заявления удовлетворяются в течение 10 дней.</p>
<p><strong>13.6. Документы при возврате:</strong></p>
<ul class="compact-list">
<li>Заявление на возврат</li>
<li>Копия квитанции или чека</li>
<li>Копия акта приема-передачи</li>
</ul>
<p><strong>13.7. Механизм возврата:</strong> Способ возврата указывается в заявлении.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>14. Срок действия соглашения</h2>
<p><strong>14.1. Начало и прекращение:</strong> Соглашение активно с момента принятия пользователем до отзыва акцепта.</p>
<p><strong>14.2. Право отзыва:</strong> Владелец может отозвать оферту согласно ст. 436 ГК РФ.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>15. Порядок разрешения споров</h2>
<p><strong>15.1. Добровольное урегулирование:</strong> Обязательный досудебный порядок рассмотрения споров.</p>
<p><strong>15.2. Претензионный порядок:</strong></p>
<ul class="compact-list">
<li>Пользователь направляет претензию</li>
<li>25 рабочих дней на ответ владельца</li>
<li>Если компромисс не достигнут — судебное рассмотрение</li>
</ul>
<p><strong>15.3. Анонимные претензии:</strong> Не принимаются к рассмотрению.</p>
<p><strong>15.4. Судебное рассмотрение:</strong> По месту нахождения владельца сайта.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📝</div>
<h2>16. Прочие условия</h2>
<p><strong>16.1. Действие:</strong> Документ заменяет все предшествующие договоренности.</p>
<p><strong>16.2. Согласие:</strong> Продолжая использовать сайт, пользователь соглашается с условиями.</p>
<p><strong>16.3. Законодательство:</strong> Вопросы разрешаются по законодательству Армении.</p>
<p><strong>16.4. Термин "Законодательство":</strong> Подразумевает законы Армении.</p>
<p><strong>16.5. Бесплатные услуги:</strong> Не предполагают применение норм о защите прав потребителей.</p>
<p><strong>16.6. Отсутствие отношений:</strong> Кроме агентской модели по п. 2.4, условия не устанавливают партнёрства, совместного предприятия или трудовых отношений.</p>
<p><strong>16.7. Недействительность пунктов:</strong> Не влияет на законную силу остальных положений.</p>
<p><strong>16.8. Реакция на нарушения:</strong> Невмешательство не препятствует последующим мерам защиты.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📞</div>
<h2>Контакты</h2>
<p>Вопросы по соглашению:</p>
<a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a>
<p><a [href]="env.phoneTel">{{ env.phones.support }}</a></p>
<p class="support-note">Мы всегда готовы помочь</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
import { RouterLink } from '@angular/router';
import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe';
@Component({
selector: 'app-public-offer-lavero-ru',
imports: [RouterLink, LangRoutePipe],
templateUrl: './public-offer-ru.component.html',
styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PublicOfferLaveroRuComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,175 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Return Policy</h1>
<p class="subtitle">Your rights and return conditions</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. General Provisions</h2>
<p>1.1. This policy describes the procedure for returning products and canceling services purchased on the Lavero Store platform.</p>
<p>1.2. Our platform acts as an information intermediary, therefore all return disputes are resolved directly between the customer and the supplier in accordance with the laws of the Republic of Armenia.</p>
<p>1.3. For quality products, Art. 26.1 of the Consumer Protection Law applies.</p>
<p>1.4. For products with defects, Art. 1824 of the same law apply.</p>
<p>1.5. Digital products are returned under special rules prescribed by legislation.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📅</div>
<h2>2. Time Frames</h2>
<p><strong>2.1. Quality products:</strong></p>
<ul class="compact-list">
<li><strong>Online purchases:</strong> one week after delivery</li>
<li><strong>Before shipment:</strong> no restrictions</li>
<li><strong>If no notification provided:</strong> 90 days from receipt</li>
</ul>
<p><strong>2.2. Defective products:</strong></p>
<ul class="compact-list">
<li>Throughout the entire warranty period</li>
<li>Without a warranty card: 24 months from purchase</li>
<li>Serious defects: throughout the entire service life</li>
</ul>
<p><strong>2.3. Digital products:</strong></p>
<p>Returns are only possible before the file is downloaded or the license key is activated.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>3. Requirements for Returning Non-Defective Products</h2>
<p>To return a purchase without defects, the following conditions must be met:</p>
<div class="features-list">
<div class="feature">✓ Presentable appearance and functionality are not compromised</div>
<div class="feature">✓ Original packaging and all components are intact</div>
<div class="feature">✓ Labels, protective films, and stickers are undamaged</div>
<div class="feature">✓ Product is in original condition, without signs of use</div>
<div class="feature">✓ Proof of payment is available (cash or sales receipt)</div>
</div>
<p>Return shipping of non-defective products is paid by the customer, unless otherwise agreed with the seller.</p>
<p>The supplier refunds the amount for unused products within 10 days of receiving the request.</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>4. Non-Returnable Items</h2>
<p>According to Government Decree No. 2463, the following categories of non-defective products are not subject to return:</p>
<ul class="compact-list">
<li>Medical equipment for personal use</li>
<li>Hygiene products (toothbrushes, combs, etc.)</li>
<li>Cosmetics and fragrances</li>
<li>Fabrics, yarn, and accessories sold by the meter</li>
<li>Underwear and hosiery</li>
<li>Disposable tableware and utensils</li>
<li>Cleaning products, gardening supplies</li>
<li>Furniture sets</li>
<li>Jewelry and costume jewelry</li>
<li>Vehicles and their components</li>
<li>Complex household appliances under warranty service</li>
<li>Weapons and ammunition</li>
<li>Live animals and plants</li>
<li>Printed materials (books, catalogs)</li>
</ul>
<p>These items are accepted for return only in case of manufacturing defects.</p>
</section>
<section class="info-card wide">
<div class="card-icon">⏱️</div>
<h2>5. How to Process a Return</h2>
<p>Step-by-step instructions for returning a purchase:</p>
<div class="process-steps">
<div class="step">
<span class="step-number">1</span>
<p>Contact the supplier through the platform or using the provided contact details</p>
</div>
<div class="step">
<span class="step-number">2</span>
<p>Explain the reason for the return, attach photos or video materials</p>
</div>
<div class="step">
<span class="step-number">3</span>
<p>Wait for instructions on return shipping</p>
</div>
<div class="step">
<span class="step-number">4</span>
<p>Place the item in original packaging with all accessories</p>
</div>
<div class="step">
<span class="step-number">5</span>
<p>Ship the package and provide the tracking number to the seller</p>
</div>
<div class="step">
<span class="step-number">6</span>
<p>Wait for the inspection (takes up to 10 days)</p>
</div>
<div class="step">
<span class="step-number">7</span>
<p>Receive your refund to your account</p>
</div>
</div>
<p>Our platform is always ready to help resolve disputes.</p>
</section>
<section class="info-card wide">
<div class="card-icon">💰</div>
<h2>6. Payment Refund</h2>
<p>Funds are refunded to the same payment method:</p>
<ul class="compact-list">
<li>Visa/MC/Mir card</li>
<li>Digital wallets</li>
<li>Payment link</li>
</ul>
<div class="refund-times">
<div class="refund-item">
<strong>Non-defective product</strong>
<span>Up to 10 days</span>
</div>
<div class="refund-item">
<strong>Defective product</strong>
<span>Up to 10 days</span>
</div>
</div>
<p>The customer has the right to claim compensation for defective products and shipping costs.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🔄</div>
<h2>7. Product Exchange</h2>
<p>If a non-defective product does not match in dimensions, size, or specifications, the customer may exchange it with the supplier for a suitable option.</p>
<p>If the desired model is unavailable, the customer has the right to cancel the order and receive a refund.</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>8. Warranty Service</h2>
<p>Warranty information is displayed on the product page or available from the seller.</p>
<p>Warranty is provided by the supplier or the manufacturer's authorized service center.</p>
<p>Warranty service does not cover physical damage, improper use, or unauthorized modifications.</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>9. Responsibilities of Parties</h2>
<p>The supplier is responsible for product quality and timely refunds.</p>
<p>The customer is required to preserve packaging and completeness until the return shipment.</p>
<p>Our marketplace, acting as an intermediary, is not responsible for sellers' failure to fulfill their obligations, but assists in resolving disputes.</p>
</section>
<section class="info-card wide">
<div class="card-icon">📧</div>
<h2>10. How to Contact Us</h2>
<p>Return questions can be directed to the seller — contact details are provided in your order.</p>
<p>To resolve disputes through the platform administration:</p>
<ul class="compact-list">
<li><strong>E-mail:</strong> <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></li>
<li><strong>Phone:</strong> <a [href]="env.phoneTel">{{ env.phones.support }}</a></li>
<li><strong>Subject:</strong> "Dispute with seller — Order #"</li>
<li><strong>Attach:</strong> correspondence, photos, payment receipt</li>
</ul>
<p>If an agreement cannot be reached, the customer may contact consumer protection authorities or the courts.</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { environment } from '../../../../../../../environments/environment';
@Component({
selector: 'app-return-policy-lavero-en',
templateUrl: './return-policy-en.component.html',
styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ReturnPolicyLaveroEnComponent {
protected readonly env = environment;
}

View File

@@ -0,0 +1,175 @@
<div class="legal-page">
<div class="legal-container">
<div class="lavero-header">
<h1>Ապրանքների վերադարձի քաղաքականություն</h1>
<p class="subtitle">Ձեր իրավունքները և վերադարձի պայմանները</p>
</div>
<div class="lavero-cards">
<section class="info-card wide">
<div class="card-icon">📋</div>
<h2>1. Ընդհանուր դրույթներ</h2>
<p>1.1. Սույն քաղաքականությունը նկարագրում է ապրանքների վերադարձի և Lavero Store հարթակում գնված ծառայություններից հրաժարվելու կարգը։</p>
<p>1.2. Մեր հարթակը գործում է որպես տեղեկատվական միջնորդ, ուստի վերադարձի վերաբերյալ բոլոր վեճերը լուծվում են անմիջականորեն գնորդի և մատակարարի միջև ՀՀ օրենսդրության համաձայն։</p>
<p>1.3. Որակյալ ապրանքների համար կիրառվում է սպառողների պաշտպանության օրենքի հոդված 26.1-ը։</p>
<p>1.4. Թերություններ ունեցող ապրանքների համար գործում են նույն օրենքի 1824 հոդվածները։</p>
<p>1.5. Թվային ապրանքները վերադարձվում են օրենսդրությամբ նախատեսված հատուկ կանոններով։</p>
</section>
<section class="info-card wide">
<div class="card-icon">📅</div>
<h2>2. Ժամանակային սահմաններ</h2>
<p><strong>2.1. Որակյալ ապրանքներ՝</strong></p>
<ul class="compact-list">
<li><strong>Առցանց գնումներ՝</strong> մեկ շաբաթ առաքման հետո</li>
<li><strong>Մինչև առաքմանը՝</strong> առանց սահմանափակման</li>
<li><strong>Ծանուցման բացակայության դեպքում՝</strong> 90 օր ստանալուց</li>
</ul>
<p><strong>2.2. Թերություններ ունեցող ապրանքներ՝</strong></p>
<ul class="compact-list">
<li>Երաշխիքի ողջ գործողության ժամկետում</li>
<li>Երաշխիքային տալոնի բացակայության դեպքում՝ 24 ամիս գնումից</li>
<li>Լուրջ խափանումներ՝ ողջ շահագործման ժամկետի ընթացքում</li>
</ul>
<p><strong>2.3. Թվային ապրանքներ՝</strong></p>
<p>Վերադարձը հնարավոր է միայն մինչև ֆայլի ներբեռնումը կամ լիցենզիայի բանալիի ակտիվացումը։</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>3. Պահանջներ որակյալ ապրանքների վերադարձի համար</h2>
<p>Առանց թերությունների գնումը վերադարձելու համար անհրաժեշտ է պահպանել հետևյալ պայմանները՝</p>
<div class="features-list">
<div class="feature">✓ Ապրանքի արտաքին տեսքը և գործառույթները չեն խախտված</div>
<div class="feature">✓ Գործարանային փաթեթավորումը և բոլոր բաղադրիչները տեղում են</div>
<div class="feature">✓ Պիտակները, պաշտպանիչ թաղանթները և կպչունները չեն վնասված</div>
<div class="feature">✓ Ապրանքը սկզբնական վիճակում է, առանց օգտագործման հետքերի</div>
<div class="feature">✓ Վճարման հաստատում առկա է (դրամարկետի կամ ապրանքային կտրոն)</div>
</div>
<p>Որակյալ ապրանքի հետ առաքման ծախսերը վճարում է գնորդը, եթե վաճառողի հետ այլ պայմանավորվածություն չկա։</p>
<p>Մատակարարը վերադարձնում է գումարը չօգտագործված ապրանքի համար 10 օրվա ընթացքում հայտը ստանալուց։</p>
</section>
<section class="info-card wide">
<div class="card-icon"></div>
<h2>4. Ինչ հնարավոր չէ վերադարձել</h2>
<p>Կառավարության թիվ 2463 որոշման համաձայն, որակյալ ապրանքների հետևյալ կատեգորիաները ենթակա չեն վերադարձման՝</p>
<ul class="compact-list">
<li>Անձնական օգտագործման բժշկական սարքեր</li>
<li>Հիգիենիկ պարագաներ (ատամի խոզանակներ, սանրեր և այլն)</li>
<li>Կոսմետիկ միջոցներ և օճանդակներ</li>
<li>Գործվածքներ, թելեր և ֆուրնիտուրա մետրաժով</li>
<li>Ներքնակի սպիտակեղևս, գուլպաներ</li>
<li>Մեկանգամյա սպասք և պարագաներ</li>
<li>Մաքրող միջոցներ, այգեգործական պարագաներ</li>
<li>Կահույքի հավաքածուներ</li>
<li>Թանկարժեք և զարդեղենք</li>
<li>Տրանսպորտային միջոցներ և դրանց բաղադրիչներ</li>
<li>Երաշխիքային սպասարկման ենթակա բարդ կենցաղային տեխնիկա</li>
<li>Զենք և զինամթերք</li>
<li>Կենդանիներ և բուսական աշխարհ</li>
<li>Տպագիր արտադրանք (գրքեր, կատալոգներ)</li>
</ul>
<p>Այս ապրանքները ընդունվում են հետ միայն գործարանային թերության դեպքում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">⏱️</div>
<h2>5. Ինչպես ձևակերպել վերադարձը</h2>
<p>Քայլ առ քայլ հրահանգներ գնումը վերադարձելու համար՝</p>
<div class="process-steps">
<div class="step">
<span class="step-number">1</span>
<p>Կապվեք մատակարարի հետ հարթակի միջոցով կամ նշված կոնտակտներով</p>
</div>
<div class="step">
<span class="step-number">2</span>
<p>Բացատրեք վերադարձի պատճառը, կցեք լուսանկարներ կամ տեսանյութեր</p>
</div>
<div class="step">
<span class="step-number">3</span>
<p>Սպասեք հետ առաքման հրահանգներին</p>
</div>
<div class="step">
<span class="step-number">4</span>
<p>Տեղադրեք ապրանքը գործարանային փաթեթավորման մեջ բոլոր լրացումներով</p>
</div>
<div class="step">
<span class="step-number">5</span>
<p>Ուղարկեք ծանրոցը և տրամադրեք հետագծման կոդը վաճառողին</p>
</div>
<div class="step">
<span class="step-number">6</span>
<p>Սպասեք փորձագիտությանը (տևողությունը մինչև 10 օր)</p>
</div>
<div class="step">
<span class="step-number">7</span>
<p>Ստացեք փոխհատուցումը ձեր հաշվին</p>
</div>
</div>
<p>Մեր հարթակը միշտ պատրաստ է օգնել վիճելի իրավիճակների կարգավորման հարցում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">💰</div>
<h2>6. Վճարման փոխհատուցում</h2>
<p>Գումարը վերադարձվում է նույն վճարման եղանակով՝</p>
<ul class="compact-list">
<li>Visa/MC/Միր քարտ</li>
<li>Թվային դրամապանակներ</li>
<li>Վճարման հղում</li>
</ul>
<div class="refund-times">
<div class="refund-item">
<strong>Որակյալ ապրանք</strong>
<span>Մինչև 10 օր</span>
</div>
<div class="refund-item">
<strong>Թերություններ ունեցող</strong>
<span>Մինչև 10 օր</span>
</div>
</div>
<p>Գնորդը իրավունք ունի պահանջել փոխհատուցում անորակ ապրանքների և առաքման ծախսերի համար։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🔄</div>
<h2>7. Ապրանքի փոխանակում</h2>
<p>Եթե որակյալ ապրանքը չի համապատասխանում չափսերով, չափորոշներով կամ հատկանիշներով, գնորդը կարող է այն փոխանակել մատակարարի մոտ համապատասխան տարբերակով։</p>
<p>Համապատասխան մոդելի բացակայության դեպքում գնորդը կարող է հրաժարվել պատվերից և ստանալ փոխհատուցում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">🛡️</div>
<h2>8. Երաշխիքային սպասարկում</h2>
<p>Երաշխիքի պայմանները նշված են ապրանքի էջում կամ հասանելի են վաճառողից։</p>
<p>Երաշխիքը տրամադրվում է մատակարարի կամ արտադրողի լիազորված սպասարկման կենտրոնի կողմից։</p>
<p>Երաշխիքային սպասարկումը չի տարածվում ֆիզիկական վնասների, ոչ պատշաճ օգտագործման կամ ինքնուրույն միջամտության դեպքում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">⚖️</div>
<h2>9. Կողմերի պարտականություններ</h2>
<p>Մատակարարը պատասխանատու է ապրանքի որակի և ժամանակային գումարի վերադարձի համար։</p>
<p>Գնորդը պարտավոր է պահպանել փաթեթավորումը և լրիվությունը մինչև հետ առաքման պահը։</p>
<p>Մեր մարկետպլեյսը, հանդիսանալով որպես միջնորդ, պատասխանատու չէ վաճառողների կողմից իրենց պարտավորությունները չկատարելու համար, սակայն աջակցում է վեճերի կարգավորման հարցում։</p>
</section>
<section class="info-card wide">
<div class="card-icon">📧</div>
<h2>10. Ինչպես կապվել մեզ հետ</h2>
<p>Վերադարձի հարցերը կարող եք ուղղել անմիջապես վաճառողին — կոնտակտները նշված են ձեր պատվերում։</p>
<p>Վեճերը հարթակի ադմինիստրացիայի միջոցով լուծելու համար՝</p>
<ul class="compact-list">
<li><strong>E-mail:</strong> <a href="mailto:info@lavero.store" class="contact-email">info@lavero.store</a></li>
<li><strong>Հեռախոս՝</strong> <a [href]="env.phoneTel">{{ env.phones.support }}</a></li>
<li><strong>Թեմա՝</strong> «Վեճ վաճառողի հետ — Պատվերի №»</li>
<li><strong>Կցեք՝</strong> նամակագրություն, լուսանկարներ, վճարման կտրոն</li>
</ul>
<p>Համաձայնության հասնելու անհնարավորության դեպքում գնորդը կարող է դիմել սպառողների պաշտպանության մարմիններին կամ դատարան։</p>
</section>
</div>
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More