Faturalar

1.6k görüntülenme Markdown

Faturaları gören, okuyan, ödeyen ve kupon uygulayan dört uç.

Genel Bakış

Fatura, hesabın borç belgesidir. Sipariş, yenileme ve bakiye yüklemesi hepsi fatura keser; ödeme de fatura üzerinden yapılır.

Her faturanın iki durumu vardır: kayıttaki ham durum ve müşteriye gösterilen durum. İkincisi vade tarihini de hesaba katar, yani ödenmemiş bir fatura vadesi geçtiğinde ayrı bir değer alır.

Ödeme burada da dar tutulmuştur: hesap bakiyesi ya da kayıtlı kart. Tarayıcı adımı isteyen ödeme yolları, kısmi ödeme ve havale bildirimi panelde kalır.

Referans

Faturaları Listeleme

get/api/v1/client/invoices
Invoices/GetInvoices aciliyet sırası

Hesabın faturalarını aciliyet sırasıyla döndürür.

Sorgu 6
pageintKaçıncı sayfa.
limitintSayfa başına satır. En çok 100.
statusstringDurum süzgeci. Müşteriye gösterilen durum sözlüğünü kabul eder.
searchstringFatura numarasında ve ilk kalemin açıklamasında arar.
sortstringSıralama alanı: kesim, vade ya da tutar. Verilmezse aciliyet sırası kullanılır.
dirstringSıralama yönü. Yalnız sıralama alanıyla birlikte çalışır.
Dönen alanlar data[] — 9 + meta — 4
invoice_idintFaturanın numarası.
numberstringGörünen fatura numarası.
statusstringHam durum.
statestringMüşteriye gösterilen durum. Ham durumdan ve vade tarihinden türetilir; vadesi geçen açık fatura ayrı bir değer alır.
totalobjectBelge toplamı. Kendi para birimindedir.
created_atstringKesim tarihi.
paid_atstringÖdenme tarihi.
due_datestringVade tarihi.
first_itemstringİlk kalemin açıklaması. Faturanın ne için olduğunu hızlıca söyler.
amount_dueobjectÖdenmesi kalan tutar; tutar ve para birimi. Toplamdan kayıtlı ödemeler düşülür; ödenmiş faturada 0.
total_countintToplam fatura. Meta altında toplam adıyla döner.
pageintBulunulan sayfa.
limitintSayfa boyutu.
next_pageintSonraki sayfa.
Hatalar 2
status_invalid422Durum bilinen bir değer değil.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/client/invoices?status=overdue' \
  -H "Authorization: Bearer $CLIENT_KEY"
