# Ödeme Kuruluşu Kancaları

https://dev.wisecp.com/tr/odeme-kurulusu-kancalari

Ödeme kuruluşuyla konuşan on dört kanca: uzlaşma, geri dönüş bildirimi, saklı kartlar ve abonelik tahsilatı.

## Genel Bakış

Ödeme kuruluşuyla iletişim **iki yönlüdür**. Biz bir tahsilat isteriz, kuruluş cevabını ya hemen verir ya da sonradan **geri bildirim** olarak gönderir. İkinci yol tarayıcıdan da gelebilir, doğrudan sunucudan da.

Saklı kartlarda ise kart numarası **bize hiç gelmez**: kuruluş bir anahtar saklar, biz yalnız gösterim bilgisini (son dört hane, marka, son kullanma) tutarız. Kancalara da yalnız o bilgi gelir.

## Referans

### Uzlaşmayı izleme

actionpayment.settled

`PaymentGatewayModule` beklemede olabilir

Ödeme kuruluşuyla uzlaşma tamamlandıktan sonra çalışır.

Parametreler 4

$modulePaymentGatewayModuleUzlaşmayı yapan modül örneği.

$checkoutarrayÖdeme kaydının **yazım sonrası** hâli: durumu ödenmiş, içinde uzlaşma zamanı ve işlem numarası. `settled_status` alanı `pending` olabilir: para **henüz kesinleşmemiş** demektir.

$resultarrayModülün **ham** sonucu: durum, mesaj, ödendi işareti, abonelik bilgisi. Kuruluşun kendi diliyle konuşur.

$responsearrayÇekirdeğe dönecek cevap: durum, beklemede işareti, yönlendirme adresi.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.settled', 10,
    function ($module, $checkout, $result, $response) {
        // BEKLEMEDE olabilir: para kesinlesmeden hizmet acmayin.
        if (($checkout['data']['settled_status'] ?? '') !== 'successful') return;

        Accounting::gatewaySettled($module->name, $checkout);
    });
```

### Geri bildirimi izleme

actionpayment.callback_returned

`PaymentGatewayModule` kayıt boş olabilir

Ödeme kuruluşunun geri bildirimi yorumlandıktan sonra çalışır.

Parametreler 4

$modulePaymentGatewayModuleBildirimi yorumlayan modül.

$checkoutarrayÖdeme kaydı. Modül kaydı çözemediyse **boş dizi** gelir: sahte ya da eşleşmeyen bir bildirim olabilir.

$settlearrayUzlaşma sonucu: durum, yönlendirme, mesaj ve `already` işareti. `already` "bu bildirim daha önce işlendi" demektir.

$is_s2sboolBildirim **doğrudan sunucudan** mı geldi. `false` ise müşterinin tarayıcısı döndürmüştür; müşteri o sayfayı hiç açmamış da olabilir.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.callback_returned', 10,
    function ($module, $checkout, $settle, $is_s2s) {
        // Bos checkout = eslesmeyen bildirim; tekrar isaretini de kontrol edin.
        if (!$checkout || !empty($settle['already'])) return;

        Ops::note('gateway-callback', $module->name, $is_s2s ? 'sunucu' : 'tarayici');
    });
```

### Kart eklemeyi durdurma

gatepayment.card_add

`AccountCards` numara gelmez

Müşteri kart eklerken çalışır. **Kart numarası bu kancaya gelmez**; karar için yalnız hesap ve modül bilgisi vardır.

Parametreler 3

$uidintKartı ekleyen hesap. Kendi hesabı olduğu doğrulanmıştır.

$moduleNamestringKart saklayan ödeme kuruluşu modülü.

$autoPayboolKart otomatik ödeme zincirine girecek mi. Modül desteklemiyorsa hep `false`.

Dönüş 1

stringBoş olmayan bir string kart eklemeyi **durdurur**.

Dinleyici PHP

```php
Hook::add('gate:payment.card_add', 10, function ($uid, $moduleName, $autoPay) {
    // Kart numarasi buraya GELMEZ: karari hesap uzerinden verin.
    if (Acme::cardCount($uid) >= 5) return 'En fazla 5 kart saklanir.';

    return null;
});
```

### Kart saklandığını izleme

actionpayment.card_stored

`AccountCards` yalnız gösterim bilgisi

Kart kuruluşta saklandıktan sonra çalışır.

Parametreler 4

$userIdintKartın sahibi.

$cardIdintSaklanan kart kaydının kimliği.

$modulestringKartı saklayan modül.

$cardarray**Yalnız gösterim bilgisi**: son dört hane, marka, tip, son kullanma ayı ve yılı. Kart numarası, güvenlik kodu ve kuruluş anahtarı **burada yoktur** ve olmayacaktır.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.card_stored', 10, function ($userId, $cardId, $module, $card) {
    // Yalniz gosterim bilgisi gelir; numara ve token asla.
    Notify::securityEvent($userId, 'card-added', $card['ln4'] ?? '');
});
```

### Varsayılan kartı izleme

actionpayment.card_default_set

`AccountCards` otomatik ödeme buradan

Bir kart varsayılan yapıldıktan sonra çalışır.

Parametreler 2

$uidintKartın sahibi.

$cardIdintVarsayılan yapılan kartın kimliği. Otomatik ödeme bundan sonra bu kartı dener.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.card_default_set', 10, function ($uid, $cardId) {
    Audit::note('card-default', (string) $uid, (string) $cardId);
});
```

