- Platform
- Web App
- Duration
- 12 weeks
- Industry
- Food & Beverage (F&B) Industry
- Team
- 2 engineers + 1 QA + 1 PM
- Engagement
- Fixed-scope
- Read time
- 7 min read
In short
RaftLabs built an AI receipt-validation and prize-draw platform for Musgrave Group's SuperValu and Centra supermarket brands in Northern Ireland. Delivered in 12 weeks through creative agency Brandfire. In the first seven days: 471 users registered, 573 receipts were validated, and 76 winners were selected across 18 participating stores. Over four weeks: 1,062 users registered and 1,610 receipts were processed with 99.9% uptime. AI validation accuracy reached near 99%, up from roughly 80% early in the build. The accuracy improvement came from a specific engineering decision: the system originally passed 128-bit UUID strings to the LLM for store matching, which the model handled unreliably. Switching to simple sequential integers before the model call, then mapping back to UUIDs internally, closed the gap. The platform uses Google Vertex AI to validate receipts against store name, minimum spend threshold (EUR 10), and a prohibited items list. Both brands run independent campaigns, prize pools, and weekly draws from one centralized admin interface. Duplicate entries are blocked using a composite identifier built from store address, store ID, POS machine ID, brand, and transaction timestamp.
Musgrave Group operates SuperValu and Centra, Ireland's two largest grocery brands. To drive footfall and repeat visits across Northern Ireland, they designed a campaign: shoppers upload a grocery receipt and enter a weekly prize draw to win cash prizes.
The numbers made manual checking unworkable. The campaign called for 10 winners per store each week across 18 participating locations. That is 180 winners every seven days. Staff checking receipts by hand would spend most of their week on that task alone, and error rates on hundreds of weekly submissions would have undermined the draw's fairness.
They came to us through Brandfire, their creative agency and our direct partner on the build. Brandfire had already worked with us on AldiFest for Aldi Ireland. They knew what we could deliver.
We built the platform in 12 weeks. First seven days in production: 471 users registered, 573 receipts were validated, and 76 winners were selected across 18 stores. Over four weeks: 1,062 users and 1,610 receipts processed with 99.9% uptime. AI validation accuracy reached near 99%. That number did not start there. It started at roughly 80%. One engineering decision closed the gap.

