# PavoPay Cloud API - Restoran Entegrasyon Dokümantasyonu

**Versiyon:** 1.0  
**Tarih:** 21 Mayıs 2026  
**API Base URL:** `https://pavo.sirrusyazilim.com/api.php`  
**Pavo Cloud API:** `https://overpaywsdemo.overtech.com.tr`  
**Admin Panel:** `https://pavo.sirrusyazilim.com/admin/`

---

## 1. Genel Bakış

Bu dokümantasyon, restoran yazılımlarının PavoPay POS cihazları ile Cloud API üzerinden entegre olmasını açıklar. Entegrasyon sayesinde restoran yazılımından satış gönderilir, POS cihazında ödeme alınır ve sonuç sorgulanır.

### Temel Akış

```
Restoran Yazılımı → API Sunucusu → PavoPay Cloud → POS Cihazı
                                                       ↓
                                                   Ödeme Alınır
                                                       ↓
Restoran Yazılımı ← API Sunucusu ← PavoPay Cloud ← Sonuç Döner
```

### Desteklenen İşlemler

- Satış gönderme (masa bazlı)
- Ödeme tipi seçimi (nakit, kredi kartı, yemek kartı vb.)
- Satış sorgulama
- Satış iptal etme
- Ürün/kategori/stok yönetimi
- Terminal bildirim gönderme
- X/Z Raporları

---

## 2. Ön Gereksinimler

### 2.1 Kimlik Bilgileri

Pavo'dan alınacak bilgiler:

| Bilgi | Açıklama | Örnek |
|-------|----------|-------|
| `appToken` | Sabit uygulama token'ı | `97b7a056881768d5a5eccac57402166b3024b798` |
| `apiKey` | Üye işyerine özel API anahtarı | `808d9ac24d7ac2fed...` |
| `terminalSerial` | POS cihaz seri numarası | `PAV860030343` |

### 2.2 Terminal Eşleşme (Bir Kez Yapılır)

Cloud API kullanmadan önce restoran yazılımı ile POS cihazı arasında eşleşme yapılması **zorunludur**. Bu işlem kurulum sırasında sadece bir kez yapılır. Eşleşme sonrası dönen `TargetFingerPrint` değeri veritabanına kaydedilir ve her satışta kullanılır.

**Restoran yazılımcısı ne yapmalı:**

1. Kurulum ekranında "POS Cihazı Eşleştir" butonu koyun
2. Kullanıcıdan POS seri numarasını alın (veya QR kod ile okutun)
3. Aşağıdaki API'yi çağırın
4. Dönen `PairingCode`'u kullanıcıya gösterin ("POS cihazında bu kodu onaylayın")
5. Kullanıcı cihazdan onayladıktan sonra `CheckPairing` çağırın
6. Dönen `TargetFingerPrint` değerini veritabanınıza kaydedin
7. Artık satış gönderebilirsiniz

**Adım 1 — Eşleşme İsteği:**

```
POST /api.php?action=pairingRequest
Content-Type: application/json

{
    "sourceFingerPrint": "RESTORAN_ADI",
    "sourceReference": "Restoran_Entegrasyon",
    "targetSerialNo": "PAV860030343"
}
```

Yanıt:
```json
{
    "Data": {
        "Id": 7735,
        "PairingCode": "053636",
        "IsApproved": false
    },
    "Success": true
}
```

> POS cihazında eşleşme isteği çıkacak — cihazdan **onaylayın**.

**Adım 2 — Eşleşme Kontrol:**

```
POST /api.php?action=checkPairing
Content-Type: application/json

{
    "pairingId": 7735,
    "targetSerialNo": "PAV860030343"
}
```

Yanıt:
```json
{
    "Data": {
        "IsApproved": true,
        "TargetFingerPrint": "SPRD/sl8541e_1h10_oversea/sl8541e_1h10:9/PPR1..."
    },
    "Success": true
}
```

> `TargetFingerPrint` değerini **kaydedin** — her satış gönderiminde kullanılacak.

---

## 3. Satış Gönderme (PaymentLinkRequest)