### Kart silmeyi izleme

actionpayment.card_removed

`AccountCards` otomatik ödeme etkilenir

Saklı kart silindikten sonra çalışır.

Parametreler 2

$uidintKartın sahibi.

$cardIdintSilinen kartın kimliği.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.card_removed', 10, function ($uid, $cardId) {
    // Son kart silindiyse otomatik odeme sessizce durur: musteriyi uyarin.
    if (Acme::cardCount($uid) === 0) Notify::noCardLeft($uid);
});
```

### Abonelik iptalini durdurma

gatepayment.subscription_cancel

`AccountCards` kuruluştaki anlaşma

Müşteri ödeme kuruluşundaki tekrarlayan anlaşmayı iptal ederken çalışır.

Parametreler 2

$uidintAnlaşmanın sahibi.

$idintİptal edilecek anlaşmanın kimliği.

Dönüş 1

stringBoş olmayan bir string iptali **durdurur**.

Dinleyici PHP

```php
Hook::add('gate:payment.subscription_cancel', 10, function ($uid, $id) {
    // Anlasma iptali hizmeti kapatmaz ama odemeyi keser: once uyarin.
    if (Acme::activeServices($uid) > 0 && !Acme::confirmed($uid))
        return 'Aktif hizmetiniz var; iptali onaylamaniz gerekiyor.';

    return null;
});
```

### Abonelik yoklamasını izleme

actionpayment.subscription_polled

`cronjobs/SubscriptionPoll` düzenli çalışır

Zamanlanmış görev ödeme kuruluşundaki anlaşmaları sorguladıktan sonra çalışır.

Parametreler 2

$subscriptionarrayYoklanan anlaşma kaydı.

$resultarrayKuruluştan dönen sonuç. Yoklama düzenli çalışır: aynı anlaşma için **defalarca** gelir.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.subscription_polled', 10, function ($subscription, $result) {
    // Duzenli calisir: her yoklamada degil, DEGISIKLIKTE tepki verin.
    Acme::syncSubscription($subscription, $result);
});
```

### Kuruluş ayarlarının kaydını izleme

actionpayment.settings_saved

`PaymentGatewayModule` diske yazıldıktan sonra

Bir ödeme modülünün ayarları kaydedildikten sonra çalışır.

Parametreler 2

$module_namestringAyarları kaydedilen modülün adı.

$configarrayDiske yazılan yapılandırmanın tamamı. İçinde API anahtarı ve gizli değerler bulunur: kendi kaydınıza ya da günlüğünüze yazmayın.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.settings_saved', 10, function ($module_name, $config) {
    // Yapilandirmanin kendisini DEGIL, yalniz degistigi bilgisini tasiyin.
    Acme::notifyOps('odeme ayari degisti: ' . $module_name);
});
```

### Kart sorgusunu devralma

filterpayment.bin_lookup

`Payment` bağla geçer

Kartın ilk hanelerinden banka ve tip çözülürken çalışır. Doldurursanız dış servise **hiç gidilmez**.

Parametreler 2

$resultarray|falsebağlaSorgu sonucu. Beklenen alanlar: ülke, kart tipi, şema, banka adı ve marka.

$bin_numberstringKartın ilk altı hanesi.

Dönüş 1

voidDönüş yoksayılır; sonucun üzerine yazarsınız. Dokunmazsanız dış sorgu normal biçimde sürer. Kendi önbelleğinizi buraya bağlamak, her ödemede dışarı çıkmayı önler.

Dinleyici PHP

```php
Hook::add('filter:payment.bin_lookup', 10, function (&$result, $bin_number) {
    // Kendi onbelleginiz varsa dis servise hic cikmayin.
    $cached = Acme::binCache($bin_number);
    if ($cached) $result = $cached;
});
```

### Ödeme panelini kendi ekranınızla değiştirme

filterpayment.gateway_pane

`Checkout` bağla geçer

Ödeme adımında kuruluşun paneli hazırlanırken çalışır. Kendi ekranınızı burada gösterir, klasik ödeme sayfasını atlarsınız.

Parametreler 2

$htmlstringbağlaPanelde görünecek içerik.

$ctxarraybağlaBağlam.

Dönüş 1

voidDönüş yoksayılır. İçeriği **dolu bırakırsanız** sizin ekranınız gösterilir; **boş bırakırsanız** klasik ödeme sayfasına düşülür. Yani boşaltmak da bir karardır.

Dinleyici PHP

```php
Hook::add('filter:payment.gateway_pane', 10, function (&$html, &$ctx) {
    // Dolu birakmak kendi ekraniniz, bos birakmak klasik sayfa demektir.
    $html = Acme::renderPane($ctx);
});
```

### Anlaşmanın iptalini izleme

actionpayment.subscription_cancelled

`AccountSubscriptions` iptal sonrası

Bir ödeme anlaşması iptal edildikten sonra çalışır. Bundan sonra o anlaşmadan tahsilat gelmez.

Parametreler 2

$subscription_idintİptal edilen anlaşmanın kimliği.

$subarrayAnlaşma satırının **iptal öncesi** hâli: sahibi, modülü, tanımlayıcısı, para birimi ve dönemi.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.subscription_cancelled', 10, function ($subscription_id, $sub) {
    // Bagli hizmetler artik otomatik tahsilatsiz kalir.
    Acme::warnUnpaidRisk((int) ($sub['user_id'] ?? 0));
});
```

