# Fatura Kalemleri ve Ödemeler

https://dev.wisecp.com/tr/fatura-kalemleri-ve-odemeler

Fatura kalemlerini düzenleyen, bölen ve ödeme kayıtlarını tutan dört uç.

## Genel Bakış

Bu dört uç faturanın **para tarafını** yürütür. İkisi kalemlerle ilgilenir: düzenlemek ve bir kısmını ayrı bir faturaya taşımak. İkisi de ödeme kayıtlarıyla.

Kalem yazma ucu **toplu çalışır**: aynı çağrıda kalem eklenir, güncellenir ve silinir. Bittiğinde toplamlar baştan hesaplanır, yani ara toplam, vergi ve genel toplam elle yazılmaz.

Ödeme kaydı faturanın durumuna **tek yönlü** etki eder: bakiye kapanınca fatura ödenmiş olur, ama bir ödemeyi silmek durumu geri çevirmez.

## Referans

### Kalemleri Yazma

put/api/v1/admin/invoices/{id}/items

`Invoices/UpdateInvoiceItems` admin toplamlar yeniden hesaplanır

Faturanın kalemlerini tek çağrıda ekler, günceller ve siler.

Gövde 3

itemsarrayİşlenecek kalemler. Numarası olan güncellenir, olmayan yeni kalem olarak eklenir.

deleted_idsint[]Silinecek kalem numaraları.

removed_discountsarrayKaldırılacak indirimler. Her girdi indirimin tipini ve bağlı olduğu kalemi taşır.

Kalem alanları items[] — 10

item_idintMevcut kalemin numarası. Verilmezse yeni kalem açılır.

descriptionstringreqKalemin açıklaması.

quantityintreqAdet.

amountfloatreqBirim tutar.

discountfloatKaleme özgü indirim değeri.

discount_typestringİndirimin tutar mı yüzde mi olduğu.

tax_ratefloatKaleme özgü vergi oranı. Boş bırakılırsa faturanın oranı kullanılır.

tax_exemptboolKalemi vergiden muaf tutar.

user_pidintBağlanacak hizmet.

oduedatestringKalemin dönem sonu.

Dönen alanlar data

dataobjectGüncel fatura. Toplamlar yeniden hesaplanmış hâlde gelir.

Hatalar 3

not_found404Fatura bulunamadı.

item_required422İşlem sonunda hiç kalem kalmıyor.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X PUT 'https://panel.ornek.com/api/v1/admin/invoices/1212/items' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"items":[{"item_id":2811,"description":"Hosting","quantity":1,"amount":12.5}],"deleted_ids":[2812]}'
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/admin/invoices/${id}/items`, {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    items: [
      { item_id: 2811, description: 'Hosting Plan', quantity: 1, amount: 12.5 },
      { description: 'Setup Fee', quantity: 1, amount: 5 },
    ],
    deleted_ids: [2812],
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/invoices/' . $id . '/items');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'items' => [
            ['item_id' => 2811, 'description' => 'Hosting Plan', 'quantity' => 1, 'amount' => 12.5],
            ['description' => 'Setup Fee', 'quantity' => 1, 'amount' => 5],
        ],
        'deleted_ids' => [2812],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Gondermediginiz mevcut kalem SILINMEZ; silmek icin numarasini silinecekler listesine koyun.
Api::Invoices()->UpdateInvoiceItems([
    'id'          => $id,
    'items'       => [['item_id' => 2811, 'description' => 'Hosting', 'quantity' => 1, 'amount' => 12.5]],
    'deleted_ids' => [2812],
]);
```

### Kalemleri Bölme

post/api/v1/admin/invoices/{id}/items/split

`Invoices/SplitInvoiceItems` admin yeni fatura açar

Seçtiğiniz kalemleri yeni bir faturaya taşır.

Gövde 1

item_idsint[]reqTaşınacak kalemler. Hepsi kaynak faturaya ait olmalı ve kaynakta en az bir kalem kalmalı.

Dönen alanlar data — 4

source_invoice_idintKaynak faturanın numarası.

new_invoice_idintAçılan faturanın numarası.

new_invoice_numberstring | nullYeni faturanın numarası. Henüz numara verilmediyse boştur.

moved_item_idsint[]Taşınan kalemler.

Hatalar 6

not_found404Fatura bulunamadı.

split_required422Hiç kalem seçilmedi.

no_items422Kalemler bu faturaya ait değil.

split_one_left422Kaynakta hiç kalem kalmıyor.

split_failed422Yeni fatura açılamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/admin/invoices/1228/items/split' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"item_ids":[2835]}'
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/admin/invoices/${id}/items/split`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ item_ids: [2835] }),
});

const { data } = await res.json();
console.log(data.new_invoice_id);
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/invoices/' . $id . '/items/split');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['item_ids' => [2835]]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Yeni fatura ODENMEMIS acilir ve musteriye kendiliginden BILDIRILMEZ.
$r = Api::Invoices()->SplitInvoiceItems(['id' => $id, 'item_ids' => $picked])['data'];
Api::Invoices()->SendInvoiceNotification([
    'id' => $r['new_invoice_id'], 'template' => 'invoice-created',
]);
```

### Ödeme Kaydetme

post/api/v1/admin/invoices/{id}/payments

