OverPowered International

OverPowered International

E-commerce ·May 2025 → ongoing ·paused

OPI Tech

The company's own electronics storefront, built from the database up: card payments in a market the provider does not serve, store credit honoured in the same transaction as the order, and a checkout that makes three services fire in the right order.

[ COVER ]
Deployment: paused Work: ongoing
Timeframe
May 2025 → ongoing
Tags
E-commerce · next.js · stripe · retention
Credits
Xern Mottley — Engineer

Where it started

OPI Tech is the company's own electronics line, and the storefront is the side project that kept coming back. Several earlier versions ran on hosted platforms — Shopify, WooCommerce and the like — and none of them did what the business needed: sell electronics in Trinidad and Tobago, streamline the process behind a sale, and keep the customer afterwards.

Two things in particular. Accepting a card online: Stripe, the provider with the developer tools the build wanted, does not operate in Trinidad and Tobago. And a checkout that does not leak — one where the payment, the order, the stock, the customer's credit and the confirmation all agree, every time, with the customer seeing none of the seams.

[ PAYMENT PATH ]
Priced in TTD, charged in USD Four steps left to right: the customer sees every price in TTD; when a payment intent is created the total is converted at a live rate and refused below the card minimum; Stripe charges the card in USD with the intent carrying the cart and the rate used; the money settles to banking arranged abroad, because the provider does not operate in Trinidad and Tobago. Cash on delivery and store credit never leave TTD. PRICED IN TTD, CHARGED IN USD · HOW A CARD PAYMENT TRAVELS card payments the customer sees TTD every price, the cart, the summary, the confirmation, the delivery rates — one currency on every surface a live rate, per intent the total is converted when the payment intent is created; the rate is cached four hours with a fixed fallback; below the card minimum the checkout refuses Stripe charges in USD the card is confirmed in the browser; the intent carries the cart and the rate it used, so the charge can always be reconciled to the order settled abroad the provider does not operate in Trinidad and Tobago; banking it could connect to was arranged before a line of code CASH ON DELIVERY and STORE CREDIT never leave TTD — no intent, no conversion, nothing crosses a border THE DECISION BEFORE THE CODE: THE PROVIDER WITH THE DEVELOPER TOOLS, AND THE BANKING IT NEEDED

Priced in TTD, charged in USD. Every price the customer sees is in their currency; when a payment intent is created the total is converted at a live rate, refused below the card minimum, and charged by Stripe in its own — settled to banking arranged abroad, because the provider does not operate in Trinidad and Tobago. The checkout says the bank statement may differ slightly. Cash on delivery and store credit never leave TTD.

What was done

A storefront and its administration, on one schema, from the database up.

A catalogue with variants, brands and categories. A cart that works for a guest and for a signed-in customer. Delivery by island, with addresses chosen from a Trinidad-and-Tobago location list, delivery methods that each say whether cash on delivery is allowed, and free delivery on a first order. Prices in the customer's currency, with the card charged in the provider's at a live rate — and the checkout says so.

Payment through Stripe, which meant a decision before a line of code: the provider does not operate here, so accepting a card online meant arranging banking abroad that it could connect to. The alternatives were researched; Stripe was chosen for its developer options and how far it could be customised.

Then the layer that keeps a customer. Store credit, with a balance and a ledger that records the balance before and after every movement, arriving for four reasons and spent inside the order's own transaction.

[ STORE CREDIT ]
Store credit: where it comes from, and where it goes Four sources on the left — a refund of a cash-on-delivery order, a referral signup bonus issued after email verification, a delivery reward of one and a half percent to the purchaser and three to the referrer, as configured on the admin surface, and an administrator's adjustment — feed one balance per customer in the centre, kept with an activity log that records the balance before and after every movement. Three uses on the right: part or all of a checkout, deducted inside the order's own transaction; expiry on a rolling year; and refunds, where card orders go back to the card and only cash-on-delivery refunds become credit. STORE CREDIT · WHERE IT COMES FROM, AND WHERE IT GOES IN OUT a refund of a cash-on-delivery order the default for orders that were never paid by card a referral signup bonus to both parties — issued only after the new account's email is verified a delivery reward 1.5% to the purchaser and 3% to the referrer as configured, once the order is delivered and above a minimum an adjustment by an administrator with a source and a description, from the customer's own record ONE BALANCE PER CUSTOMER the balance, and a ledger every movement is a row with the balance before and after it — credit, debit, expiry, adjustment — so a balance can always be recomputed from its history a customer sees it in the header and on their account page part or all of a checkout deducted inside the order's own transaction — never after it expiry unused credit lapses on a rolling year a refund back a card order refunds to the card; only cash-on-delivery refunds become credit THE RETENTION MECHANISM, DRAWN: CREDIT ARRIVES FOR FOUR REASONS AND IS HONOURED IN THE SAME TRANSACTION AS THE ORDER