Restoran yazılımından POS cihazına satış göndermek için `PaymentLinkRequest` endpoint'i kullanılır.

### 3.1 Temel Satış

```
POST /api.php?action=paymentLinkRequest
Content-Type: application/json
```

```json
{
    "LinkType": "P",
    "SourceFingerPrint": "RESTORAN_ADI",
    "SourceTerminalReference": "Masa-5",
    "TargetFingerPrint": "SPRD/sl8541e_1h10_oversea/...",
    "TargetSerialNo": "PAV860030343",
    "PushNow": true,
    "PaymentLinkReference": "SRS260521143000",
    "PaymentAmount": 150.00,
    "CurrencyCode": "TRY",
    "RequestedMethod": "P",
    "ApplicationName": "Satış",
    "Request": {
        "Sale": {
            "RefererApp": "Harici Uygulama",
            "RefererAppVersion": "1.0.0",
            "SendEMailNotification": false,
            "SendPhoneNotification": false,
            "SaleReason": "Masa-5 Hesabı",
            "TotalAmount": 150.00,
            "IntegrationSaleType": 1,
            "OrderNo": "MS005-001",
            "TotalPrice": 150.00,
            "GrossPrice": 150.00,
            "CurrencyCode": "TRY",
            "ExchangeRate": 1.0,
            "MainDocumentType": 1,
            "ShowCreditCardMenu": true,
            "AddedSaleItems": [
                {
                    "IsGeneric": false,
                    "ItemQuantity": 2,
                    "Name": "Adana Kebap",
                    "TaxGroupCode": "KDV20",
                    "UnitCode": "C62",
                    "UnitPriceAmount": 50.00,
                    "GrossPriceAmount": 100.00,
                    "TotalPriceAmount": 100.00
                },
                {
                    "IsGeneric": false,
                    "ItemQuantity": 2,
                    "Name": "Ayran",
                    "TaxGroupCode": "KDV10",
                    "UnitCode": "C62",
                    "UnitPriceAmount": 25.00,
                    "GrossPriceAmount": 50.00,
                    "TotalPriceAmount": 50.00
                }
            ]
        }
    }
}
```

### 3.2 Yanıt

```json
{
    "Data": {
        "Id": 72626,
        "StatusId": 1,
        "PaymentLinkReference": "SRS260521143000",
        "PaymentAmount": 150.0,
        "RequestTime": "2026-05-21T14:30:00.123"
    },
    "Success": true
}
```

> `Data.Id` değerini kaydedin — satış durumu sorgulamak için kullanılacak.

---

## 4. Parametre Açıklamaları

### 4.1 Ana Parametreler

| Parametre | Zorunlu | Açıklama |
|-----------|---------|----------|
| `LinkType` | Evet | `"P"` (Paired — eşleşmiş cihaz) |
| `SourceFingerPrint` | Evet | Kaynak uygulama kimliği (eşleşmede kullanılan) |
| `SourceTerminalReference` | Evet | Masa adı / kaynak bilgisi (cihazda görünür) |
| `TargetFingerPrint` | Evet | Eşleşme sonrası alınan cihaz fingerprint'i |
| `TargetSerialNo` | Evet | POS cihaz seri numarası |
| `PushNow` | Evet | `true` — cihaza anında gönder |
| `PaymentLinkReference` | Evet | Benzersiz referans numarası (sorgulama için) |
| `PaymentAmount` | Evet | Toplam tutar |
| `CurrencyCode` | Evet | Para birimi: `"TRY"`, `"USD"`, `"EUR"` |
| `RequestedMethod` | Evet | `"P"` (Payment), `"C"` (Cancel/İptal) |
| `ApplicationName` | Evet | Uygulama adı: `"Satış"` |

### 4.2 Sale (Satış) Parametreleri