`Invoices/AddInvoicePayment` admin bakiye biterse ödenir

Faturaya elle bir ödeme kaydı ekler.

Gövde 7

amountfloatreqÖdenen tutar. Sıfırdan büyük olmalı.

payment_methodstringreqÖdemenin nasıl alındığı.

currency_idintÖdemenin para birimi. Faturanınkinden farklıysa çevrilir.

transaction_idstringİşlem numarası. Aynı numarayla ikinci bir kayıt kabul edilmez.

descriptionstringÖdemenin açıklaması.

paid_atstringÖdemenin yapıldığı tarih.

feesfloatKesilen komisyon.

Dönen alanlar data + meta — 1

dataobjectGüncel fatura. Bakiye sıfırlandıysa durum ödenmiş olur.

payment_idintAçılan ödeme kaydının numarası. Meta altında döner.

Hatalar 5

not_found404Fatura bulunamadı.

invalid_amount422Tutar sıfır ya da altında.

method_required422Ödeme yöntemi verilmedi.

payment_rejected422Fatura zaten ödenmiş, işlem numarası tekrarlanmış ya da para birimi geçersiz.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/admin/invoices/1212/payments' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"amount":12.5,"payment_method":"Balance","transaction_id":"TXN-1042"}'
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/admin/invoices/${id}/payments`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amount: 12.5,
    payment_method: 'Balance',
    currency_id: 840,
    transaction_id: 'TXN-1042',
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/invoices/' . $id . '/payments');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount'         => 12.5,
        'payment_method' => 'Balance',
        'transaction_id' => 'TXN-1042',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Islem numarasi MUKERRERI onler; ag hatasinda cagriyi tekrarlamak ikinci kayit acmaz.
Api::Invoices()->AddInvoicePayment([
    'id'             => $id,
    'amount'         => 12.5,
    'payment_method' => 'Balance',
    'transaction_id' => $txn,
]);
```

### Ödemeyi Silme

delete/api/v1/admin/invoices/{id}/payments/{payment_id}

`Invoices/DeleteInvoicePayment` admin durum geri dönmez

Bir ödeme kaydını faturadan kaldırır.

Dönen alanlar data

dataobjectGüncel fatura. Ödenmiş tutar ve bakiye yeniden hesaplanır.

Hatalar 3

not_found404Ödeme bu faturada bulunamadı.

invalid_payment422Ödeme numarası geçersiz.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/invoices/1212/payments/31' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/admin/invoices/${id}/payments/${paymentId}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/invoices/' . $id . '/payments/' . $paymentId);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Fatura ODENMIS kalir: bakiye geri acilsa da durumu ayrica siz cevirmelisiniz.
Api::Invoices()->DeleteInvoicePayment(['id' => $id, 'payment_id' => $pid]);
Api::Invoices()->UpdateInvoiceStatus(['id' => $id, 'status' => 'unpaid']);
```

## Tuzaklar

> **Kalemi atlamak onu silmez**
> 
> Kalem yazma çağrısında göndermediğiniz mevcut bir kalem **yerinde kalır**. Silmek için numarasını silinecekler listesine koymanız gerekir. Faturanın kalem setini olduğu gibi gönderen bir betik, kaldırılan kalemleri kaldırmaz; iki listeyi karşılaştırıp farkı silinecekler listesine yazın.

> **Fatura kalemsiz kalamaz**
> 
> Hem kalem yazma hem bölme çağrısı, sonunda faturada **en az bir kalem** kalmasını ister. Bütün kalemleri silmeye ya da hepsini bölmeye çalışmak hata verir. Faturayı tümüyle kaldırmak istiyorsanız kalemlerini değil faturanın kendisini silin ya da iptal edin.

> **Toplamları elle yazmayın**
> 
> Kalem yazma çağrısı bittiğinde ara toplam, vergi ve genel toplam **yeniden hesaplanır**. Aynı anda fatura düzenleme ucundan toplam yazmaya çalışmak, iki kaynağın çekiştiği bir kayda yol açar. Toplamlar kalemlerden çıkar; onları değiştirmenin yolu kalemleri değiştirmektir.

> **Ödeme silmek durumu geri çevirmez**
> 
> Bakiye kapanınca fatura kendiliğinden ödenmiş olur, ama ödemeyi silmek aynı yolu **geri yürümez**: ödenmiş tutar ve bakiye yeniden hesaplanır, durum ödenmiş kalır. Yanlış girilmiş bir ödemeyi geri alırken durumu ayrıca ödenmemişe çevirmeniz gerekir.

> **Bölme yeni bir borç doğurur**
> 
> Bölme çağrısı ödenmemiş **yeni bir fatura** açar ve müşteriye bundan kendiliğinden haber vermez. Yani müşterinin haberi olmadan bir borcu daha olur. Bölmeden sonra yeni faturanın numarasını alıp bildirim gönderin; kaynak faturanın toplamı da düşeceği için iki belge de değişmiştir.

## İlgili Makaleler

- [Fatura Yönetimi](https://dev.wisecp.com/tr/fatura-yonetimi)
- [Fatura Durumu ve Bildirimleri](https://dev.wisecp.com/tr/fatura-durumu-ve-bildirimleri)
- [Kasa Kayıtları](https://dev.wisecp.com/tr/kasa-kayitlari)
