All work

React / Tailwind / Express / WebSockets / Payment Integration — 2025

Alabasterapp LTD

Alabasterapp is an e-commerce platform built around a single promise: everything sold on it is authentic. I worked on the storefront, and on the two things a plain React app could not do on its own — server-rendering product metadata so shared links preview properly, and a live chat channel for settling disputes over an item.

Alabasterapp LTD

Role

Frontend Engineer

Timeline

2025

Stack

React, Tailwind, Express, WebSockets, Payment Integration

The problem

Everything about the platform rests on a buyer believing a listing is genuine, and two things worked against that. Product links get shared constantly — WhatsApp, X, group chats — and a client-rendered storefront hands a social crawler an empty app shell, so a link meant to sell one specific product arrived as a blank preview card. And when a buyer did dispute an item, resolving it meant email threads and screenshots, with an admin trying to reconstruct the argument after the fact.

What I built

  • 01Built the customer-facing storefront in React and Tailwind — catalogue, product pages, search and cart.
  • 02Put an Express layer in front of the app that renders per-product metadata on the server, so a crawler following a shared product link gets real Open Graph tags — title, image, price — instead of the shell.
  • 03Built a WebSocket chat in the front end that puts an admin in the room with the parties to a product dispute, so it gets resolved as a conversation instead of a chain of forwarded emails.
  • 04Integrated the third-party payment gateway into checkout, with an order treated as paid only once the gateway's verified webhook confirmed it — never on the browser redirect alone.

Decisions

Render the metadata, don’t migrate the app

The obvious fix for empty link previews is to move the whole storefront onto a framework that renders on the server. That is a migration measured in weeks, to solve a problem that only affects what crawlers see — real users were already getting the full app. An Express layer that renders metadata for bot requests fixed the previews without anyone touching the React codebase.

I wrote this one up in full

A conversation, not a ticket queue

A dispute over whether an item is authentic is genuinely a conversation: one side has photos, the other has an explanation, and an admin has to weigh both. A ticket form flattens that into a queue and leaves the admin chasing context across replies. Putting everyone in a live thread keeps the evidence and the decision in one place, and lets the admin close it out while both parties are still there.

Trust the webhook, not the redirect

The quick way to confirm a payment is to believe the browser when the gateway redirects back with a success flag. It is also the easiest thing in the flow to forge, and it silently fails every time someone closes the tab mid-payment. Settling only on the gateway’s server-to-server webhook costs a moment of “pending” in the UI and removes an entire class of way it can go wrong.