| Parametre | Zorunlu | Açıklama |
|-----------|---------|----------|
| `RefererApp` | Evet | `"Harici Uygulama"` (sabit) |
| `RefererAppVersion` | Evet | `"1.0.0"` |
| `TotalAmount` | Evet | Toplam tutar |
| `TotalPrice` | Evet | Toplam fiyat (TotalAmount ile aynı) |
| `GrossPrice` | Evet | Brüt fiyat (TotalAmount ile aynı) |
| `IntegrationSaleType` | Evet | Satış tipi (bkz. aşağıda) |
| `OrderNo` | Hayır | Sipariş numarası (kendi sisteminizden) |
| `MainDocumentType` | Hayır | 1: E-Arşiv, 9: Gider Pusulası, 10: Cari Tahsilat |
| `ShowCreditCardMenu` | Hayır | `true`: cihazda ödeme tipi seçimi çıkar |
| `SaleReason` | Hayır | Satış açıklaması |
| `AddedSaleItems` | Evet | Satış kalemleri dizisi |
| `PaymentInformations` | Hayır | Boş bırakılırsa cihazda ödeme tipi seçilir |

### 4.3 Satış Kalemleri (AddedSaleItems)

| Parametre | Zorunlu | Açıklama |
|-----------|---------|----------|
| `Name` | Evet | Ürün adı |
| `IsGeneric` | Evet | `false` (tanımlı ürün) |
| `ItemQuantity` | Evet | Miktar |
| `UnitCode` | Evet | `"C62"` (Adet), `"KGM"` (Kg), `"LTR"` (Lt) |
| `UnitPriceAmount` | Evet | Birim fiyat |
| `GrossPriceAmount` | Evet | Brüt tutar (miktar × birim fiyat) |
| `TotalPriceAmount` | Evet | Toplam tutar |
| `TaxGroupCode` | Evet | KDV kodu (bkz. aşağıda) |

### 4.4 Ödeme Bilgileri (PaymentInformations) — Opsiyonel

Eğer ödeme tipi önceden belirlenmişse:

```json
"PaymentInformations": [
    {
        "Mediator": 1,
        "Amount": 150.00,
        "CurrencyCode": "TRY",
        "ExchangeRate": 1.0
    }
]
```

**Cihazda ödeme tipi seçilsin istiyorsanız:** `PaymentInformations` göndermeyin ve `ShowCreditCardMenu: true` yapın.

---

## 5. Ödeme Tipi Seçenekleri

### 5.1 Cihazda Seçim (Önerilen)

`PaymentInformations` göndermezseniz ve `ShowCreditCardMenu: true` yaparsanız, cihaz ekranında tüm ödeme seçenekleri görünür. Garson veya müşteri cihazdan seçer.

### 5.2 Sabit Ödeme Tipi

| Mediator ID | Ödeme Tipi |
|-------------|-----------|
| 1 | Nakit |
| 2 | Kredi Kartı (BKM TechPos) |
| 4 | Multinet |
| 10 | Harici Yemek Kartı |
| 13 | Metropol |
| 27 | Ödemesiz |
| 28 | Havale / EFT |
| 29 | Açık Hesap |

---

## 6. Referans Kodları

### 6.1 KDV Kodları (TaxGroupCode)

| Kod | Oran | Açıklama |
|-----|------|----------|
| `KDV20` | %20 | Standart KDV |
| `KDV10` | %10 | İndirimli KDV |
| `KDV1` | %1 | Düşük KDV |
| `KDV0-351` | %0 | KDV İstisna |

### 6.2 Satış Tipleri (IntegrationSaleType)

| Tip | Ad |
|-----|----|
| 1 | Normal Satış |
| 2 | Avans Satış |
| 3 | Cari Satış |
| 4 | Kuyum Satış |
| 6 | Kısmi İade |
| 7 | Avans Kısmi İade |

### 6.3 Satış Durumları (StatusId)

| ID | Durum |
|----|-------|
| 1 | Initial (Başlatıldı) |
| 2 | InProgress (İşleniyor) |
| 3 | Completed (Tamamlandı) |
| 4 | Abandoned (Vazgeçildi) |
| 5 | Aborted (İptal Edildi) |

### 6.4 Birim Kodları (UnitCode)

| Kod | Birim |
|-----|-------|
| `C62` | Adet |
| `KGM` | Kilogram |
| `LTR` | Litre |
| `MTR` | Metre |

---

## 7. Satış Durumu Sorgulama

### 7.1 PaymentLinkId ile Sorgulama

