# Billing İnteqrasiyası — User Agent (Proxy) Server

Bu sənəd User Agent (proxy) serverinin billing sistemi ilə necə əlaqə qurduğunu, hansı dəyişikliklərin edildiyini və bərpa üçün nə lazım olduğunu təsvir edir.

---

## 1. Serverlər

| Rol | IP / Domen | Qeyd |
|---|---|---|
| **Billing** | `10.10.4.134` | Daxili şəbəkə, internetə açıq deyil |
| **User Agent (Proxy)** | `useragent.starttelecom.az` | Public, app buraya qoşulur |
| **Sayt (şəxsi kabinet)** | `starttelecom.az` | Ayrı sistem, billing-ə öz token-i ilə qoşulur |

### Billing serverinə giriş

```
Host:       10.10.4.134
Port:       22 (SSH)
İstifadəçi: eminov
Parol:      <SSH_PAROL>        ← bu sənəddə saxlanılmır
Veb kök:    /var/www/html
DB:         billing (MySQL)
```

> **Təhlükəsizlik qeydi:** SSH parolu bu fayla yazılmamalıdır. Fayl git-ə, yedəyə və ya paylaşıma düşərsə, parol açıq qalar. Parol ayrıca, şifrələnmiş yerdə (parol meneceri) saxlanılmalıdır.

---

## 2. Arxitektura

```
Tətbiq (Android)
    |  HTTPS + Bearer <access_token> + X-App-Signature
    v
User Agent / Proxy  (useragent.starttelecom.az)
    |  - token yoxlaması (öz AccessToken sistemi)
    |  - cihaz statusu (aktiv / blok / dondurulmuş)
    |  - App Setting flag-ları (maintenance, menu_*, func_*)
    |  - imza yoxlaması (X-App-Signature)
    |
    |  HTTP + Bearer <billing_token>   (daxili şəbəkə)
    v
Billing  (10.10.4.134)
```

**Vacib:** Tətbiq billing-i heç vaxt birbaşa görmür. Bütün sorğular proxy üzərindən keçir.

### Təhlükəsizlik vəziyyəti (cari)

| Qat | Vəziyyət |
|---|---|
| App → Proxy: Bearer access token (10 dəq) + refresh token (30 gün) | Var |
| App → Proxy: `X-App-Signature` (APK imza həşi) | Var |
| Proxy → Billing: Bearer token (ayrıca hesab) | Var |
| Proxy → Billing: **HTTP (şifrələnməmiş)** | Yoxdur — daxili şəbəkədədir |
| Rate limiting (qeydiyyat endpoint-lərinə) | Yoxdur |
| Sertifikat pinning (MITM qorunması) | Yoxdur |

> Proxy ↔ billing əlaqəsi **tam təhlükəsiz formada deyil** (HTTP, daxili şəbəkə). Bu, məlum və qəbul edilmiş risqdir — billing internetə açıq olmadığı üçün hazırda tolerantdır, amma gələcəkdə HTTPS-ə keçirilməsi tövsiyə olunur.

---

## 3. Billing-də yaradılmış API hesabı

Proxy billing-ə **öz ayrıca hesabı** ilə qoşulur (saytın token-ini paylaşmır).

**Cədvəl:** `members` (webvimark user-management modulu)

| Sahə | Dəyər |
|---|---|
| `id` | 66 |
| `username` | `useragent` |
| `fullname` | **User Application** |
| `api_access` | `1` (aktiv) |
| `status` | `1` |
| `auth_key` | Bearer token kimi istifadə olunur |

> Token yoxlaması `webvimark/module-user-management/components/UserIdentity.php` → `findIdentityByAccessToken()` funksiyasında **`auth_key`** sütunu ilə aparılır.

### Hesabın adını yeniləmək (User Application)

```sql
UPDATE members SET fullname = 'User Application' WHERE username = 'useragent';
```

Bu ad billing-də (məsələn, müraciət qeydlərində `member` sahəsində) görünür.

### Hesabı yenidən yaratmaq (reset-dən sonra lazım olarsa)

```bash
AUTH_KEY=$(openssl rand -hex 16)
PASS_HASH=$(php -r "echo password_hash(bin2hex(random_bytes(16)), PASSWORD_BCRYPT);")
NOW=$(date +%s)

mysql -u root -p billing <<EOF
INSERT INTO members (username, fullname, auth_key, password_hash, api_access, status, superadmin, created_at, updated_at)
VALUES ('useragent', 'User Application', '${AUTH_KEY}', '${PASS_HASH}', '1', 1, 0, ${NOW}, ${NOW});
EOF

echo "TOKEN: $AUTH_KEY"
```

Çıxan token proxy serverdə `common/config/params-local.php`-ə yazılır.

---

## 4. Proxy serverin konfiqurasiyası

**Fayl:** `/var/www/html/common/config/params-local.php`

