After integrating Stripe, Reepay and Fenerum into production Laravel and Node.js systems, the same few problems come up every time. Here is what I do now.
1. Never trust the redirect
Confirm payment state only through signed webhooks, and make your handlers idempotent so a retried event cannot create a second order. Store the gateway event id and verify the signature before touching your database.
2. Queue the slow work
With Redis and Bull in Node.js, or Laravel queues, webhook endpoints answer in milliseconds and the heavy processing happens in a worker with retries.
3. Design for failure from day one
Refunds, expired cards, disputes and subscription renewals are where real money is lost. Model them as first-class states, not edge cases.
4. Log every state transition
Support should be able to answer a customer without reading code.
About me
I am Faisal Nadeem, a full-stack and AI integration engineer in Lahore, Pakistan. I share case studies from client work at https://faisalnadeem.net and you can reach me there for payment integration or RAG pipeline projects.
Top comments (1)
Never trust the redirect is the lesson every gateway integration re-learns, but the quiet extension is that you also never trust your own webhook handler the first time it fires: signature verification and idempotency have to survive a replayed event from last week, not just a duplicate from five minutes ago. The 'support should be able to answer a customer without reading code' test for state-transition logging is a better acceptance criterion than any logging library debate. Out of curiosity, did the Reepay and Fenerum integrations share one internal event model, or did each gateway's vocabulary leak into your domain tables?