```
POST /api.php?action=checkLinkRequest
Content-Type: application/json

{
    "paymentLinkId": 72626,
    "paymentLinkReference": ""
}
```

### 7.2 PaymentLinkReference ile Sorgulama

```
POST /api.php?action=checkLinkRequest
Content-Type: application/json

{
    "paymentLinkId": 0,
    "paymentLinkReference": "SRS260521143000"
}
```

### 7.3 OrderNo ile Sorgulama

```
GET /api.php?action=getCompletedSale&orderNo=MS005-001
```

### 7.4 Yanıt Örneği

```json
{
    "Data": {
        "Id": 72626,
        "StatusId": 3,
        "PaymentLinkReference": "SRS260521143000",
        "PaymentAmount": 150.0,
        "RequestTime": "2026-05-21T14:30:00.123",
        "ResponseTime": "2026-05-21T14:30:15.456",
        "Response": "{...satış detayları...}"
    },
    "Success": true
}
```

> `StatusId: 3` = Tamamlandı. `Response` alanında satış detayları (SaleNumber, ödeme bilgileri vb.) JSON olarak yer alır.

---

## 8. Satış İptal Etme

### 8.1 Link İptali

Henüz tamamlanmamış bir satış linkini iptal etmek için:

```
POST /api.php?action=cancelLinkRequest
Content-Type: application/json

{
    "paymentLinkId": 72626,
    "paymentLinkReference": ""
}
```

### 8.2 Tamamlanmış Satış İptali

Tamamlanmış bir satışı iptal etmek için `RequestedMethod: "C"` ile PaymentLinkRequest gönderilir:

```json
{
    "LinkType": "P",
    "SourceFingerPrint": "RESTORAN_ADI",
    "SourceTerminalReference": "Masa-5",
    "TargetFingerPrint": "...",
    "TargetSerialNo": "PAV860030343",
    "PaymentLinkReference": "CANCEL001",
    "PaymentAmount": 150.00,
    "CurrencyCode": "TRY",
    "RequestedMethod": "C",
    "ApplicationName": "Satış",
    "Request": {
        "Sale": {
            "SaleNumber": "rjQz55XXwC",
            "ReceiptInformation": {
                "PrintCustomerReceipt": true,
                "PrintMerchantReceipt": false,
                "ReceiptWidth": "80mm"
            }
        }
    }
}
```

---

## 9. Restoran Yazılımı Entegrasyon Rehberi

### 9.1 Yazılımcının Yapması Gerekenler

#### Adım 1: API Bağlantı Sınıfı Oluşturun

Restoran yazılımınızda bir `PavoPayService` sınıfı oluşturun. Bu sınıf:
- `appToken` ve `apiKey` ile authenticate olur
- Token'ı cache'ler (60 dk geçerli)
- Tüm API çağrılarını yapar

#### Adım 2: Ayarlar Ekranı

Restoran yazılımınızın ayarlar bölümüne ekleyin:
- PavoPay appToken girişi
- PavoPay apiKey girişi
- POS seri numarası girişi
- "POS Eşleştir" butonu
- Eşleşme durumu göstergesi (Eşleşmiş ✓ / Eşleşmemiş ✗)

#### Adım 3: Eşleşme Akışı (Bir Kez)

```
Kullanıcı "POS Eşleştir" butonuna basar
    → PairingRequest gönder
    → Ekranda göster: "POS cihazında XXXXXX kodunu onaylayın"
    → Kullanıcı "Onayladım" butonuna basar
    → CheckPairing çağır
    → TargetFingerPrint'i veritabanına kaydet
    → Ekranda göster: "Eşleşme tamamlandı ✓"
```

#### Adım 4: Masa / Hesap Kapatma Akışı

Restoran yazılımınızda hesap kapatma butonuna basıldığında:

```
1. Masa bilgilerini topla (masa adı, ürünler, tutar)
2. PaymentLinkRequest gönder:
   - SourceTerminalReference = masa adı ("Masa-5")
   - OrderNo = kendi sipariş numaranız ("SIP-2026-001")
   - PaymentLinkReference = benzersiz referans ("REF" + timestamp)
   - AddedSaleItems = masadaki ürünler
   - ShowCreditCardMenu = true (garson cihazda ödeme tipi seçer)
3. Dönen LinkId'yi kaydet
4. Polling başlat (3 sn aralıkla CheckLinkRequest)
5. StatusId = 3 (Completed) → masa kapat, fiş bilgilerini kaydet
6. StatusId = 4 veya 5 → hata göster, tekrar dene seçeneği sun
```

#### Adım 5: Sipariş Detaylarını POS'a Gönderme

Her masadaki ürünü `AddedSaleItems` dizisine ekleyin:

```
Masa-5 Siparişi:
  2x Adana Kebap    → 100.00 ₺ (KDV20)
  1x Lahmacun       →  45.00 ₺ (KDV20)
  3x Ayran          →  75.00 ₺ (KDV10)
  1x Künefe         →  60.00 ₺ (KDV20)
  ─────────────────────────────
  Toplam:             280.00 ₺
```

Bu, POS cihazında ürün bazlı fiş çıkmasını sağlar.

### 9.2 Tipik Restoran Kullanım Senaryoları

#### Senaryo 1: Normal Masa Hesabı

```
Garson tablet/bilgisayardan "Hesabı Kapat" butonuna basar
→ Yazılım PaymentLinkRequest gönderir (ShowCreditCardMenu: true)
→ POS cihazına satış düşer, ekranda "Masa-5" ve ürünler görünür
→ Garson POS'ta ödeme tipini seçer (Nakit / Kart)
→ Ödeme alınır, fiş basılır
→ Yazılım CheckLinkRequest ile sonucu alır
→ Masa kapatılır
```

#### Senaryo 2: Nakit Ödeme (Önceden Belirlenen)

```
Müşteri "Nakit ödeyeceğim" der
→ Yazılım PaymentInformations ile Mediator:1 (Nakit) gönderir
→ POS cihazında direkt nakit ödeme ekranı açılır
→ Garson parayı alır, POS'ta onaylar
```

#### Senaryo 3: Kart ile Ödeme (Önceden Belirlenen)

```
Müşteri kartını uzatır
→ Yazılım PaymentInformations ile Mediator:2 (Kredi Kartı) gönderir
→ POS cihazında direkt kart okutma ekranı açılır
→ Müşteri kartını okuttur, PIN girer
```

#### Senaryo 4: Hesap İptali

```
Müşteri siparişten vazgeçer (henüz ödeme alınmadı)
→ Yazılım CancelLinkRequest ile linki iptal eder
→ POS cihazından istek kaldırılır
```

#### Senaryo 5: Satış İadesi (Ödeme Alındıktan Sonra)

```
Müşteri iade ister
→ Yazılım RequestedMethod: "C" ile PaymentLinkRequest gönderir
→ SaleNumber ile orijinal satışı referans gösterir
→ POS cihazında iade işlemi yapılır
```

### 9.3 Veritabanı Tasarım Önerisi

Restoran yazılımınızda şu tabloları oluşturun:

```sql
-- PavoPay Ayarları
CREATE TABLE pavopay_config (
    config_key VARCHAR(100) PRIMARY KEY,
    config_value TEXT
);
-- Kayıtlar: app_token, api_key, terminal_serial,
--           target_finger_print, source_finger_print, pairing_id

-- PavoPay Satış Logları
CREATE TABLE pavopay_sales (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_id INT,                    -- Kendi sipariş ID'niz
    table_name VARCHAR(50),          -- Masa adı
    payment_link_id INT,             -- Pavo LinkId
    payment_link_reference VARCHAR(100), -- Benzersiz referans
    amount DECIMAL(12,2),
    status VARCHAR(20),              -- pending/completed/cancelled
    request_json TEXT,
    response_json TEXT,
    created_at DATETIME DEFAULT NOW()
);
```

### 9.4 Örnek Entegrasyon Kodu (PHP)

