The client
The client is a large finance sector company in the US that sells prepaid cards to businesses. Companies buy cards in bulk for their staff, customers or campaigns. Each order picks a card type and a design, and can carry the buyer's own logo and a short message. Cards are printed to order and shipped by standard or overnight delivery.
What they needed
The company wanted its business customers to order cards online, pay, and follow each order to delivery on their own. Its team needed one place to run those orders, with every order and customer still recorded in Salesforce, where the sales team already works.
What we built
We built a customer portal, an admin portal and the API behind both.
In the customer portal:
- Company accounts with several users. A customer admin manages the company and its people. A regular user sees only their own orders. One person can belong to several companies and switch between them.
- Ordering. Pick a card type and design, add a logo and a two line message, or upload your own artwork.
- Quick Ship. A short list of designs already printed and in stock, with no customisation, shipped overnight for customers who need cards fast.
- Payments through Stripe by card, ACH debit from a US bank account, or bank transfer to a dedicated account.
- Invoices and refund receipts as PDF downloads, plus discount codes.
- Order history with a status timeline for every order.
- Sign in with a password or a passkey.
In the admin portal:
- An order queue where the team moves each order through fulfilment to delivery.
- Three staff roles. Full access for super admins. Sales admins run orders, customers, invoices, payments and refunds but do not see company wide revenue totals. Other staff can view orders and update their status, nothing more.
- Card types, designs, Quick Ship stock, customers and users, all managed from the same screens.
Behind both portals, every account, contact, address, order and order line is synced to Salesforce.

How we built it
One pricing engine calculates every order. The quote a customer sees at checkout and the invoice that follows come from the same code, so they cannot disagree.
Both portals share one typed API client. A change to the API contract shows up in both portals at build time, not in production.
Card designs are uploaded before anything is saved, so a failed upload never leaves an order pointing at a missing file. Salesforce updates run in the background and never block a customer's order.
The API runs as a container on AWS. Both portals are served through Amazon CloudFront with a web application firewall in front. Every change goes through automated checks and a staging environment before production.
Technology used
- API
- Node.js ยท Fastify ยท TypeScript
- Portals
- Next.js
- Data
- PostgreSQL ยท Drizzle ORM
- Payments
- Stripe
- CRM
- Salesforce
- Sign in
- Amazon Cognito ยท Passkeys
- Hosting
- AWS ECS ยท AWS Amplify ยท Amazon CloudFront
- Monitoring
- Sentry
If your customers still order by email
If your business customers still order by email or phone, and your team retypes every order into your CRM, the same approach works for you. Let customers order and pay online, keep one source for prices, and let the CRM update itself. Talk to us about an ordering platform for your business.
