# AltBusiness — Java / Spring Boot bağlantısı

PHP və ya Node.js işlətmək lazım deyil. `AbcSiteBridge.java` Java 11 və daha yeni versiyada işləyən, əlavə kitabxana tələb etməyən hazır HTTPS/JSON müştərisidir. Spring Boot layihəsinə də adi Java sinfi kimi əlavə olunur.

## Müştərinin edəcəyi 3 addım

1. **Sayt bağlantıları → Sayt qoş → Xüsusi sayt** seçin. Saytın açıq əsas ünvanını yazın, məsələn `https://magaza.az`; admin panelinin və hostinqin ünvanını yazmayın.
2. Görmək istədiyiniz məlumatları seçin, əvvəlcə yalnız baxış icazəsi ilə qoşulma kodu yaradın.
3. **Java bağlantı dəstini** proqramçıya verin. Proqramçı birdəfəlik kodu saytın serverində istifadə edir. Sonra əlavə etdiyiniz saytın qoşulma və sinxronlaşma vəziyyətini burada yoxlayın.

WordPress / WooCommerce hazır əlavəsi varsa ZIP faylı yükləmək və kodu daxil etmək kifayətdir. Hazır uyğunlaşdırıcısı olmayan fərdi saytın daxili məlumat quruluşunu avtomatik təxmin etmək olmaz; aşağıdakı xəritələməni proqramçı bir dəfə edir. Mövcud API və uyğun məlumatlar varsa ilk oxuma bağlantısı qısa çəkə bilər; tam ikitərəfli inteqrasiyanın bütün fərdi saytlarda 5–10 dəqiqəyə bitməsi vəd edilmir.

## Proqramçının edəcəyi iş

### 1. Hazır sinfi layihəyə əlavə edin

`AbcSiteBridge.java` faylını saytın Java server layihəsinə əlavə edin. Layihənizin paket quruluşuna uyğun `package ...;` sətrini əlavə edə bilərsiniz. Verilənlər bazası, ödəniş və ya istifadəçi şifrəsi ABC-yə verilmir.

### 2. Birdəfəlik qoşulun

```java
AbcSiteBridge abc = new AbcSiteBridge("https://magaza.az", null);
Map<String,Object> paired = abc.connect(
    System.getenv("ABC_PAIRING_CODE"),
    AbcSiteBridge.map("products", List.of("read"), "customers", List.of("read"), "orders", List.of("read"))
);
// paired.token: serverin secret manager / mühit dəyişənində saxlayın.
// Tokeni loga, brauzerə, Git-ə və ya açıq fayla yazmayın.
// paired.progress və sync_generation ilk sinxronlaşmanın mövqeyidir.
```

Kod birdəfəlikdir. Sonrakı işə salınmada yeni kod yaratmayın; saxlanmış tokenlə `new AbcSiteBridge(siteUrl, savedToken)` istifadə edin. Qoşulma zamanı qəbul edilmiş icazələr cavabda gəlir; dəstəkləmədiyiniz yazma icazələrini elan etməyin.

### 3. Öz repository nəticələrinizi standart formaya çevirin

```java
Map<String,Object> record = AbcSiteBridge.record(
    product.getId().toString(), product.getName(),
    AbcSiteBridge.map(
      "name", product.getName(), "sku", product.getSku(),
      "price", product.getPrice().toPlainString(), "currency", "AZN",
      "stock_quantity", product.getStock(), "manage_stock", true,
      "status", "publish"),
    product.getVersion().toString() // hər dəyişiklikdə dəyişən mənbə versiyası
);
Map<String,Object> reply = abc.exchange(
  List.of(AbcSiteBridge.upload("products", List.of(record), generation, sequence, snapshotId, cursor, complete)),
  List.of()
);
```

`product.get...` sizin mövcud entity/repository metodlarınızdır; SDK saytınızın cədvəl adlarını bilmədiyi üçün bu uyğunlaşdırma vacibdir. Sınaq/maket məlumatını həqiqi məhsul əvəzinə göndərməyin.