const res = await fetch('https://panel.ornek.com/api/v1/client/invoices?status=overdue', {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data, meta } = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/client/invoices?status=overdue');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Iki durum alani vardir: suzgec MUSTERI durumunu alir, ham durum vadesi gecmisi ayirmaz.
$rows = Kernel::internal('client:Invoices/GetInvoices',
    ['owner_id' => $uid, 'status' => 'overdue'])['data'];

Faturayı Okuma

get/api/v1/client/invoices/{id}
Invoices/GetInvoice kesim anı saklanır

Faturanın kalemlerini, müşteri kaydını, özetini ve ödemelerini döndürür.

Dönen alanlar data — 17
invoice_idintFaturanın numarası.
numberstringGörünen fatura numarası.
statusstringHam durum.
statestringMüşteriye gösterilen durum. Ham durumdan ve vade tarihinden türetilir; vadesi geçen açık fatura ayrı bir değer alır.
totalobjectBelge toplamı. Kendi para birimindedir.
created_atstringKesim tarihi.
paid_atstringÖdenme tarihi.
due_datestringVade tarihi.
amount_dueobjectHâlâ açık tutar. Kapanınca sıfır olur.
payableboolÖdeme ucuna verilebilir mi.
subscription_lockedboolBir abonelik bu faturayı tahsil ediyor mu. Öyleyse elle ödeme reddedilir.
notesstringBelgedeki operatör notları.
billed_toobjectFaturanın üzerinde saklanan müşteri kaydı. Profil sonradan değişse bile kesim anındaki bilgileri taşır: tür, ad, ilgili kişi, e-posta, vergi numarası, kimlik numarası ve adres.
custom_fieldsobject[]Operatörün faturada göstermeyi seçtiği ek alanlar.
itemsobject[]Fatura kalemleri.
item_idintKalemin numarası.
parent_item_idintÜst kalemin numarası. Ek hizmet kalemlerinde dolar.
descriptionstringKalem açıklaması.
eventstringKalemi yazan akış. Elle girilen kalemde boş gelir.
service_idintFaturalanan hizmetin numarası.
cyclestringFaturalama döngüsü.
period_startstringKapsanan dönemin başı. Eski belgelerde boş olabilir.
period_endstringKapsanan dönemin sonu.
domainstringKalemin ilgili olduğu alan adı.
quantityintAdet.
unit_priceobjectBirim tutar.
totalobjectKalem toplamı.
summaryobjectPara özeti.
subtotalobjectKalem ara toplamı.
discountsobjectİndirimler. Bayi indirimi ve uygulanmış kuponu taşır.
taxobjectVergi satırı. Oran ve tutar taşır.
payment_feeobjectSeçilen yöntemin komisyonu.
installmentobjectTaksit planı. Taksit sayısı ve farkı taşır.
totalobjectBelge toplamı.
paidobjectBugüne kadar ödenen.
amount_dueobjectHâlâ açık tutar.
transactionsobject[]Kapanmış para hareketleri. Tür, yöntem, sağlayıcı referansı, tutar ve tarih taşır; başarısız denemeler saklanmaz.
bank_transferobjectOnay bekleyen havale bildirimi. Banka adı, gönderen ve referans taşır.
Hatalar 2
not_found404Böyle bir fatura yok, başka bir müşteriye ait ya da taslak.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/client/invoices/1193' \
  -H "Authorization: Bearer $CLIENT_KEY"
const res = await fetch(`https://panel.ornek.com/api/v1/client/invoices/${id}`, {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data } = await res.json();
if (data.payable && ! data.subscription_locked) enablePayButton();
$ch = curl_init('https://panel.ornek.com/api/v1/client/invoices/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Faturadaki musteri kaydi KESIM ANININ fotografidir; guncel profille karsilastirip duzeltmeye calismayin.
$inv = Kernel::internal('client:Invoices/GetInvoice', ['owner_id' => $uid, 'id' => $id])['data'];
$thenAddress = $inv['billed_to']['address'];

Faturayı Ödeme

post/api/v1/client/invoices/{id}/pay
Invoices/PayInvoice bakiye ya da kayıtlı kart

Açık bir faturayı bakiyeyle ya da kayıtlı kartla kapatır.

Gövde 1
paymentobjectreqÖdeme kaynağı.
methodstringreqÖdeme yolu: hesap bakiyesi ya da kayıtlı kart.
card_idintÇekilecek kartın numarası. Verilmezse hesabın varsayılan kartı çekilir.
Dönen alanlar data — 2
invoiceobjectFaturanın taze özeti. Numara, durum, toplam, açık tutar ve tarihleri taşır.
paymentobjectÇekimin sonucu.
methodstringKullanılan yol.
statusstringÖdendi mi düştü mü. Düşmesi yalnız kart reddinde olur.
cardobjectÇekilen kartın numarası ve son dört hanesi.
transaction_idstringSağlayıcının işlem referansı.
errorstringReddin gerekçesi.
Hatalar 10
not_found404Böyle bir fatura yok, başka bir müşteriye ait ya da taslak.
invoice_not_payable422Fatura açık değil ya da ödenecek tutar kalmamış.
subscription_collects422Bir abonelik bu faturayı tahsil ediyor.
payment_method_invalid422Ödeme yolu iki değerden biri değil.
balance_not_allowed422Bakiye yükleme faturası cüzdanla ödenemez.
insufficient_balance422Cüzdan komisyon dahil tutarı karşılamıyor. Gerekli ve eldeki tutar yanıtın ayrıntısında gelir.
no_stored_card422Kart seçilmemiş ve varsayılan kart yok.
card_expired422Kayıtlı kartın süresi dolmuş.
card_not_chargeable422Kartın sağlayıcısı tarayıcı adımı istiyor.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/client/invoices/1193/pay' \
  -H "Authorization: Bearer $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"payment":{"method":"balance"}}'
const res = await fetch(`https://panel.ornek.com/api/v1/client/invoices/${id}/pay`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${clientKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ payment: { method: 'card' } }),
});

const { data } = await res.json();
if (data.payment.status === 'failed') showError(data.payment.error);
$ch = curl_init('https://panel.ornek.com/api/v1/client/invoices/' . $id . '/pay');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $clientKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['payment' => ['method' => 'balance']]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// KART REDDI hata degildir: yanit basarili doner, fatura komisyonuyla acik kalir, durumu okuyun.
$r = Kernel::internal('client:Invoices/PayInvoice',
    ['owner_id' => $uid, 'id' => $id, 'payment' => ['method' => 'card']])['data'];

if ($r['payment']['status'] === 'failed') $retryLater($id);

Faturaya Kupon Uygulama

post/api/v1/client/invoices/{id}/coupon
Invoices/ApplyInvoiceCoupon belge başına tek kupon

Açık bir faturaya kupon uygular ve belgeyi yeniden fiyatlar.

Gövde 1
codestringreqKupon kodu.
Dönen alanlar data — 3
invoiceobjectYeniden fiyatlanmış belge özeti.
couponobjectUygulanan kupon.
discountobjectBu belgede tanınan indirim.
Hatalar 8
not_found404Böyle bir fatura yok, başka bir müşteriye ait ya da taslak.
invoice_not_payable422Fatura açık değil.
coupon_code_required422Kod gönderilmemiş.
coupon_invalid422Böyle bir kupon yok.
coupon_not_invoice422Kupon faturalarda kullanılamaz.
coupon_used422Bu belgeye zaten bir kupon uygulanmış.
coupon_scope422Kupon bu faturadaki kalemlere uygulanamıyor.
coupon_rejected422Kupon motoru reddetti. Gerekçe mesajda gelir.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/client/invoices/1193/coupon' \
  -H "Authorization: Bearer $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"code":"WELCOME10"}'
const res = await fetch(`https://panel.ornek.com/api/v1/client/invoices/${id}/coupon`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${clientKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ code }),
});

