My Stripe Connect payout bounced and thMenu did not notify me — payout.failed webhook (PR #565 TT F4)
Hanna Hamburg Sankt Pauli 35-yo 6-yr freelance growth marketing consultancy 4-yr Otto SE digital growth team + 2-yr independent mid-sized German retail SaaS thMenu affiliate 11 months 14 restaurants €310/month commission Stripe Connect Deutsche Bank business monthly automatic 1st. Monday end-of-month €316 sent 5 days ago thMenu affiliate dashboard never landed Deutsche Bank no €316 7 days. Deutsche Bank callcenter negative. Stripe Connect Express dashboard €316 status: failed failure_message account_holder_information_mismatch beneficiary name does not match bank record Hanna Schmidt Stripe vs Hanna Verena Schmidt Deutsche Bank IBAN verification name mismatch payout failed. thMenu hadn't notified dashboard sent silent stuck. Support email Stripe Connect payout failed thMenu shows sent webhook handler payout.failed delivered. Engineering 1 hour Stripe Connect Dashboard webhook delivery log payout.failed 5 days ago delivered thMenu Connect handler 200 OK audit log default branch. apps/web-admin/src/app/api/stripe/connect/webhook/route.ts 5 events account.updated + account.application.authorized + deauthorized + payout.paid + payout.created. payout.failed + payout.canceled + capability.updated missing. 3 wrong theories (1) Stripe Connect webhook secret expired/wrong signature verified 200 OK secret OK; (2) payout.paid handler also fires payout.failed explicit event.type === 'payout.paid' check; (3) Connect default branch DLT entry main webhook PR #606 CCC F4 [BEACON:stripe_webhook_unhandled] + DLT info Connect webhook none silent 200 OK. Correct pattern 3 missing event + default branch beacon + DLT info row. 90-day Stripe Connect Dashboard delivered (a) payout.failed 7 affiliates 9 events all silent 200 OK 9 payouts not reached dashboard sent €280 × 9 = €2520 stuck; (b) payout.canceled 2 affiliates 2 events rarer manual cancel same silent; (c) capability.updated 12 affiliates Stripe Connect capability status change KYC re-verification card_payments temporarily inactive thMenu displayed payments enabled every PI 402 12 affiliates confused customers not converting Stripe Connect real status not reflected. Total 21 affiliates × 23 missing events silent gaps 2-7 days delay manual Stripe Dashboard discovery. PR #565 batch TT F4 3 new cases Case 1 payout.failed SELECT affiliate_id WHERE stripe_connect_account_id + UPDATE affiliate_payouts SET status=failed failure_code failure_message WHERE stripe_payout_id + DLT info row connect_payout_failed + sendPayoutFailedEmail Payout failed Reason failure_message update bank info Connect dashboard or contact support. Case 2 payout.canceled same flow sendPayoutCanceledEmail Contact support reissue. Case 3 capability.updated event.data.object.status active/inactive/pending UPDATE affiliate_profiles SET connect_capabilities_status + dashboard widget refresh + sendCapabilityChangeEmail card_payments inactive KYC re-verification. Bonus default branch [BEACON:stripe_connect_webhook_unhandled] Sentry beacon + DLT info row main webhook PR #606 CCC F4 pattern Connect webhook extends new event types surface coverage gaps not silent 200 OK. Hanna's case Stripe Connect Express dashboard direct link name field Hanna Verena Schmidt matching Deutsche Bank updated retry queued 2 days €316 Deutsche Bank. 21 affected affiliates personal outreach + Stripe direct link + manual reissue 1 week resolve 7 Hall of Fame + 3-month Pro discount. Hanna LinkedIn 36 hours fix + auto-reissue affiliate-marketing community disclosure benchmark Hamburg keeps going 3.4k. Beren Izmir Cigli 32-yo 4-yr @beren-grow growth marketing thMenu affiliate 14 months 17 restaurants Yapı Kredi Beren Selin Erdem vs Beren Erdem mismatch parallel disclosure same fix + 3-month Pro discount + Hall of Fame. Pattern Stripe Connect webhook handler (separate endpoint from main) explicitly handle every payout-affecting + capability-affecting event default branch must not silent 200 OK [BEACON:stripe_connect_webhook_unhandled] + DLT info row. Stripe Connect lifecycle events (a) account.* 3 existing; (b) capability.updated PR #565 TT F4; (c) payout.* failed/canceled missing closed PR #565 TT F4; (d) external_account.created/updated bank info changes future TT-B; (e) person.updated KYC representative changes future TT-B; (f) transfer.* Phase 2. Sibling-surface parity main + Connect same pattern + DLT + email + cache invalidate. Implementation enumerate Stripe Connect Dashboard webhook coverage + handled vs default ratio + every event explicit case + default branch [BEACON:] + DLT info + 90-day silent-gap backfill + PR template checkbox + quarterly audit. PR #565 reference.
thMenu Team
thmenu.com
Found this helpful? Share it.
Related articles
Why Digital Menus Increase Restaurant Revenue by Up to 30%
Studies show restaurants using digital QR menus see measurable increases in aver…
When a Customer Downgrades, What Happens to Old Features? — The Silent Feature-Drift Problem in SaaS
Most SaaS apps run a single line of code when a customer downgrades — but old fe…
JWT alg-confusion attack — why Supabase's HS256 → RS256/JWKS migration breaks legacy verifiers
Verifiers that never decode the JWT header are wide open to `alg=none` and alg-c…