```php
class PavoPayService {
    private string $apiUrl;
    private string $appToken;
    private string $apiKey;
    private string $sourceFP;
    private string $targetFP;
    private string $targetSerial;

    public function __construct(array $config) {
        $this->apiUrl       = $config['api_url'];
        $this->appToken     = $config['app_token'];
        $this->apiKey       = $config['api_key'];
        $this->sourceFP     = $config['source_finger_print'];
        $this->targetFP     = $config['target_finger_print'];
        $this->targetSerial = $config['terminal_serial'];
    }

    /**
     * Masa hesabını POS cihazına gönder
     */
    public function sendTableOrder(
        string $tableName,
        string $orderNo,
        float  $totalAmount,
        array  $items,
        bool   $letDeviceChoosePayment = true
    ): array {
        $saleModel = [
            'RefererApp'            => 'Harici Uygulama',
            'RefererAppVersion'     => '1.0.0',
            'SendEMailNotification' => false,
            'SendPhoneNotification' => false,
            'SaleReason'            => $tableName . ' Hesabı',
            'TotalAmount'           => $totalAmount,
            'IntegrationSaleType'   => 1,
            'OrderNo'               => $orderNo,
            'TotalPrice'            => $totalAmount,
            'GrossPrice'            => $totalAmount,
            'CurrencyCode'          => 'TRY',
            'ExchangeRate'          => 1.0,
            'MainDocumentType'      => 1,
            'ShowCreditCardMenu'    => $letDeviceChoosePayment,
            'AddedSaleItems'        => $items,
        ];

        $body = [
            'LinkType'                => 'P',
            'SourceFingerPrint'       => $this->sourceFP,
            'SourceTerminalReference' => $tableName,
            'TargetFingerPrint'       => $this->targetFP,
            'TargetSerialNo'          => $this->targetSerial,
            'PushNow'                 => true,
            'PaymentLinkReference'    => 'ORD' . time(),
            'PaymentAmount'           => $totalAmount,
            'CurrencyCode'            => 'TRY',
            'RequestedMethod'         => 'P',
            'ApplicationName'         => 'Satış',
            'Request'                 => ['Sale' => $saleModel],
        ];

        return $this->post('paymentLinkRequest', $body);
    }

    /**
     * Satış durumunu sorgula
     */
    public function checkStatus(int $linkId): array {
        return $this->post('checkLinkRequest', [
            'paymentLinkId'        => $linkId,
            'paymentLinkReference' => '',
        ]);
    }

    /**
     * Satışı iptal et
     */
    public function cancelLink(int $linkId): array {
        return $this->post('cancelLinkRequest', [
            'paymentLinkId'        => $linkId,
            'paymentLinkReference' => '',
        ]);
    }

    private function post(string $action, array $data): array {
        $ch = curl_init($this->apiUrl . '?action=' . $action);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($data),
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
            CURLOPT_TIMEOUT        => 30,
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true) ?? ['Success' => false];
    }
}

// Kullanım:
$pavo = new PavoPayService([
    'api_url'              => 'https://pavo.sirrusyazilim.com/api.php',
    'app_token'            => '97b7a056881768d...',
    'api_key'              => '808d9ac24d7ac2f...',
    'source_finger_print'  => 'SIRRUS',
    'target_finger_print'  => 'SPRD/sl8541e_1h10...',
    'terminal_serial'      => 'PAV860030343',
]);

// Masa-5 hesabını gönder
$result = $pavo->sendTableOrder('Masa-5', 'SIP-001', 280.00, [
    ['IsGeneric'=>false, 'ItemQuantity'=>2, 'Name'=>'Adana Kebap',
     'TaxGroupCode'=>'KDV20', 'UnitCode'=>'C62',
     'UnitPriceAmount'=>50, 'GrossPriceAmount'=>100, 'TotalPriceAmount'=>100],
    ['IsGeneric'=>false, 'ItemQuantity'=>3, 'Name'=>'Ayran',
     'TaxGroupCode'=>'KDV10', 'UnitCode'=>'C62',
     'UnitPriceAmount'=>25, 'GrossPriceAmount'=>75, 'TotalPriceAmount'=>75],
]);

if ($result['Success']) {
    $linkId = $result['Data']['Id'];
    // Sonucu bekle...
    $status = $pavo->checkStatus($linkId);
}
```