before / after
What changed
- Every receipt required a person to check the store name, purchase total, and prohibited items by hand
- Managing two brands meant running two separate systems with no shared infrastructure
- High submission volumes during campaign launches meant staff working overtime to process entries
- Draw selection across 18 store locations was a manual process prone to errors and inconsistency
- No reliable audit trail for GDPR marketing consent across thousands of customer records
- Seasonal campaign themes required developer involvement to update and were slow to change
- Google Vertex AI reads every receipt automatically: store name, spend, and prohibited items checked in seconds
- SuperValu and Centra run independent campaigns from one centralized admin panel
- The platform handles submission spikes without manual intervention or overtime
- Automated draws select 10 winners per store per week across all 18 locations with full audit logs
- GDPR-compliant registration captures explicit opt-in with timestamp and source URL for every entry
- Seasonal branding updates in the admin panel require no developer involvement
What we had to solve
- 01
Getting AI validation from 80% to near 99%
Every till in the 18 participating stores produces a different receipt format. Store name, purchase total, and date appear in different positions depending on the location. Getting those fields extracted correctly across real-world receipt images, including faded thermal paper, low-light photographs, and cropped uploads, was the base requirement.
The harder problem appeared during testing: store-matching was failing roughly one time in five. The OCR was reading the text correctly, but the model could not reliably match the store to the right location in the campaign. The system was passing 128-bit UUID strings to the LLM as store identifiers. Long arbitrary character strings are processed inconsistently by language models. Prompt refinements alone did not close the gap.
The fix was to strip the UUIDs from the model's input. We mapped each store UUID to a simple sequential integer before the LLM call, sent those integers to the model, and mapped back to the original UUID after it returned a result. The model never saw the raw identifiers.
That change took validation accuracy from roughly 80% to near 99%.
- 02
Two brands, one system, no data crossover
SuperValu and Centra are independent brands with separate customer bases. Prize pools, competition windows, winner lists, and customer data had to stay completely separate. At the same time, Musgrave's team needed to manage both from one admin interface without switching between systems.
We built a multi-tenant architecture where each brand has its own campaign space, its own branded URL, and its own data isolation, all managed from a shared admin panel. Brand managers could run campaigns, review entries, and publish winners without technical help.
- 03
Blocking the same receipt from entering twice
The competition mechanic ran on trust: one receipt equals one entry. Pixel-based image comparison would miss a shopper who photographed the same receipt twice from a different angle, or in better light the second time.
We built a composite identifier using five fields extracted from every validated receipt: store address, store ID, POS machine ID, brand name, and transaction timestamp. One POS machine records only one transaction at a given timestamp. If all five fields match an existing entry in the database, the system rejects the submission as a duplicate and shows the shopper a clear reason. No manual review required.
outcomes
What we achieved
Promotional entries required staff to check each receipt by hand. The headcount available for manual review was the ceiling on campaign volume. 471 of those users registered in the first week alone.
Early testing showed store-matching failing roughly one time in five. The LLM was receiving 128-bit UUID strings it could not process reliably. Switching to sequential integers before the model call, with internal remapping after, closed the gap from roughly 80% to near 99%.
The campaign launched to a public audience with no reliability guarantee. Submission spikes during the first week meant the platform had to handle real volume immediately, with no warm-up period.
What clients say
What Nuala said after launch
Three-year average engagement. Founders and operators describing the work in their own words. No marketing varnish.

RaftLabs was outstanding at addressing our complex platform needs, delivering a stable, high-performance loyalty application that has been genuinely loved by the customers.
Running loyalty campaigns that still rely on manual receipt checking?
the build
What we built
The platform is built around a validation engine that does what a human checker would do, at any volume, in seconds.
Shoppers enter the draw in under a minute, duplicates blocked automatically
A shopper visits the campaign URL, registers with their email, confirms GDPR marketing consent, and uploads a photo of their grocery receipt. The AI reads the receipt immediately: store name, purchase date, total spend, brand. If the receipt meets the campaign rules (EUR 10 minimum spend, correct store, no excluded items such as fuel or tobacco), the entry is validated and the shopper is entered into that week's draw.
If the receipt has already been submitted, a composite check across five fields (store address, store ID, POS machine ID, brand, and transaction timestamp) catches the duplicate before it enters the draw. Shoppers see a clear reason for any rejection.

SuperValu and Centra campaigns run independently, managed from one dashboard
The admin panel lets Brandfire and Musgrave's team create and manage SuperValu and Centra campaigns independently. Each brand has its own seasonal creative, its own store lists, its own competition windows, and its own prize pool. Customers see completely separate branded experiences. Admins see one dashboard.

Weekly draws take minutes instead of hours
At the end of each competition window, the system runs a randomized draw selecting 10 winners per store across all 18 participating locations. Admins review and publish results. A "Winners Coming Soon" placeholder shows automatically until results go live. In the first week alone, 76 winners were selected across the campaign.

Every entry has a timestamped audit trail, GDPR exports ready on request
The admin dashboard shows live submission totals, validation status, and winner records in real time. Full CSV exports include email addresses, validation outcomes, and consent flags for marketing and compliance teams. Every entry carries a timestamped audit trail for GDPR purposes.