Where credit comes from and where it goes. Four sources — a cash-on-delivery refund, a referral bonus after verification, a delivery reward, an administrator's adjustment — into one balance with a ledger that records the balance before and after every movement; out through a checkout, an expiry, or a refund.

[ SCREENSHOT ]
Store credit as the customer sees it: the balance, each credit with its rolling one-year expiry, and the ledger of every movement with the balance after it — a demonstration account, credited by an administrator's adjustment.

Store credit as the customer sees it: the balance, each credit with its rolling one-year expiry, and the ledger of every movement with the balance after it — a demonstration account, credited by an administrator's adjustment.

A referral programme with its integrity in the schema — no self-referral, one referee per link, a bonus issued only after the new account's email is verified, and a delivery reward to both parties once an order arrives. Reviews that only a verified purchaser may write, moderated before they show.

Twelve transactional emails, from the order's confirmation to a review request, with abandoned-cart reminders at twenty-four and forty-eight hours that check, at the moment of sending, whether the cart is still abandoned.

[ COMMUNICATIONS ]
Twelve emails, and what sends them Twelve transactional email templates grouped by what triggers them: seven for an order's status changes, one to verify an account, two referral bonuses sent after verification, one review request to verified purchasers after delivery, and two abandoned-cart emails scheduled at twenty-four and forty-eight hours that are only sent if the cart is still abandoned at send time. Beneath, the delivery-status strip: the provider reports sent, delivered, bounced or complained, and a complaint switches that customer's marketing email off. TWELVE EMAILS, AND WHAT SENDS THEM THE ORDEReach status change confirmation processing shipped delivered cancelled refunded reward credit earned THE ACCOUNTon signup verify your email REFERRALSafter verification signup bonus, to the new customer signup bonus, to the referrer REVIEWSafter delivery review request — verified purchasers only THE CART24 h and 48 h after it was left abandoned cart, first abandoned cart, second sent only if the cart is still abandoned when the time comes: a converted or changed cart is skipped — checked at send time, not at scheduling AFTER SENDING the provider reports back by webhook: sent · delivered · bounced · complained each is written to the email's record; a complaint switches that customer's marketing email off, the same minute EVERY TEMPLATE IS IN THE REPOSITORY; THE ORDER ONES RENDER FROM THE ORDER ITSELF, NOT FROM A COPY OF IT

Twelve emails and what sends them. The two abandoned-cart reminders are scheduled with the provider at twenty-four and forty-eight hours and check at send time whether the cart is still abandoned. The provider reports back on every email, and a complaint switches that customer's marketing email off.

[ SCREENSHOT ]
The order confirmation, rendered from the repository's own template with sample data — the catalogue's real product, a placeholder customer. No customer's email is shown.

The order confirmation, rendered from the repository's own template with sample data — the catalogue's real product, a placeholder customer. No customer's email is shown.

Every order moves through a stated set of states, with a written rule for who may move it: a customer cancels on their own before anything ships; a refund is an administrator's workflow, only after delivery and within thirty days, back to the card for a card order and to store credit for cash on delivery.

[ ORDER LIFECYCLE ]
An order's states, and who may move it Five states in a row — pending, processing, shipped, delivered, refunded — with cancelled below. A customer may cancel from pending or processing on their own; only a delivered order may be refunded, within thirty days, through an administrator's workflow. Refunds default to the card for card orders and to store credit for cash-on-delivery orders. A failed card payment is recorded by Stripe's webhook with its reason. AN ORDER'S STATES, AND WHO MAY MOVE IT pending cash on delivery starts here processing a paid card, or credit, starts here shipped delivered refunded · final refund: delivered only, within 30 days, by an administrator card → back to the card · cash on delivery → store credit cancelled by the customer, on their own, from pending or processing — before anything ships a failed card payment is recorded by Stripe's webhook, with the reason, and never reaches processing cancelled after a card payment → refunded THE RULE THE ADMIN AND THE ACCOUNT PAGE BOTH ENFORCE: CANCEL IS SELF-SERVICE, REFUND IS A WORKFLOW

An order's states and who may move it. Cancel is the customer's own action before anything ships; refund is an administrator's workflow after delivery, within thirty days — back to the card for a card order, to store credit for cash on delivery.

The administration behind all of it — products, stock with history and alerts, orders, customers and their credit, reviews, communications, and the referral programme's own parameters on a surface that sets them.