---

## 10. Tüm API Endpoint'leri

### 10.1 Kimlik Doğrulama

| Endpoint | Method | Açıklama |
|----------|--------|----------|
| `?action=auth` | GET | Token al (otomatik cache'lenir) |
| `?action=authenticate` | GET | Yeni token oluştur |

### 10.2 Satış İşlemleri

| Endpoint | Method | Açıklama |
|----------|--------|----------|
| `?action=paymentLinkRequest` | POST | Satış/İptal gönder |
| `?action=checkLinkRequest` | POST | Satış durumu sorgula |
| `?action=cancelLinkRequest` | POST | Link iptal |
| `?action=getCompletedSale` | GET | Satış detay (orderNo/saleId/saleUID/saleNumber) |
| `?action=listCompletedSales` | GET | Tamamlanan satış listesi |
| `?action=listSales` | GET | Satış listesi |

### 10.3 Terminal Eşleşme

| Endpoint | Method | Açıklama |
|----------|--------|----------|
| `?action=pairingRequest` | POST | Eşleşme isteği |
| `?action=checkPairing` | POST | Eşleşme kontrol |

### 10.4 Ürün Yönetimi

| Endpoint | Method | Açıklama |
|----------|--------|----------|
| `?action=listProducts` | GET | Ürün listesi |
| `?action=getProduct` | GET | Ürün detay |
| `?action=uploadProduct` | POST | Ürün ekle/güncelle |
| `?action=uploadCategory` | POST | Kategori ekle |
| `?action=uploadProperty` | POST | Özellik ekle |
| `?action=uploadProductStock` | POST | Stok güncelle |
| `?action=addStockTransaction` | POST | Stok hareketi |
| `?action=deleteProductImages` | POST | Ürün resimleri sil |
| `?action=listBranches` | GET | Şube listesi |

### 10.5 Bildirim

| Endpoint | Method | Açıklama |
|----------|--------|----------|
| `?action=sendNotification` | POST | Firebase push bildirim |

---

## 11. Hata Yönetimi

### 11.1 API Yanıt Yapısı

Başarılı:
```json
{
    "Success": true,
    "Data": { ... },
    "Message": null
}
```

Hatalı:
```json
{
    "Success": false,
    "Message": "Hata açıklaması"
}
```

### 11.2 Yaygın Hatalar

| Hata | Çözüm |
|------|-------|
| `Authentication failed` | appToken veya apiKey hatalı |
| `SourceFingerPrint cannot be empty` | Eşleşme bilgileri eksik |
| `Undefined request method type` | TargetFingerPrint boş — eşleşme yapılmamış |
| `Payment link not found` | Geçersiz PaymentLinkId veya Reference |
| `Cihaz Meşgul` | POS cihazında başka işlem devam ediyor |

### 11.3 Öneriler

- Her satış için **benzersiz** `PaymentLinkReference` kullanın
- Satış sonucunu **polling** ile sorgulayın (3-5 saniye aralıklarla)
- Token otomatik cache'lenir (60 dk), süre dolunca yenilenir
- Hata durumunda **retry** mekanizması kurun

---

## 12. Güvenlik

- API iletişimi **HTTPS** üzerinden yapılır
- Token **60 dakika** geçerlidir, otomatik yenilenir
- `TargetFingerPrint` eşleşme onayı olmadan satış gönderilemez
- Her satış **loglanır** (sale_logs tablosu)
- Admin panel **şifre korumalı** (session timeout: 1 saat)

---

## 13. Test Ortamı

| Bilgi | Değer |
|-------|-------|
| API Base URL | `https://overpaywsdemo.overtech.com.tr` |
| appToken | `97b7a056881768d5a5eccac57402166b3024b798` |
| Admin Panel | `https://pavo.sirrusyazilim.com/admin/` |
| Admin Giriş | admin / admin123 |
| Terminal | PAV860030343 (ID: 76295) |

---

## 14. İletişim

- **Pavo Destek:** gmudestek@pavo.com.tr / 0850 611 0 444
- **Sirrus Yazılım:** admin@sirrusyazilim.com