```php
<?php
return [
    'token' => '<BILLING_TOKEN>',      // members.auth_key
    'api_host' => '10.10.4.134',
    'app_signatures' => [
        '<APK_IMZA_HESI_SHA256>',      // iki nöqtəsiz, kiçik hərflə
    ],
];
```

**Asılılıq:** `yiisoft/yii2-httpclient` paketi lazımdır.

```bash
cd /var/www/html
composer require yiisoft/yii2-httpclient
```

---

## 5. Billing-də əlavə edilmiş API endpoint-ləri

**Fayl:** `/var/www/html/controllers/ApiController.php`

Mövcud kod **dəyişdirilməyib** — yalnız yeni funksiyalar əlavə olunub. Sayt (`starttelecom.az`) öz endpoint-lərindən istifadə etməyə davam edir.

### 5.1 `POST /api/app-profile` (yeni)

Tətbiqin Profil ekranı üçün genişləndirilmiş profil məlumatı.

**Sorğu:**

```json
{"contract_number": "SRT004294"}
```

**Cavab:**

```json
{
  "status": "success",
  "data": {
    "fullname": "...",
    "phone": "+994...",
    "address": "Şəhər, Rayon, Location, mənzil X",
    "contract_date": "02-05-2026",
    "balance": 18,
    "bonus": 0,
    "status": 1,
    "expired_at": "01-08-2026 00:05",
    "services": [
      {"service_name": "internet", "packet_name": "Home_80MB", "packet_price": 23, "status": 1},
      {"service_name": "tv", "packet_name": "BaseDigital + iNet", "packet_price": 7, "status": 1}
    ]
  }
}
```

**Fərqi (`user-service`-dən):** `phone`, `address`, `contract_date` sahələri əlavə olunub. Ünvan `address_cities` + `address_district` + `address_locations` cədvəllərindən birləşdirilir.

### 5.2 `POST /api/tariffs` (yeni)

Abonentin **prefiksinə uyğun** internet tarifləri.

**Sorğu:**

```json
{"contract_number": "SRT004294"}
```

**Cavab:**

```json
{
  "status": "success",
  "data": {
    "current": "Home_80MB",
    "prefix": "Home_",
    "tariffs": [
      {"id": 53, "packet_name": "Home_20MB", "download_mb": 20, "upload_mb": 20, "price": 15, "is_current": false},
      {"id": 95, "packet_name": "Home_80MB", "download_mb": 80, "upload_mb": 80, "price": 23, "is_current": true}
    ]
  }
}
```

**Kommersiya məntiqi (vacib):** Abonent yalnız **öz prefiksindəki** tarifləri görür:

- `Home_` → yalnız Home paketləri (ETTH ev abonenti)
- `GPON_` → yalnız GPON paketləri (optik ev abonenti)
- `Corp_` → yalnız Corp paketləri (kommersiya)

Səbəb: `GPON_150MB` = 27 AZN, `Corp_150MB` = 120 AZN. Filtr olmasa, Corp abonenti ucuz ev tarifinə keçə bilər.

---

## 6. Mövcud (dəyişdirilməmiş) billing endpoint-ləri

Bunlar əvvəldən var idi, sayt da istifadə edir:

| Endpoint | Metod | Body | İstifadə |
|---|---|---|---|
| `/api/check-contract` | POST | `contract_number, phone` | Qeydiyyat yoxlaması |
| `/api/user-service` | POST | `contract_number` | Profil (sayt) |
| `/api/payments` | POST | `contract_number, page, per-page` | Ödəniş tarixçəsi |
| `/api/complaints` | POST | `contract_number, page, per-page` | Müraciət siyahısı |
| `/api/add-complaint` | POST | `contract_number, reason, description` | Yeni müraciət |
| `/api/activity` | POST | `contract_number, page, per-page` | Status tarixçəsi |
| `/api/support` | POST | `contract_number, reason, description` | Dəstək |
| `/api/add-balance` | POST | `contract_number, balance_in, transaction, receipt` | Ödəniş qeydə alma |
| `/api/search` | POST | `contract_number` | Ümumi axtarış |

**Hamısı `Authorization: Bearer <token>` tələb edir** (`HttpBearerAuth`, `api_access = 1` şərti ilə).

---

## 7. Proxy serverin API-si (app tərəfi)

**Qovluq:** `/var/www/html/api/controllers/`

| Endpoint | Metod | Qorunur? | Fayl |
|---|---|---|---|
| `/api/profile` | GET | Bəli (token) | `ProfileController.php` |
| `/api/payments?page=N` | GET | Bəli (token) | `PaymentsController.php` |
| `/api/requests?page=N` | GET | Bəli (token) | `RequestsController.php` |
| `/api/requests` | POST | Bəli (token) | `RequestsController.php` |
| `/api/tariffs` | GET | Bəli (token) | `TariffsController.php` |
| `/api/settings` | GET | Xeyr (public) | `SettingsController.php` |
| `/api/device/register` | POST | Xeyr (public) | `DeviceController.php` |
| `/api/device/status` | GET | Xeyr (public) | `DeviceController.php` |
| `/api/registration/*` | POST | Xeyr (public) | `RegistrationController.php` |