### Anlaşmadan üye çıkarmayı durdurma

gatepayment.subscription_member_remove

`AccountSubscriptions` çıkarmadan önce

Bir hizmet ya da eklenti ödeme anlaşmasından çıkarılmadan önce çalışır.

Parametreler 6

$uidintAnlaşmanın sahibi.

$subscription_idintAnlaşmanın kimliği.

$typestring`service` ya da `addon`.

$midintÜyenin kimliği.

$memberarrayÇıkarılacak üye satırı. Eklentide sahip alanı **üst hizmetin** kimliğini taşır, kullanıcınınkini değil: buna göre okuyun.

$subarrayAnlaşma satırı.

Dönüş 1

string|null**Boş olmayan bir metin çıkarmayı engeller** ve hata olarak gösterilir. Boş dönüş devam ettirir.

Dinleyici PHP

```php
Hook::add('gate:payment.subscription_member_remove', 10,
    function ($uid, $subscription_id, $type, $mid, $member, $sub) {
        // Taahhut suresi dolmadan cikarmaya izin vermeyin.
        if (Acme::underCommitment($mid, $type)) return 'Taahhut suresi dolmadan cikarilamaz.';

        return null;
    });
```

### Üyenin çıkarılmasını izleme

actionpayment.subscription_member_removed

`AccountSubscriptions` çıkarma sonrası

Üye anlaşmadan çıkarıldıktan sonra çalışır.

Parametreler 5

$typestring`service` ya da `addon`.

$idintÜyenin kimliği.

$memberarrayÜye satırının **çıkarma öncesi** hâli. Anlaşma alanı hâlâ **eski** değeri taşır: “hangi anlaşmadan çıktı” sorusunun cevabı buradadır.

$subarrayAnlaşma satırının **değişim öncesi** hâli; durumu ve tutarı eski değerleridir.

$historyarrayİşlemin sonucu, geçmiş kaydına yazılanla aynı.

Dönüş 1

voidDönüş yoksayılır.

Dinleyici PHP

```php
Hook::add('action:payment.subscription_member_removed', 10,
    function ($type, $id, $member, $sub, $history) {
        // 'Hangi anlasmadan cikti' sorusu eski degerde durur.
        Acme::detached($type, $id, (int) ($member['subscription_id'] ?? 0));
    });
```

## Tuzaklar

> **Uzlaşma "para geldi" demek değildir**
> 
> Uzlaşma kaydında durum **beklemede** olabilir: kuruluş işlemi almış ama kesinleştirmemiştir. Bu durumu kontrol etmeden hizmet açan bir dinleyici, sonradan başarısız olan bir ödeme için **bedava hizmet** vermiş olur.

> **Geri bildirimde kayıt boş olabilir**
> 
> Modül bildirimi bir ödeme kaydına bağlayamazsa kanca **boş bir dizi** alır. Bu, sahte ya da eşleşmeyen bir bildirim demektir. Ayrıca aynı bildirim **tekrar** gelebilir; sonuçtaki "daha önce işlendi" işaretini kontrol etmeyen dinleyici işi çiftler.

> **Kart numarası hiçbir kancaya gelmez**
> 
> Saklı kart kancaları **yalnız gösterim bilgisi** taşır: son dört hane, marka, son kullanma. Numara, güvenlik kodu ve kuruluş anahtarı bize hiç gelmez. Kart üzerinden karar veren bir kural yazamazsınız; kararınızı **hesap** üzerinden kurun.

> **Tarayıcı dönüşü güvenilir bir sinyal değildir**
> 
> Geri bildirim **sunucudan** gelmişse ödeme kuruluşu konuşuyordur. Tarayıcıdan geldiyse müşteri o sayfayı hiç açmamış olabilir — kapatmış, ağı kopmuş, yönlendirmeyi kaçırmış olabilir. Paraya bağlı işi **sunucu bildirimine** dayandırın.

## İlgili Makaleler

- [Ödeme Kancaları](https://dev.wisecp.com/tr/odeme-kancalari)
- [Fatura Yaşam Döngüsü Kancaları](https://dev.wisecp.com/tr/fatura-yasam-dongusu-kancalari)
- Sipariş Akışı Kancaları
