All cases

VEYA2026veyamobile.tech

Mobile top-ups across all 27 EU countries: a 6-language product, payment gateway and ads with an automatic budget ladder

The gist in 10 seconds

A prepaid top-up service for all 27 EU countries for TELEflash GmbH: four steps without registration, 6 languages, 150 operators, bank-grade security and Google Ads with our own budget automation.

27
EU countries
150
operators
6
languages
69
automated tests
10
ad campaigns
383
keywords
1,037
negative keywords
15,523
lines of code
VEYA

Task

A fast, no-registration top-up service for 27 countries, correct prices in non-euro currencies, a lawful cookie layer and ads ready to scale.

Result

A working product with 150 operators, 69 automated tests, strict CSP and a 10-campaign ad structure. Payments launch awaits the provider contract — the integration boundary is ready.

What was done

  • Next.js 16 + React 19 + strict TypeScript: 14 pages, API routes, 29 components; the “number → operator → amount → payment” flow with country detection from the number (libphonenumber)
  • Data: 27 countries, 150 operators, 113 logos (imported, generated and sanitised by scripts), 6 non-euro currencies with ECB rates and server-side rounding
  • i18n: 6 languages, 7 legal documents × 6 languages, country detection by IP/CDN/Accept-Language on the server
  • Payment layer: adapter for the external gateway contract, hand-off to the payment form, “browser return ≠ payment” rule, webhook handler
  • Security: per-request CSP nonce, HSTS, X-Frame DENY, Permissions-Policy, rate limit, Zod validation on client and server, zero PII in logs
  • Tests: 55 unit (Vitest) + 14 e2e (Playwright, Pixel 7 and desktop): gateway contract, price parity, logo validity, accessibility (16 px, 44 px, focus trap)
  • Google Ads: CSV generator from site data, 10 campaigns / 45 ad groups / 383 keywords / 1,037 negatives / 45 RSAs for DE, IT, FR, ES, PL; Google policy validator
  • Budget automation: a “×2 ladder at 55% spend” script plus our own click counter (nginx log parsing, AdsBot filter, dedup, Telegram alerts)
  • Infrastructure: systemd services, nginx with Let's Encrypt, deploy script with staged build and auto-rollback

Screens

Explore the details — the full picture

The task

A German telecom operator needed a storefront service: a person enters a number, the system detects the country and operator, shows the amount in their currency and sends them to payment. No accounts, no extra fields. Plus a lawful cookie layer, an Imprint, seven legal documents in six languages and ads ready to roll out to five countries.

The product

Next.js 16 and React 19 with strict TypeScript, Tailwind 4, Radix and Motion. The home page is the product: the “number” step with an IP-based flag, the “operator” step with prefix detection (libphonenumber) and a “looks like Vodafone” hint, the “amount” step, the “payment” step. Ad landings pre-fill country, operator and amount via URL parameters.

Data: 27 countries, 150 operators, 113 logos imported, generated and sanitised by scripts; six non-euro currencies with ECB rates, server-side calculation and rounding up. Six languages, about 200 UI keys and 6,680 lines of legal text.

Payments and security

The payment provider boundary lives in an adapter for its contract, with hand-off to the payment form and a webhook handler. A hard rule: the browser returning from the payment page is not a payment — only the server confirmation is.

Per-request CSP nonce with strict-dynamic, HSTS, X-Frame DENY, Permissions-Policy, rate limit, identical Zod validation on client and server, no PII in logs or analytics — the tracking function rejects PII keys.

Quality

55 Vitest unit tests and 14 Playwright e2e tests (Pixel 7 and desktop): gateway contract, price parity across screens, XML validity of logos, accessibility (16 px text, 44 px targets, focus trap), a ban on the wrong legal entity in copy.

Ads and budget automation

A CSV generator for Google Ads Editor straight from site data: 27 language files, live import for DE, IT, FR, ES, PL — 10 campaigns, 45 ad groups, 383 keywords (cut from 10,426 to those that actually convert), 1,037 negatives, 45 responsive ads, a built-in Google policy validator.

The problem: Google Ads data lags three hours, and the bank blocks the card on sudden spend jumps. The solution — a “×2 ladder at 55% spend” script plus our own server-side click counter: it parses the nginx log, filters AdsBot and reviewers, deduplicates and sends Telegram alerts.

Honest: what is not finished

  • Payments are not verified and top-ups are not executed until the provider contract is signed — the integration boundary is ready, the supplier is not.
  • The site is in preview with noindex until launch: sitemap, OpenGraph and schema.org switch on after the flag is lifted.
  • 111 “legal review” markers in document translations.

Stack Next.js 16React 19TypeScriptTailwind 4RadixMotionZodlibphonenumbergeoipPlaywrightVitestGoogle Ads Scripts

request

Tell us the idea. A couple of lines is enough.

We reply within a business day in the messenger you choose. No newsletters.

Or straight to Telegram: @moreteploe

We need a @handle, phone or e-mail — otherwise we cannot find you.
Preferred channel

By sending you agree to data processing needed to answer your request.