Hər sorğu 750 KB-dan kiçik, hər paket ən çox 100 qeyd olmalıdır. İlk tam siyahını səhifələrə bölün. `sync_generation` və `progress` dəyərlərini server cavabından götürün; sequence hər resurs üçün əvvəlkindən 1 böyükdür. Eyni snapshot_id bütün səhifələrdə sabit qalır. Yalnız son səhifədə complete=true yazın. Cursor/sequence mövqeyini yalnız uğurlu cavabdan sonra saxlayın. 409 aldıqda boş exchange edib qaytarılan progress ilə uzlaşdırın. Bu yanaşma mövcud qeydləri itirmədən təkrar cəhdə imkan verir.

| Bölmə | Əsas data sahələri |
|---|---|
| products | name, sku, price (məs. "29.90"), currency, stock_quantity, manage_stock, status |
| customers | name, phone, email |
| orders | number, status, total ("29.90"), currency, customer_external_id, customer_name, items |
| pages | title, slug, content, status |
| coupons | code, amount, discount_type, date_expires |
| settings | title, tagline, timezone, currency |

Müştəri kartının nömrəsi, CVV, şifrə, cookie, API açarı və sessiya məlumatı göndərilmir. Qiymətlər saytın əsas valyutasında **manat vahidində mətn** kimi göndərilir; ABC-nin daxili qəpik formatı ilə qarışdırmayın.

### 4. Dövri sinxronlaşma və qəbul yoxlaması

Spring `@Scheduled(fixedDelay=15000)` və ya mövcud növbə/planlaşdırıcınızdan istifadə edin. Eyni sayt üçün paralel dövrlər açmayın. Sayt başladıqda mövqeyi və tokeni davamlı yaddaşdan bərpa edin.

Yazma imkanları üçün əlavə olaraq `cycle(uploads, persistentReceiptDirectory, executor)` istifadə olunur. Executor **eyni DB transaction-da** command ID üzrə təkrarı dayandırmalı, expected_version müqayisəsi etməli, dəyişiklik və nəticəni saxlamalıdır. Uyğunlaşdırılmamış yazma funksiyasını açmayın. SDK yarımçıq qalmış qeyri-müəyyən əmri özbaşına təkrar icra etmir. Çoxsaylı server instansiyası varsa fayl receipt anbarı yerinə ortaq DB icra jurnalı olan adapter qurun.

Qəbul: (1) məhsul sayı uyğun gəlir, (2) ad/qiymət/stok düzgündür, (3) saytdakı dəyişiklik ABC-yə düşür, (4) yazma aktivdirsə ABC-dən bir sınaq dəyişikliyi sayta düşür, (5) köhnə versiya dəyişdirilmir, (6) başqa şirkətin məlumatı görünmür. Əvvəl sınaq qeydi istifadə edin.

## Yalnız sifarişlər lazımdırsa daha qısa yol

`AbcOrderWebhook.java` saytınızda sifariş uğurla yaradıldıqdan sonra imzalı sifarişi ABC-yə göndərir. Sayt bağlantılarının **Sifariş ötürmə** bölməsindən endpoint, anbar ID-si və secret götürün. Sifarişdəki SKU-lar əvvəl ABC-dəki məhsullarla uyğun olmalıdır. Bu yol məhsul, səhifə və digər sayt məlumatlarının tam idarəetməsi deyil.

```java
AbcOrderWebhook.send(endpoint, System.getenv("ABC_WEBHOOK_SECRET"),
  persistedEventId, abcLocationId,
  AbcSiteBridge.map("name", customerName, "phone", customerPhone),
  List.of(AbcSiteBridge.map("sku", productSku, "quantity", quantity)));
```

Sifariş üçün event ID bir dəfə yaradılıb DB-də saxlanır; uğursuz şəbəkə cəhdində eyni ID təkrar istifadə edilir. Tam kart məlumatı bu bağlantıda da tələb edilmir.

## Şəbəkəsiz texniki sınaq

```sh
javac AbcSiteBridge.java AbcOrderWebhook.java AbcSiteBridgeSmokeTest.java
java AbcSiteBridgeSmokeTest
```

Sınaq real hesaba qoşulmur, açar tələb etmir və sifariş göndərmir.
