Project 001 · NFC review cards · web shop · sales

AlmiBoost

NFC cards that turn one phone tap into a Google review. I built the whole thing around them: the online shop, a 3D card designer, payments, invoices and an admin panel, plus the hardware sourcing and the door-to-door sales behind it.

RoleCo-founder & CTO
TimelineJun 2026 – present
StatusLive, taking orders
StackNext.js, React, TypeScript, Tailwind, Postgres, Vercel
AlmiBoost screenshot

Overview

AlmiBoost sells small NFC cards to local businesses. A customer holds a phone against the card and the Google review form for that business opens straight away. There is no app, no QR code and no searching for the profile. The cards are programmed for each customer's own Google profile before they ship.

The company is run by three students, and I am the CTO. That means I own the technical side end to end: the hardware supply chain, the website and shop, and a good part of the in-person selling. This page covers the website and shop in detail, because that is the largest piece of software I have shipped.

The problem

Google reviews decide whether a customer picks one shop or the one down the street. Most owners know this, but asking for a review is awkward and the customer usually postpones it. By the time they find the profile, tap through to the form and start writing, many have given up.

A QR code removes some friction but still needs the camera, a scan, and often a second tap. An NFC card removes the rest: the form is open the moment the phone touches the card. The product is simple, so the work was in making it easy to buy, easy to customise, and easy for a three-person team to fulfil without errors.

The product line

The shop sells seven stock products and a fully custom card.

ProductDetails
Standard Google review card85 × 54 mm, the size of a payment card. Fits next to the till. From €14.99.
Round cardA 100 mm round sticker-style card, the most visible option on a counter. €19.99.
Square Google cardA square format for a counter or window.
Menu cardOpens a restaurant's menu on tap.
Instagram, TikTok, Facebook cardsOpen the business's social profile on tap.
Custom cardOwn logo, print and size, designed in the browser (see the configurator below).

Volume discounts apply across the whole basket: 3 pieces 10%, 5 pieces 15%, 10 pieces 20%, 20 pieces 25%. Each review-card chip is programmed for the customer's Google profile, which we look up ourselves from the business name and address, so the customer does not have to hunt for a link.

A product page with a draggable 3D card, live stock status and the volume-discount selector.
A product page with a draggable 3D card, live stock status and the volume-discount selector.

What I built

Storefront and product pages

Product grid, stock badges and a 3D card viewer you can drag to rotate and double-click to flip. The 3D card uses the real millimetre dimensions of each product, so the preview matches what arrives.

Custom card configurator

Pick one of the preset sizes (from 45 × 25 mm up to 100 mm round) or enter your own size, upload artwork, crop it in a modal, and check it for print readiness. A live price with the volume discount updates as you go.

Checkout without registration

Cart, delivery and payment in one flow. One order can cover several businesses, each with its own address and cards, which is how a small chain or a landlord actually buys.

Online payments

Card, Apple Pay, Google Pay and bank buttons through the GoPay gateway. Bank transfer and cash on personal pickup are also supported, and the form only offers combinations that make sense.

Delivery options

Packeta pickup point (free above a set order value), courier, personal pickup in Bratislava, or us installing the card in person. A Packeta point picker is built into the checkout.

Invoices

A PDF tax document is generated for each order with pdf-lib and an embedded font, so Slovak characters render correctly. All the arithmetic is done in whole cents to avoid rounding errors.

Admin panel

A protected area to see orders, change status, trigger payment and e-mail actions, upload invoices, see stats cards and switch products in or out of stock.

Content and SEO

Twelve blog posts and guide pages about getting Google reviews, NFC versus QR codes, and local SEO, with a sitemap, dynamic share images and rich structured data on every page.

How an order flows through the system