**Public olanlar qəsdəndir:**

- `settings` — maintenance/flag məlumatı, sirr deyil, token-siz cihaz da görməlidir
- `device/*` və `registration/*` — token **elə bu axının nəticəsində** yaranır, ondan əvvəl mövcud deyil

**Qorunanlar** `BaseApiController`-dən törəyir → `beforeAction()`-da həm `X-App-Signature`, həm Bearer token yoxlanılır.

---

## 8. Adapter qatı (`BillingService`)

**Fayl:** `/var/www/html/common/services/BillingService.php`

Billing ilə bütün əlaqə burdan keçir. Metodlar:

| Metod | Billing endpoint |
|---|---|
| `findSubscriber($contractNo)` | `/api/app-profile` (qeydiyyat yoxlaması üçün) |
| `phoneMatches($subscriber, $phone)` | — (lokal, son 9 rəqəm tutuşdurulur) |
| `getUserService($contractNo)` | `/api/user-service` |
| `getAppProfile($contractNo)` | `/api/app-profile` |
| `getPayments($contractNo, $page, $perPage)` | `/api/payments` |
| `getComplaints($contractNo, $page, $perPage)` | `/api/complaints` |
| `addComplaint($contractNo, $reason, $description)` | `/api/add-complaint` |
| `getTariffs($contractNo)` | `/api/tariffs` |

> **Qeyd:** Mock məlumatlar tam silinib. Sistem yalnız real billing ilə işləyir.

---

## 9. Billing sabitləri (app-da istifadə olunur)

### Müraciət səbəbləri (`damage_reason`)

Mənbə: `UserDamages::getDamageReason()`

| Kod | Səbəb |
|---|---|
| 0 | İnternet sürəti çox aşağıdır |
| 1 | Router reset edilib |
| 2 | İnternet işləmir |
| 3 | TV siqnal qəbul etmir |
| 4 | Bəzi kanallar işləmir |
| 5 | Digər səbəb |

### Müraciət statusu

| Kod | Məna |
|---|---|
| 0 | Baxılır |
| 1 | Həll olundu |

### Ödəniş növü (`pay_for`)

| Kod | Məna |
|---|---|
| 0 | İnternet |
| 1 | TV |
| 2 | Wi-Fi |
| 4 | VoIP |
| `null` + `balance_in > 0` | Balans artımı |

### Xidmət növü (`service_id` — `service_packets` cədvəli)

| Kod | Xidmət |
|---|---|
| 1 | İnternet |
| 2 | TV |

### Abonent statusu (`users.status`)

| Kod | Məna |
|---|---|
| 1 | Aktiv |
| 2 | Deaktiv |
| 3 | Arxiv |
| 7 | VIP |

---

## 10. Billing DB cədvəlləri (istinad)

| Cədvəl | Məzmun |
|---|---|
| `users` | Abonentlər (contract_number, phone, balance, bonus, status, credit_status, credit_time) |
| `service_packets` | Tarif paketləri (packet_name, download, upload, packet_price, service_id) |
| `users_services_packets` | Abonent ↔ paket əlaqəsi |
| `user_balance` | Ödəniş / tutulma hərəkətləri |
| `user_damages` | Müraciətlər |
| `address_cities` | Şəhərlər (`city_name`) |
| `address_district` | Rayonlar (`district_name`) |
| `address_locations` | Yaşayış məntəqələri (`name`) |
| `members` | Əməkdaşlar + API hesabları (`auth_key`, `api_access`) |

> **Diqqət:** `download` / `upload` **Kbit**-dədir (102400 = 100 Mb). Mb üçün 1024-ə bölünür.

---

## 11. Reset-dən sonra bərpa (checklist)

Billing test rejimindədir və SQL reset + yenidən dump oluna bilər. Reset-dən sonra:

- [ ] `members` cədvəlinə `useragent` hesabını yenidən əlavə et (bölmə 3)
- [ ] Yeni `auth_key`-i proxy-nin `params-local.php`-ə yaz
- [ ] `ApiController.php`-də `actionAppProfile` və `actionTariffs` funksiyalarının qaldığını yoxla
- [ ] Test et:

```bash
curl -s -X POST http://10.10.4.134/api/app-profile \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"contract_number":"<TEST_MUQAVILE>"}'
```

---

## 12. Açıq işlər

| İş | Vəziyyət |
|---|---|
| Tarif keçidi sorğusu (real bağlantı) | Düymə var, endpoint yoxdur |
| TV qoşul / imtina (real bağlantı) | Düymə var, endpoint yoxdur |
| 3 günlük kredit (real bağlantı) | Düymənin yeri var, `credit_status` oxunmur |
| Proxy → Billing HTTPS | HTTP-dədir |
| Rate limiting | Yoxdur |
| Sertifikat pinning | Yoxdur |
