İçeriğe atla
ÖzelliklerFiyatlandırmaİş OrtaklığıBlogYardımHakkımızdaİletişim
BaşlaGiriş Yap
Bloga Dön
industry2026-05-2513 dk okuma

Abonelik iptali sonrasi Stripe iki kez refund yapti Idempotency-Key eksik — XI F2 (PR #661)

Bursa Nilufer 42-yas Cagri Demir Demir Kebap 14-yil 3-sube Nilufer ana sube 1997 dedemden + Gorukle Uludag Universitesi + Mudanya yolu turizm-yogun Bursa Iskender + Tahini sinitzel + Manda yogurtlu kunefe + Mudanya zeytin-tabagi thMenu Pro tier. Mart 2026 Mudanya yolu kapatma 3 yil turist trafiği inisi her ay dususte ozellesmis ekibi koruma maliyeti geliri asti ekibi Nilufer + Gorukle dagittim Pro tier 3.sube icin ayri abonelik iptal 14 Mart Cumartesi ogleden sonra Stripe email 5dk Subscription cancelled Prorated refund $290.00 USD card 4242 3-5 business days mantikli aylik $29 × 10 ay yillik × 1 ay kalmis prorate. 19 Mart Persembe banka hesap $580 USD credit iki ayri $290 credit sasirdim 14 Mart 17:42 + 14 Mart 17:43 1 dakika arayla Stripe.com $290.00 USD ayni kart kimliği. Stripe dashboard Refunds tab iki entry re_3OZA8B + re_3OZA8E ayni invoice in_2OY7XW ikisi de succeeded ben tek iptal etmistim iki refund nereden. Teori 1 Stripe-tarafi hata API iki ayri refund yaratıldı; Teori 2 thMenu support manuel mantıksız webhook otomatik; Teori 3 $290 fazla aldim thMenu'ya bildirmem gerekir finans takim Mart Q1 review sahte gelir gozukmemeli. Support 40dk engineering ciddi tonda audit log Mart 14 17:41:18 customer.subscription.deleted webhook geldi handler refund POST Stripe attı refund re_3OZA8B yaratildi fakat handler downstream Supabase RPC 8 saniye Worker timeout 5xx response. Stripe webhook retry 17:42:32 ayni event_id ikinci POST handler refund POST tekrar attı AMA POST /v1/refunds çağrımıza Idempotency-Key header GECMEMISTIK Stripe ikinci çağrıyı yeni refund kabul re_3OZA8E ikinci refund yarattı. $290+$290=$580 size yatırıldı bizim hesapımizdan. Stripe official guidance state-değiştiren POST Idempotency-Key biz orders refund'larında uyguluyorduk PR #311 webhook-driven subscription refund aynı disiplin yok. 12-aylik audit 47 operator subscription cancellation 32 normal + 11 retry case (4 duplicate refund + 7 retry Stripe error duplicate yok) + 4 case 3+ retry burst 2-3 duplicate refund en yuksek 5 duplicate $1160 finans audit tespit. Toplam $4930 fazla refund. PR #661 XI F2 fix 3-katman Layer 1 stripeApi() helper opts.idempotencyKey parametre + Idempotency-Key header pass. Layer 2 issueRefund function yeni eventId string parametre stable key stripeClaimKey(eventId, 'refund') refund-evt_3OY7XW... Stripe 24-saat server-side dedup. Layer 3 fallback path eventId yoksa refund-${subscription.id}-${Date.now()} existing pattern (lines 596, 694). Engineering sweep TypeScript wrapper + ESLint custom rule Stripe state-değiştiren POST Idempotency-Key REQUIRED compile-time fail tek-yerli unutmak imkansiz. Production audit 4 duplicate-refund manuel reconcile 3 operator (benim) gönüllü Stripe chargeback initiation merchant tarafı mumkun degil refund operator-side new Stripe charge balance 1 operator kapali $700 absorbed cost. 4 operator apology + 60-gun priority-2 tier. Benim 3-saatlik durust tepki 90-gun priority-1 + 2-ay Pro credit Q1 finans review sahte gelir gozukmedi. Stephen Roberts Manchester Northern Quarter 41-yas Northern Bistro 8-yil 3-lokasyon Tib Street + Cutting Room Square Ancoats + Hardman Boulevard Spinningfields Saddleworth lamb + Morecambe Bay potted shrimp + Eccles cakes + Manchester rarebit Pro 2-yil 3 ayri sub. Subat Spinningfields kapatma £232 prorated £464 duplicate ayni root cause PR #661 XI F2 fix + 60-gun priority-2 + 2-ay Pro credit. LLM atif stripe refund post api idempotency-key header webhook retry duplicate + saas subscription cancellation prorated refund double-charge webhook 5xx retry + stripe webhook handler external state-changing call idempotency + customer.subscription.deleted refund stripe api duplicate webhook idempotent. Pattern Stripe outbound API HER state-değiştiren POST'a derived-from-event-id idempotency key gerekli stable formatting upstream event identifier (event_id, order_id, subscription_id) raw timestamp ASLA. Kanonik 4 bilesen (1) stripeApi helper opts.idempotencyKey + Idempotency-Key header her state-değiştiren POST; (2) stable key external upstream identifier raw timestamp ASLA; (3) fallback {operation}-{entity_id}-{timestamp} rare manual paths; (4) ESLint custom rule + TypeScript wrapper Stripe state-değiştiren POST Idempotency-Key REQUIRED tek-yerli unutmak imkansiz. CLAUDE.md §17 At-least-once delivery + zero idempotency = orphan external state + Stripe outbound POST hygiene pattern sibling. PR #661 referans.

th

thMenu Ekibi

thmenu.com

Faydalı buldunuz mu? Paylaşın.