Engagement
How we worked together
- 01Weeks 1–2
Discovery and scoping
We map the problem before writing code. Two weeks of technical audit, stakeholder interviews, and prototype — so both teams align on scope and risk before sprint one.
- 02Ongoing
Two-week Agile sprints
Each sprint ends with working software, not a status update. You review a real build, request changes, and approve before we move forward. No surprises at handover.
- 03Ongoing
Daily async updates
Slack for daily progress, Asana for task visibility, weekly video calls for decisions. You have full visibility without needing to attend every meeting.
- 04Final
Handover and warranty
Full code handover with deployment runbooks and documentation. Thirty-day warranty period for production issues at no extra cost.
stack
Why we chose this stack
- 01The campaign pages needed fast first-load on mobile, since most shoppers arrived via QR code in-store. Next.js server-side rendering handled that without additional CDN configuration, and deployment to Vercel kept production updates fast during the live campaign.Next.js
- 02Google's OCR delivered the most consistent extraction accuracy across 18 stores with different receipt formats and varying photo quality. We also used an LLM layer for store matching. The key decision was to map store UUIDs to sequential integers before the model call, which took matching accuracy from roughly 80% to near 99%.Vertex AI
- 03The campaign generated heavy submission volume in short bursts when marketing pushed shoppers to the platform. Lambda scaled to meet those spikes without pre-provisioned capacity. Outside campaign periods, infrastructure cost drops to near zero.AWS Lambda
- 04The admin dashboard needed live receipt validation status without polling. Hasura's GraphQL subscriptions pushed updates to the dashboard the moment a receipt was validated or rejected, so the team could monitor the campaign in real time.Hasura
- 05Entry records, GDPR consent timestamps, duplicate-check identifiers, and draw audit logs all needed transactional integrity. PostgreSQL gave us the reliability and query precision that compliance-grade data requires.PostgreSQL
FAQs
The platform uses Google Vertex AI to read uploaded receipt images and extract the store name, purchase date, total spend, and brand. It then checks the entry against the campaign rules: minimum EUR 10 spend, correct store, no excluded items such as fuel, tobacco, or PayPoint services. Valid entries go into the draw. Invalid entries are declined with a specific reason shown to the shopper.
Accuracy reached near 99% in production. It started lower, around 80%, because the system was originally passing 128-bit UUID strings to the LLM for store matching, which the model handled inconsistently. The fix was to map each UUID to a simple sequential integer before the model call and remap internally after. That single change closed most of the accuracy gap.
A fully featured, production-ready loyalty platform of this type typically costs between $20,000 and $40,000 depending on the number of brands, validation complexity, and integrations required. See our loyalty program cost guide for a detailed breakdown.
Yes. The platform runs on AWS Lambda, which autoscales to handle submission spikes. During the first week of the Musgrave campaign, 471 users registered and 573 receipts were validated without any manual intervention or downtime.
Pixel-based image comparison would miss a shopper who photographed the same receipt twice from a different angle. Instead, we built a composite identifier using five fields from every validated receipt: store address, store ID, POS machine ID, brand name, and transaction timestamp. One POS machine records only one transaction at a given time. If all five fields match an existing entry, the system rejects the submission as a duplicate. The admin dashboard flags these submissions automatically.
Yes. We have built loyalty and receipt-scanning platforms for Aldi Ireland, Sanbra Fyffe, and Energia. We also build custom loyalty programs across healthcare, hospitality, and retail. Visit our loyalty program development page to see the full scope.
Ready to scope a receipt-validation platform for your campaign?
Related work
More work like this
Loyalty Rewards App for Brand Loyalty and Customer Retention
Aldi Ireland's AldiFest campaign reached 2,000+ signups and processed 5,000 receipts in the first week. Built via BrandFire in 14 weeks.
Read case study

Modernizing Loyalty for a Leading Irish Utility Provider
We rebuilt Energia's loyalty rewards platform from WordPress to Next.js in 12 weeks, migrating 300K+ user records with 99.9% uptime from day one.
Read case study
Gas Station Management Software with AI-Based OCR
AI-based OCR automates invoice processing and unifies inventory, sales, and vendor tracking across 40+ gas station locations.
Read case study







