TidyLinker.com
TypeScript
Pull Request Opened
PR #83 opened: feat: add payment verify endpoint as webhook fallback
Summary
- Adds a
POST /client/jobs/{job}/quotes/{quote}/payment/verifyendpoint that checks the PaymentIntent status directly with Stripe - Frontend calls this endpoint immediately after
stripe.confirmPayment()succeeds, so the local Payment record gets updated even if the webhook is delayed or lost - Best-effort call (silently catches failures) — webhooks remain the primary mechanism
Problem
After a client confirms payment via Stripe Elements, the payment status transition (pending → authorized) relied entirely on Stripe webhooks. If a webhook was delayed or lost, the UI would get stuck showing "Pay & Confirm" indefinitely.
Changes
- PaymentController: New
verify()method — retrieves PaymentIntent from Stripe, syncs local status (requires_capture→ authorized,canceled→ cancelled), skips Stripe call if already non-pending - routes/web.php: New route
client.jobs.quote.payment.verify - payment-form.tsx: POST to verify endpoint after
confirmPayment()succeeds - payment-dialog.tsx: Pass
verifyUrlprop via Wayfinder route - PaymentControllerTest: 6 new tests (authorized transition, already-authorized skip, 404, processing passthrough, cancelled transition, auth check)
Test plan
- All 12 PaymentController tests pass (6 existing + 6 new)
- Manual: confirm payment locally without
stripe listen→ page should show authorized state - Manual: confirm payment with
stripe listenrunning → verify is a no-op, webhook handles it
+368
additions
-115
deletions
12
files changed