const { data } = await res.json();
showNewTotal(data.invoice.total, data.discount);
$ch = curl_init('https://panel.ornek.com/api/v1/client/invoices/' . $id . '/coupon');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $clientKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['code' => $code]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Kuponu ODEMEDEN ONCE uygulayin: belge kapandiktan sonra degistirilemez, iade yolu yoktur.
Kernel::internal('client:Invoices/ApplyInvoiceCoupon',
    ['owner_id' => $uid, 'id' => $id, 'code' => $code]);

Kernel::internal('client:Invoices/PayInvoice',
    ['owner_id' => $uid, 'id' => $id, 'payment' => ['method' => 'balance']]);

Tuzaklar

Reddedilen kart hata döndürmez

Ödeme ucu kart reddedildiğinde de başarılı yanıt verir: fatura açık kalır ve seçilen yöntemin komisyonu belgenin üzerinde durur. Sonucu yanıttaki ödeme durumundan okuyun. Aynı faturayı başka bir yöntemle ödemeye kalkarsanız komisyon farkını da hesaba katın.

Abonelik tahsil ediyorsa elle ödeme reddedilir

Bir ödeme sağlayıcısı aboneliği bu faturayı tahsil ediyorsa ödeme ucu reddeder. Bu bir hata değil, çifte tahsilata karşı bir kapıdır. Detaydaki abonelik alanını okuyup ödeme butonunu kapatın; elle ödemek için önce aboneliği iptal etmek gerekir.

Faturadaki müşteri bilgisi kesim anına aittir

Fatura, müşteri kaydını üzerinde saklar: adres, vergi numarası ve unvan kesim anındaki hâliyle durur. Profil sonradan değişse belge değişmez, çünkü resmi bir kayıttır. Güncel profille karşılaştırıp tutarsızlık raporlamayın.

Belge başına tek kupon, ödemeden önce

Bir faturaya yalnız bir kupon uygulanır ve bu ancak belge açıkken olur. Ödendikten sonra kupon uygulamak reddedilir, geri alma yolu da yoktur. Kupon deneyecekseniz ödeme çağrısından önce yapın.

Bakiye yükleme faturası cüzdanla ödenmez

Cüzdana para yüklemek için kesilen fatura cüzdanla ödenemez; döngüsel olurdu. Bu fatura kayıtlı kartla ya da panelden ödenir. Genel bir ödeme akışı yazıyorsanız bu hatayı ayrı ele alın.

İki durum alanı aynı şeyi söylemez

Ham durum kayıttaki değerdir; müşteriye gösterilen durum vade tarihini de hesaba katar. Ödenmemiş bir fatura vadesi geçtiğinde yalnız ikincisi değişir. Süzgeç müşteri durumunu alır, yani vadesi geçenleri ham durumla arayamazsınız.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.