The site is a Next.js application deployed on Vercel. Pages render on the server; mutations go through route handlers. Postgres holds orders, Vercel Blob holds uploaded designs and invoices, GoPay handles money, and a scheduled job nags unpaid orders.

  1. The customer fills the basket or the configurator. Nothing the browser sends about price is trusted.
  2. The order route validates the input with Zod, then recalculates the price on the server from the shared price tables: product price, volume discount, delivery price and, for custom cards, the setup fee.
  3. The order is stored in Postgres with a short human-readable number (like #0012) from a database sequence. Custom orders also store the design file URL and a JSON spec.
  4. For card payments the server creates a GoPay payment and redirects the customer to the secure gateway.
  5. GoPay calls a notification endpoint. The server then asks GoPay for the real payment state instead of reading anything from the return URL, because a return URL can be edited by the customer.
  6. Confirmation e-mail goes out through Nodemailer. In the admin panel the order shows as paid.
  7. When the parcel ships, the invoice PDF is generated and attached; for custom orders a proof is sent first and its approval time is recorded.
  8. A daily Vercel cron job at 08:00 finds unpaid orders and sends payment reminders.

The custom card designer

This was the most interesting part to build, because it has to be pleasant for a shop owner and strict enough for a printer.

  • Sizes and limits. Eight presets plus a free-size mode with minimum and maximum edges and a maximum area. All cards are PVC at payment-card thickness (0.76 mm). A size flag lets us switch off a format the supplier cannot deliver by editing one line, so the picker never offers something we cannot ship.
  • Artwork upload and crop. The customer uploads an image and crops it in a modal. A print-readiness check calculates the effective DPI from the pixel size and the physical size, and warns when the image is too small to print sharply.
  • 3D preview. The card is rendered with the uploaded art on the correct shape (rectangle with rounded corners, or circle) so the owner can rotate it before paying. Front images are prepared at 1024 px because smaller textures produced jagged edges when the browser scaled them down.
  • Proof and consent. A proof is sent before production and both the sent and approved times are stored. That record matters legally: made-to-order goods are excluded from the right to withdraw only if they were made to the customer's approved specification.
  • Pricing. Price per piece by size, volume discount on the total, and a one-time design setup fee that is waived from five pieces. The same pricing module is used by the form and the API so the two can never disagree.
The custom-card page: pick a size, upload artwork and spin the card in 3D.
The custom-card page: pick a size, upload artwork and spin the card in 3D.

Data model

One Postgres table holds orders, grown by small additive migrations so that old orders never broke:

  • Customer and business fields, an items JSON array (product, quantity, unit price), totals, discount and delivery.
  • Custom-order columns: design URL, a pending-design flag, a JSON spec with sizes and artwork metadata, a setup fee, and the proof timestamps.
  • A businesses JSON column for orders that cover more than one business. The first business is also copied into the classic columns, so existing lists and search keep working.
  • Invoice URL and file name, payment method and payment status, and a unique human-friendly order number.
  • A separate product_stock table that the admin panel edits, so availability is a switch rather than a code change.

Security and correctness decisions

  • The server is the source of truth for money. Delivery price, discounts and totals are recomputed on the server. A tampered request cannot buy at a different price.
  • Payment state comes from the gateway. The return URL only tells the page to refresh; the paid status is read from GoPay's API.
  • Admin is protected before anything renders. A proxy layer verifies a signed session cookie for every admin page, the admin API routes and the Server Actions, so an action cannot be called directly without loading the page.
  • Secrets stay in environment variables. Gateway credentials and mail settings are never in the code or sent to the browser.
  • One source of truth for company data. The company identity used in the footer, terms and privacy policy comes from a single module, so the pages cannot drift apart. Slovak distance-selling law requires this information to be complete and correct.
  • Honest marketing rules. The copy never promises a number of reviews or star ratings. Promising either breaks Google's policy and the EU Omnibus directive, which matters for a business that sells review-collection hardware.

Search and structured data

Because most customers find us by searching for review cards, the site is built to be understood by search engines. Each page type carries the right structured data: a local business with its social profiles on every page, products with offers (including return policy and shipping details), articles with named authors, FAQ pages with the real questions, how-to guides and breadcrumbs. Blog posts and product pages generate their own share images. I checked all pages in a crawl against the sitemap, and the one thing I deliberately do not add yet is star-rating markup, because there is no real customer review data to back it up.

Hardware and supply chain

The cards use NTAG213 and NTAG215 NFC chips. I source them directly from a manufacturer in Shenzhen and pay by international wire transfer. Each card is programmed with the customer's Google review link, tested with a phone, and shipped; delivery inside Slovakia takes about 3–5 working days. A replacement guarantee covers the first twelve months.

Before AlmiBoost I had already built a servo-driven cabinet lock around a PN532 NFC module, so the hardware side was familiar. The hard part was not the chip but the logistics: sample orders, quality checks, and keeping stock honest on the website, which is why the stock panel exists.

Selling it

The first customers came from door-to-door visits in Bratislava. I deliberately skipped cold calling in favour of showing the card in person. A pitch leads with the prospect's own review count compared to a competitor nearby, not with a product demo. Every visit is logged in a field tool I built for the purpose, AlmiBoost Scout. At the time of writing, the live About page reports 15 businesses served and 26 cards sold since August 2026.

What I learned

  • A small shop is mostly edge cases: partial stock, multi-business orders, VAT maths, proofs for custom goods. Designing the data model for them early saved a lot of rework.
  • Never trust the client with money, and never trust a redirect to prove a payment.
  • Doing sales myself made me a better developer. Watching a shop owner try to leave a review shaped almost every decision in the checkout and the product pages.
  • Hardware sourcing is a project of its own: lead times, samples and quality checks need as much planning as software.

What is next

  • Collect real customer reviews and add star-rating markup once there is genuine data behind it.
  • Improve the follow-up funnel, since many pitched businesses are never contacted a second time.
  • Extend the platform into new NFC products for small businesses.
Next project AlmiBoost Scout →