[ SCREENSHOT ]
The referral programme's parameters on the surface that sets them: the order that qualifies, the reward on an order and on a first order, the signup bonus. Every change to them is audited.

The referral programme's parameters on the surface that sets them: the order that qualifies, the reward on an order and on a first order, the signup bonus. Every change to them is audited.

The decision that mattered

The checkout. It is the single most important part of an e-commerce site, and it is where three services with their own clocks — the payment provider, the database, the email provider — have to be made to fire in one order and end up agreeing.

[ CHECKOUT ]
One checkout, three clocks A sequence in three lanes — the browser, the server, and Stripe with the email provider — showing the eight steps of a card checkout: the customer decides; a payment intent is created in USD from the TTD total; Stripe holds the intent and the card is confirmed in the browser; the order is created with the intent id; the server verifies the intent, the cart and the addresses; one atomic database function writes the order, items, stock, payment, history and store-credit deduction together; the confirmation email is sent; Stripe's signed webhook marks the order processing or failed. Store-credit-only and cash-on-delivery orders take steps one and four to eight. ONE CHECKOUT, THREE CLOCKS · THE ORDER THINGS FIRE IN BROWSER SERVER STRIPE · RESEND 1 · the customer decides delivery method · store credit to apply · card or cash on delivery 2 · a payment intent, in USD the TTD total converted at a live rate (cached four hours, fixed fallback) · rejected below the card minimum · the intent carries the cart and the rate 3 · Stripe holds the intent the card is confirmed in the browser against it — card details never touch the server 4 · create the order sent with the intent id, the items, the addresses and the credit to use 5 · verify before writing retrieve the intent from Stripe · confirm the cart still exists · save or reuse the addresses 6 · one atomic database function order · items · stock decremented · payment record · status history · store credit deducted · cart cleared. Insufficient stock raises, and all of it rolls back 7 · the confirmation email sent through the provider the moment the order exists; failure logged, never blocks the order 8 · Stripe reports back a signed webhook: succeeded → the order found by its intent id and marked processing; failed → marked failed with the reason kept CARD steps 1 to 8 STORE CREDIT ONLY steps 1, 4 to 8 — no intent; the order is processing at once CASH ON DELIVERY steps 1, 4 to 8 — pending until delivered STEP 6 IS WHERE THE STORE-CREDIT RACE WAS: CREDIT WAS ONCE DEDUCTED AFTER THE ORDER. IT NOW HAPPENS INSIDE IT, OR NOT AT ALL

One checkout, three clocks: the browser's sequence, the server's and Stripe's, drawn in the order they fire. Step six is a single database function that writes the order, its items, the stock decrement, the payment record and the store-credit deduction together — or nothing. Credit was once deducted after the order; the race that produced is why it now happens inside it.

The browser's sequence is the customer's: choose delivery, apply credit, pick card or cash. The server's begins when a payment intent is requested — the total converted to the provider's currency at a live rate, rejected below the card minimum, the intent stamped with the cart and the rate used. The card is confirmed in the browser against that intent and never touches the server.

Only then is the order created, and before anything is written the server goes back to the provider to retrieve the intent, confirms the cart still exists, and saves or reuses the addresses.

The writing itself is one atomic database function: the order, its items, the stock decrement, the payment record, the status history, the store-credit deduction and the cleared cart, together — or, if a variant has run out, none of it. The confirmation email goes the moment the order exists. And the provider's own clock closes the loop: a signed webhook finds the order by its intent and marks it processing, or marks it failed and keeps the reason.

[ SCREENSHOT ]
The checkout, signed in, with a pair of earbuds in the cart: delivery methods with their rate and cash-on-delivery flag, store credit to apply, the choice of card or cash on delivery with the currency conversion stated, and the summary in the customer's currency — first-order delivery free and the delivery reward already counted. Captured locally on a demonstration account; nothing was typed into the card element and no order was placed.

The checkout, signed in, with a pair of earbuds in the cart: delivery methods with their rate and cash-on-delivery flag, store credit to apply, the choice of card or cash on delivery with the currency conversion stated, and the summary in the customer's currency — first-order delivery free and the delivery reward already counted. Captured locally on a demonstration account; nothing was typed into the card element and no order was placed.

[ SCREENSHOT ]
The same checkout on a phone, where most shop traffic lands.

The same checkout on a phone, where most shop traffic lands.

The part worth copying is the part that was wrong first. Store credit was originally deducted after the order was created — a second step, a moment later. The project's own working notes record what that produced: race conditions, and order totals that did not match the credit actually taken.

The fix was not a retry. It was to move the deduction inside the same function as the order, so that an order and its credit either both happen or neither does. That is the whole lesson of the build in one change: in a checkout, the order of operations is the product.

