fix(odeme): önce kredi sonra paid damgası; çift pakette iade akışı; UNIQUE tespiti
All checks were successful
Deploy / deploy (push) Successful in 8m50s

- odemeyiSonuclandir krediyi yazıp sonra paid damgalar; araya kesinti girerse
  sipariş pending kalır ve yeniden denenir (eskiden: paid görünür, kredi yok).
  paid + deftersiz eski siparişler ilk ziyarette onarılır
- paket tek seferlik: grantCredits({ paketTekil }) zaten paketliye yazmaz
  (kontrol UPDATE'in WHERE'inde). Sipariş paid damgalanır, senkron log +
  destek@ e-postası, /odeme/sonuc 'Bu ödeme iade edilecek' kartı, /kosullar#iade
- drizzle DrizzleQueryError üst mesajında 'UNIQUE' yok → idempotent no-op yerine
  hata fırlıyordu (grant + iki spend yolu); cause zincirine bakılıyor
- callback geçici DB hatasında 500 yerine sonuç sayfasına yönlendirir
- krediKaydiVarMi (reason, ref_id) indeksini kullanır; haftalık mutabakat sorgusu

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-09-21 16:36:24 +03:00
parent 8f4669e31d
commit 024a2a49c4
6 changed files with 240 additions and 26 deletions

View File

@@ -66,6 +66,25 @@ Ayrıntı: `src/lib/app-url.ts`.
`paid`'e döner. Para çekildiyse kredi mutlaka tanımlanır.
- **Tutar kontrolü**: `paidPrice` sipariş tutarıyla eşleşmiyorsa kredi otomatik
tanımlanmaz, log'a düşer.
- **Önce kredi, sonra `paid` damgası.** `odemeyiSonuclandir` krediyi yazıp
ardından siparişi `paid` yapar. Ters sırada araya kesinti girerse sipariş
`paid` görünür ama kredi hiç yazılmaz. `paid` görülen ama defterde kaydı
olmayan siparişte kredi yeniden denenir (eski kayıpların onarımı).
- **Çift paket = iade (Bilal kararı, 21.09.2026).** Paket tek seferliktir:
`grantCredits({ paketTekil })` kullanıcı zaten paketliyse yazmaz
(`neden: "zaten-paketli"`, kontrol bakiye UPDATE'inin WHERE'inde → eşzamanlı
iki ödemede de tek paket). Sipariş yine `paid` damgalanır, `odeme_tamamlandi`
atılmaz, `destek@kolaytercih.com`'a "İade gerekli" e-postası gider ve
`/odeme/sonuc` "Bu ödeme iade edilecek" kartını gösterir
(`iadeEdilecekMi`: paid + paket + defterde kayıt yok). **İade otomatik
DEĞİL**: iyzico panelinden elle yapılır. İade sonrası defter satırı silinmez;
gerekirse ters kayıt atılır.
- **Haftalık mutabakat (salt okunur).** Ödenmiş ama kredisi yazılmamış siparişler:
`SELECT o.id, o.user_id, u.has_paket FROM orders o JOIN user u ON u.id=o.user_id
LEFT JOIN credit_ledger l ON l.ref_id=o.id AND l.reason IN ('purchase','topup')
WHERE o.status='paid' AND l.id IS NULL;` — `has_paket=0` satırlar kullanıcının
ilk `/odeme/sonuc` ziyaretinde kendiliğinden onarılır; `has_paket=1` satırlar
iade bekleyen çift paket ödemesidir (e-posta kaçmış olabilir → elle iade et).
## İmza doğrulaması