Short answer
RaftLabs built a customer rewards platform for a full-fibre broadband provider in Northern Ireland and Cumbria. Customers reach offers, coupons, and competitions from the provider's account portal with single sign-on, using a 10-second, single-use signed token. The backend runs on Vercel, Neon, and Drizzle to fit a fixed monthly hosting fee. Built and on staging, but not launched.
Engagement
The engagement
- Client
- A full-fibre broadband provider in Northern Ireland and Cumbria (name withheld)
- Delivered through
- A loyalty agency partner
- Scope
- Customer rewards web app inside the provider's account portal, admin console, API, and portal sign-in integration
- Team
- One full-stack developer, a project manager, and QA
- Timeline
- Scoping from May 2026; staging live on 18 June 2026; agency and brand feedback rounds from July to September 2026
- Status
- Built and on staging; not yet launched
The situation
A broadband subscription is a relationship most customers only notice when something breaks: a bill, an outage, a complaint. A rewards program is the one positive touchpoint the provider controls. A full-fibre broadband provider wanted its customers to get partner offers, coupons, and competitions as part of their subscription, reached from the account portal they already use. Customers shouldn't sign in twice, and the loyalty agency running the program had to keep it inside a fixed monthly hosting fee.
Those two constraints shaped the build. Sign-in had to hand a customer from the portal straight into rewards without an extra login. Hosting had to stay small enough to run and monitor inside the fee. The platform is built and on staging. It hasn't launched, so this page covers the decisions behind it. Results come after launch.
Before and after
From a new program to a rewards platform inside the portal
- No rewards program existed for the provider's broadband customers
- A second login would have kept customers out of a program that lived outside the portal
- The program had to run and be monitored inside a fixed monthly hosting fee
- An import of every portal customer would have created accounts for people who never used rewards
- Offers, coupons, and competitions sit behind a rewards link in the provider's account portal
- Single sign-on takes a customer from the portal into rewards with no second login
- A Hono API on Vercel Functions, Neon serverless Postgres, and Drizzle ORM keep hosting to one platform
- Accounts start on a customer's first click-through, so the platform only holds people who used it
- Participation KPIs live inside the admin console
The decisions that shaped the build
Hosting had to fit a fixed monthly fee
The agency's first written concern was cost: it needed to run and monitor the program within a fixed monthly fee. That ruled out a stack of separately hosted services, each with its own sizing and upkeep.
On 15 June, ten days into the codebase, we settled the backend on Vercel: a Hono API on Vercel Functions, Neon serverless Postgres, Drizzle ORM, Better Auth for admin sign-in, Vercel Blob for media, and Vercel Cron for an hourly lifecycle job. One platform hosts every part of the program. No production data existed yet, so the schema was written once, in Drizzle.
Without a separate permission layer, access checks live in application code: customer queries scope to the signed-in customer, and admin routes check roles. That was the biggest correctness risk in the design, and the API's integration tests cover it. The API region sits in London, next to the database.
Customers should reach rewards without a second login
Customers arrive from the provider's portal and shouldn't sign in twice. When a customer clicks the rewards link, the portal signs a token. The rewards platform checks the signature, rejects anything older than 10 seconds, accepts each token once, and sets its own 24-hour session. Replay protection and secret rotation are built in, so the shared secret can change without a coordinated cutover.
The sign-in contract is written up as a specification for the provider's security team. It keeps the payload to one opaque customer reference, signs it with HMAC-SHA256, and encrypts it as a JSON Web Encryption token. It offers three ways for the token to travel: an encrypted token in the URL with an immediate bounce, a POST that keeps it out of the address bar, or a back-channel exchange where the browser only carries a spent one-time code. The provider picks the one that fits their standard. It's data minimisation applied to a login. The specification awaits the provider's sign-off.
Accounts start on a customer's first click-through
The early plan included an API to pre-load an account for every portal customer. The agency agreed to drop it on 7 May.
The platform creates an account the first time a customer arrives through sign-in and refreshes their last-access time on every visit. It only stores and hosts people who actually used it, and the first-time-active and active-user KPIs count real visits instead of imported rows.
Access stays with the provider. The portal shows the rewards link once a customer's installation is complete and hides it when they leave or are suspended. Sessions last 24 hours, so a removed customer loses access within a day at most.
Reporting moved into the admin console
The agency asked whether KPIs would come through Metabase. For a program this size, a separate reporting service meant one more thing to host, size, and maintain inside the fixed fee.
We built the KPIs into the admin console instead: active users, engaged users, first-time active users, reward views and redemptions, competition views and entries, and campaign views and redemptions. The numbers sit next to the rewards they describe, and there's no second system to keep running.
A full component library for the people running the program daily
Operators use the admin to create rewards, campaigns, competitions, and homepage content, then publish and schedule them. Each change needs a confirmation step, and the target is WCAG 2.1 AA.
On earlier projects, building admin screens from minimal shadcn/ui primitives meant hand-building accessibility, browser support, and theming for each control, and AI coding agents burned time on the same gaps. For this admin we chose Mantine, a full component library that already handles those. The customer app keeps Tailwind and shadcn/ui under the provider's brand.
System flow
How a customer gets from the portal to a reward
A simplified view based on the project repository and the SSO specification. It shows the path a provider's security and loyalty teams need to understand. Supporting services are left out.
Entry
Provider's customer portal
Shows the rewards link to eligible customers and signs a short-lived token for each click. The provider controls who sees the link.
Sign-in
SSO route and session
Checks the signature, the 10-second expiry, and a single-use nonce, creates the account on the first visit, and sets a 24-hour session cookie.
API
Hono on Vercel Functions
Handles redemptions, competition entries, coupon allocation, and voucher PDFs, with access checks in application code and an hourly lifecycle job.
Data and operations
Neon, Drizzle, and the admin console
Postgres holds rewards, campaigns, competitions, coupons, and engagement events. Operators manage them and read KPIs in the admin.
the build
What customers and operators get
The platform splits into a customer web app, an admin console, and an API, each deployed as its own Vercel project.
Offers, coupons, and competitions under the provider's brand
Customers browse partner rewards and claim coupons delivered as a text code, a redirect link, or a branded PDF voucher. Coupons can be unique per customer or shared. Competitions can include multiple-choice questions, sponsors can run video content, and a family page filters rewards by Northern Ireland county.
An admin that moves rewards from draft to live to ended
Operators author rewards, campaigns, competitions, brands, categories, and homepage content, then publish or schedule them. Business rules run on the server, and each change asks for confirmation. An hourly job expires finished campaigns, settles closed competitions, and clears spent sign-in nonces. An audit log records what changed.
Participation KPIs without a separate reporting tool
The admin shows active, engaged, and first-time active users alongside views and redemptions for rewards, competitions, and campaigns. Engagement events feed those figures directly, so the numbers operators read come from the same data the customer app writes.
Proof
What exists today, and what this page can't claim yet
The platform hasn't launched, so there are no usage, engagement, or cost results. These are the delivered and recorded facts.
| Result | What changed | Period or context | Evidence and limitation |
|---|---|---|---|
| Delivery speed | Staging live 13 days after the codebase was created | 5 to 18 June 2026 | Project-recorded: repository history |
| Backend | One Drizzle schema on Neon, with a Hono API on Vercel Functions | Backend decision on 15 June 2026 | Project-recorded: backend plan and repository |
| Sign-in | 10-second, single-use signed tokens with replay protection and secret rotation | Current staging build | Project-recorded; the opaque-reference contract awaits the provider's security sign-off |
| Hosting model | Backend runs on Vercel and Neon with no AWS services | Staging | Project-recorded; the hosting fee is confidential and not published |
| Outcomes | Not yet available | Before launch | KPIs are built into the admin console and will report once customers arrive |
The lesson
Agree the sign-in contract with the client's security team before you build
Single sign-on from a customer portal touches the client's identity rules, and those rules differ by sector. A telecom provider's security rules can differ from what a rewards platform built for another sector assumes.
If you're adding sign-in from a customer portal into a partner platform, take the payload, the transport, and the revocation model to the client's security team before building. One review call shapes the whole contract, and it costs less on day one than in the middle of the build.
The second lesson is about where the attention went. The admin got attention first, and the agency's review rounds surfaced customer-side UX details we should have caught earlier. The customer app is where a new program earns its first impression, so start there and build the admin around what customers see.
Where to go next
What stayed out on purpose
Scope decisions made during the engagement. None of these are part of the current build.
- Next 01
Features beyond the launch brief
The brief covered offers, coupons, and competitions inside the portal. Anything new waits for a later phase.
- Next 02
Instant session revocation
Sessions expire after 24 hours for launch. A revocation webhook or a status check can close that gap before voucher campaigns, if the provider wants it.
- Next 03
An in-app entry point
Phase 1 assumes customers arrive from the web portal. An entry inside a mobile app's web view would need the redirects and session cookie reviewed first.
How it runs
- Next.js
- The customer app runs on Next.js with Tailwind and shadcn/ui under the provider's brand. The sign-in route, the session cookie, and a strict nonce-based content security policy live in the same app.
- Hono on Vercel Functions
- A small API framework on Vercel's Node runtime handles redemptions, competition entries, coupons, voucher PDFs, and the hourly lifecycle job, deployed as its own project next to the two apps.
- Neon and Drizzle
- Serverless Postgres with a typed schema keeps the database on the same platform as the API. Access rules live in application code, scoped by the signed-in customer and the admin's role.
- React, Vite, and Mantine
- The admin console uses a full component library, so tables, filters, forms, and confirmation dialogs behave the same everywhere and meet an accessibility target without hand-building each control.
- Vercel
- Three Vercel projects cover the customer app, admin, and API, with Vercel Blob for media and Vercel Cron for scheduled jobs. One platform keeps hosting inside a fixed monthly fee.
Common questions
The portal signs a short-lived token when the customer clicks the rewards link. The rewards platform checks the signature, rejects tokens older than 10 seconds, and accepts each token only once. On the first visit it creates the account, then sets its own 24-hour session. In the specification sent to the provider, the token carries one opaque customer reference and nothing else.
Yes, if identity is an opaque reference that only the provider can resolve to a person. The specified design keys every reward, redemption, and entry to that reference and greets customers generically. A right-to-erasure request then comes through the provider, who sends the reference so the platform can delete the activity held against it.
The provider hides the rewards link, so a former customer can't start a new session. An existing session runs out within 24 hours. A customer who later rejoins arrives under a new reference and starts fresh, with no history carried over. For immediate removal, a revocation webhook or status check can be added before voucher campaigns.
Ten seconds covers a redirect, and the window is configurable if testing shows slow devices need more. Both sides need clocks synced with NTP, and the verifier allows about two seconds of clock skew. The shared secret can also rotate: the platform accepts the previous secret during an overlap window, so rotation doesn't need a coordinated cutover.
The program had to run inside a fixed monthly hosting fee. Vercel and Neon put the API, database, scheduled jobs, and media storage on one platform, so there were fewer services to size, monitor, and pay for. Access rules moved into application code, covered by integration tests, and there was no production data to migrate yet.
Here, staging went live 13 days after the codebase was created, with scoping in May beforehand. Most of the calendar since has gone to sign-in review and brand feedback, and the platform hasn't launched yet. Plan the timeline around integration and approvals. See our loyalty program development service and pricing guide.
Related work
Related loyalty platform work

Energia Rewards loyalty platform migration
A 10-12 week Energia Rewards rebuild that migrated roughly 500,000 users and reduced support tickets by 80% (client-reported), and replaced a WordPress platform that had reached its operating limit.

OOHPOD rewards program software
A 10-week rewards program software build connecting OOHPOD customer eligibility with reward browsing, coupon claims, competitions, and campaign administration.

Bella Skin Institute loyalty app
A custom mobile loyalty program with QR-based point earning, expiring rewards, and an operator-owned admin experience.