Three paths share the sequence. A card takes all eight steps. An order covered entirely by credit skips the intent and is processing at once. Cash on delivery skips it too, and stays pending until the goods arrive.

Where it stands

Not live, and between iterations — on purpose. The storefront runs against its own catalogue, and the next version is being refined rather than the current one rushed out.

[ HISTORY ]
How it was built: commits per day, and what landed A table of the days on which the storefront was committed to, with a bar per commit and a line saying what landed: 16 commits between May and July 2025, from the storefront taking shape to store credit made atomic with the order and the referral programme; then fourteen months with no commit in either repository; then two days in September 2026, the split into its own repository and the review that preceded this page. HOW IT WAS BUILT · COMMITS PER DAY, AND WHAT LANDED DAYCOMMITSWHAT LANDED 8 May 2025 the storefront takes shape inside the company's main site 12 Jun 2025 environment and dependencies settled 13 Jun 2025 layout · addresses by island · first-order free delivery · Stripe 24 Jun 2025 currency in the checkout · the email provider · cart validated before the order 26 Jun 2025 store credit through the whole application — order creation made atomic with it 27 Jun 2025 its own identity: icons, manifest, open graph 7 Jul 2025 the referral programme · the balance in the header 13 Jul 2025 the referral bonus moved behind email verification fourteen months — no commit touching the storefront in either repository 3 Sep 2026 the split: 260 files into a repository of its own, by a written plan 10 Sep 2026 the review — nineteen routes, eleven findings fixed — then the taste pass 16 COMMITS IN TEN WEEKS; NOTHING FOR FOURTEEN MONTHS; THEN TWO DAYS THAT MADE IT ITS OWN, AND MADE IT RIGHT

Sixteen commits in ten weeks, May to July 2025; then nothing in either repository for fourteen months; then two days in September 2026 — the split into a repository of its own, and the review that preceded this page.

In September 2026 it was decoupled from the company's main site into a repository of its own, by a written plan of five decisions — whether the admin was ever meant to be shared (no), separate repositories rather than a monorepo or a subdomain, and what to do with the database (first one answer, then, the same day, its reversal, left visible in the record rather than overwritten).

The split moved two hundred and sixty files, found three that had been living outside the storefront's namespace, fixed a shared utility that had been living inside it, and was verified with a production build before it was called done.

Before this page was written, every route a visitor can reach was reviewed against a written rubric at two widths — nineteen routes, eleven findings, two of them security-grade, all fixed the same day — and then the storefront was refined against the company's own design principles: one accent, one display face, a shape language that says what can be pressed.

[ THE REVIEW ]
The review: eight checks, then seven rules Two columns. Left, the eight checks every public route was reviewed against at two widths — works, states, responsive, accessible, metadata, copy and money, honest performance, public surface — with the number of findings under each, 11 in all, every one fixed the same day. Right, the seven design rules then applied from the company's own principles: one accent, the product elevated and the chrome flat, font roles with no overlap, shape that says what can be pressed, two hover gestures, the footer as a sign-off, and the boring pages passing the same test. BEFORE THIS PAGE · NINETEEN ROUTES AT TWO WIDTHS, EIGHT CHECKS, THEN SEVEN RULES THE RUBRICFINDINGS THE RULESAPPLIED R1works 3 R2states 2 R3responsive R4accessible 1 R5metadata 1 R6copy & money 2 R7honest performance R8public surface 2 S1one accent, one shadeAPPLIED S2the product elevated, the chrome flatAPPLIED S3font roles with no overlapAPPLIED S4shape says what can be pressedAPPLIED S5two hover gesturesAPPLIED S6the footer as a sign-offAPPLIED S7the boring pages pass the same testAPPLIED 11 FINDINGS, ALL FIXED THE SAME DAY · SEVEN RULES, VERIFIED BY COMPUTED STYLE, BY RECON AND BY EYE

Every route a visitor can reach, reviewed at two widths against eight written checks: nineteen routes, eleven findings, all fixed the same day. Then seven design rules from the company's own principles, applied and verified the same way.

The intent is plain: build more of these, with increasing proficiency, and keep refining this one until it is a working part of the OPI brand.

Everything shown here is the storefront's own surfaces and templates, captured locally. The catalogue in the captures was seeded for them — real, current products, each with a freely licensed photograph from Wikimedia Commons, credited in the storefront — because the shop's own stock is between iterations. The account shown is a demonstration account; no customer, order or address appears; the email is the real template rendered with sample data, and says so.

Next — NMLS Document Repository →

Selling online where the big payment providers don't operate?