Prince of Code </>

Back to blog
·5 min read

Integrating payments into a web application

A payment integration is more than displaying a pay button: you need to handle statuses, errors and security.

PaiementStripeE-commerce

Payment on the user side

The client experience must be smooth: a clear form, real-time feedback, card error handling and a clean redirect. Stripe Elements or Checkout handle the sensitive part (card numbers) without your servers ever touching raw banking data.

Webhooks

The real challenge of a payment integration is server-side. Stripe notifies your backend via webhooks when an event occurs: successful payment, refund, dispute. You need to listen, validate the signature and update the order state idempotently.

Order statuses

An order goes through several states: pending, processing, paid, failed, refunded. Modelling these transitions clearly in your database is essential to avoid ghost orders or double shipments.

Security and traceability

Always validate the webhook signature, log every event and make your handlers idempotent. In case of a Stripe retry, the same event must not trigger the same action twice.

typescript
app.post("/webhook", async (req, res) => {
  const event = req.body;

  if (event.type === "checkout.session.completed") {
    await updateOrderStatus(event.data.object.id, "paid");
  }

  res.status(200).json({ received: true });
});