Skip to content

Cannapopolis Core

Cannapopolis Core: the Romanian store’s homepage with a field video and the product row
FIG. 01 — Cannapopolis Core · E-commerce
Client
Cannapopolis
Industry
E-commerce
Status
Live
What we built
Online store · Website · Web app
Stack
Next.js · TypeScript · PostgreSQL · Prisma · Docker · Cloudflare
Services
Architecture & product · UX/UI design · E-commerce platform · Payments & delivery · Analytics & ads · SEO in 9 languages

FIG. 02 — Anatomy

Brief

Nine European markets, without a separate site for each country.

Cannapopolis Core: the Romanian store’s homepage with a field video and the product row
Cannapopolis Core: the Romanian store’s homepage with a field video and the product row
A — Interface
9 storefronts, each with its own language, currency, couriers and payments
B — Logic
Market profile → prices, delivery, checkout and tracking
C — Data
46 PostgreSQL models and a dossier for every order

Approach

  1. 01Challenge

    The brand sold through a standard online store and wanted to open new European markets without building a separate site for each country. It needed a system that could open a country in days, respect the strict rules for communicating about CBD products and show honestly where every order came from.

  2. 02Approach

    We built one core with a profile per market: language, currency, prices, couriers, payments, legal texts, SEO and tracking. Every risky feature sits behind its own switch, and every release goes through automated tests.

  3. 03Result

    Less than four weeks after the first line of code, all nine stores were live. Today the platform brings together the catalogue and local pricing, delivery through local carriers, card or cash-on-delivery payment, content in nine languages and a private centre for order and ad intelligence.

Highlights

  • 019 countries · 9 languages · 5 currencies, one core
  • 02Google Ads and Meta campaigns for every country
  • 0315 local carriers through one fulfilment partner
  • 04More than 3,000 automated tests
Skip the chapters ↓

How it’s built

CH. 01—06

Chapters

Cannapopolis Core is a platform we built for the brand: it runs the brand’s CBD-oil stores in Bulgaria, Romania, Greece, Hungary, Italy, Slovenia, Czechia, Poland and the Netherlands. Each store has its own language, currency, couriers, payments, legal pages and SEO, and behind the storefront sit customer-journey tracking, a dossier for every order and a watch on the checkout.

  1. 01One core, nine countries
  2. 02Following the whole customer journey
  3. 03Campaigns for every country
  4. 04A checkout that never sleeps
  5. 05It sells by explaining
  6. 06Nine stores in 23 days

CH. 01 / 06 — Multi-market platform

One core, nine countries

One codebase runs nine national stores. Each market has its own language, currency, prices, couriers, payments, legal pages and SEO: nine stores that work as one multilingual, multi-country shop.

Bulgaria

Cannapopolis’s local Bulgarian brand, Kanabidiol.com, with a free-delivery bar, quick order and an AI assistant.

  • BG
  • EUR · BGN
  • Econt · Speedy · Pigeon · BOX NOW
  • Cash on delivery
Open the store — Bulgaria (opens in a new tab)
kanabidiol.com

PL. 01 — Bulgaria · kanabidiol.com

  1. kanabidiol.com
    Bulgaria · Kanabidiol.com: Cannapopolis’s local Bulgarian brand, with a free-delivery bar, quick order and an AI assistant

    01 / 09 — Bulgaria

    Cannapopolis’s local Bulgarian brand, Kanabidiol.com, with a free-delivery bar, quick order and an AI assistant.

    • BG
    • EUR · BGN
    • Econt · Speedy · Pigeon · BOX NOW
    • Cash on delivery
    Open the store — Bulgaria (opens in a new tab)
  1. kanabidiol.com
    Bulgaria · Kanabidiol.com: Cannapopolis’s local Bulgarian brand, with a free-delivery bar, quick order and an AI assistant

    01 / 09 — Bulgaria

    Cannapopolis’s local Bulgarian brand, Kanabidiol.com, with a free-delivery bar, quick order and an AI assistant.

    • BG
    • EUR · BGN
    • Econt · Speedy · Pigeon · BOX NOW
    • Cash on delivery
    Open the store — Bulgaria (opens in a new tab)

CH. 02 / 06 — Tracking & attribution

Following the whole customer journey

From first touch to delivery, every step leaves a trace: only with consent, and with no names, emails or phone numbers in the reports. Without consent the source stays “unknown”; the system never guesses.

A click from search or an ad

Campaigns are reported per market and never mix countries or currencies.

What gets recorded

  • Click ID and UTM, only after consent
  • Per-market reporting

Visit source

Demo data

Demo · schematic
Channel
Google Search
Market
Romania
Marketing consent
yes
Kept
first and last touch, 90 days
  1. 01 / 07 — Ad

    A click from search or an ad

    Campaigns are reported per market and never mix countries or currencies.

    What gets recorded

    • Click ID and UTM, only after consent
    • Per-market reporting

    Visit source

    Demo data

    Demo · schematic
    Channel
    Google Search
    Market
    Romania
    Marketing consent
    yes
    Kept
    first and last touch, 90 days
  2. 02 / 07 — Landing

    A page that explains

    Guides and articles in nine languages lead to the right product, with no promises of effect.

    What gets recorded

    • First and last touch
    • GA4, split by market
    cannapopolis.nl
    Dutch price guide: how to compare CBD oil by price per mg
  3. 03 / 07 — Product

    Strength and spectrum

    The shopper picks a strength and spectrum and sees each variant’s price in their own currency.

    What gets recorded

    • Product view: Meta, where switched on
    • Price per variant and currency
    cannapopolis.nl
    Dutch product page: strength and spectrum picker with a “3 for 2” hint
  4. 04 / 07 — Cart

    “3 for the price of 2”, no spreadsheets

    Bundles are priced automatically in the cart, for every market and currency.

    What gets recorded

    • Add to cart
    • Bundle price per market
    cannapopolis.nl
    Dutch ‘3 for the price of 2’ bundle page: spectrum choice, bundle counter and saving badge
  5. 05 / 07 — Checkout

    Checkout and payment

    Card in eight markets or cash on delivery in all nine. The purchase is reported with its currency, value and order number, never twice.

    What gets recorded

    • Every step in the flight recorder, pseudonymously
    • Purchase: currency, value, order number
    cannapopolis.gr
    Greek checkout: Geniki or ACS delivery, card or cash on delivery, live order summary
  6. 06 / 07 — Delivery

    A local carrier, one partner

    15 local carriers across the nine countries, with every order going through one fulfilment partner.

    What gets recorded

    • Order readiness check before dispatch
    • Local delivery times and prices
    The delivery step of all nine checkouts side by side: local carriers, local currencies, local delivery times
  7. 07 / 07 — Dossier

    A dossier for every order

    Automatic checks right away and after 1, 24 and 72 hours, cross-checked with Google Ads, GA4 and Meta. Each check is a separate, immutable record.

    What gets recorded

    • 0 · 1 · 24 · 72 hours
    • No names, emails or IP addresses
    • No consent: “unknown”

    Order dossier

    Demo data

    Demo · schematic
    Right away
    consent and source recorded
    After 1 h
    checked against Google Ads
    After 24 h
    checked against GA4 and Meta
    After 72 h
    final assessment
    Source
    Google Search
  1. 01 / 07 — Ad

    A click from search or an ad

    Campaigns are reported per market and never mix countries or currencies.

    What gets recorded

    • Click ID and UTM, only after consent
    • Per-market reporting

    Visit source

    Demo data

    Demo · schematic
    Channel
    Google Search
    Market
    Romania
    Marketing consent
    yes
    Kept
    first and last touch, 90 days
  2. 02 / 07 — Landing

    A page that explains

    Guides and articles in nine languages lead to the right product, with no promises of effect.

    What gets recorded

    • First and last touch
    • GA4, split by market
    cannapopolis.nl
    Dutch price guide: how to compare CBD oil by price per mg
  3. 03 / 07 — Product

    Strength and spectrum

    The shopper picks a strength and spectrum and sees each variant’s price in their own currency.

    What gets recorded

    • Product view: Meta, where switched on
    • Price per variant and currency
    cannapopolis.nl
    Dutch product page: strength and spectrum picker with a “3 for 2” hint
  4. 04 / 07 — Cart

    “3 for the price of 2”, no spreadsheets

    Bundles are priced automatically in the cart, for every market and currency.

    What gets recorded

    • Add to cart
    • Bundle price per market
    cannapopolis.nl
    Dutch ‘3 for the price of 2’ bundle page: spectrum choice, bundle counter and saving badge
  5. 05 / 07 — Checkout

    Checkout and payment

    Card in eight markets or cash on delivery in all nine. The purchase is reported with its currency, value and order number, never twice.

    What gets recorded

    • Every step in the flight recorder, pseudonymously
    • Purchase: currency, value, order number
    cannapopolis.gr
    Greek checkout: Geniki or ACS delivery, card or cash on delivery, live order summary
  6. 06 / 07 — Delivery

    A local carrier, one partner

    15 local carriers across the nine countries, with every order going through one fulfilment partner.

    What gets recorded

    • Order readiness check before dispatch
    • Local delivery times and prices
    The delivery step of all nine checkouts side by side: local carriers, local currencies, local delivery times
  7. 07 / 07 — Dossier

    A dossier for every order

    Automatic checks right away and after 1, 24 and 72 hours, cross-checked with Google Ads, GA4 and Meta. Each check is a separate, immutable record.

    What gets recorded

    • 0 · 1 · 24 · 72 hours
    • No names, emails or IP addresses
    • No consent: “unknown”

    Order dossier

    Demo data

    Demo · schematic
    Right away
    consent and source recorded
    After 1 h
    checked against Google Ads
    After 24 h
    checked against GA4 and Meta
    After 72 h
    final assessment
    Source
    Google Search

CH. 03 / 06 — Ads & measurement

Campaigns for every country

We built separate Google Ads and Meta campaigns for every store and every country. The ads centre sets their reports next to the store’s real orders, and copy is checked against banned-claim lists because CBD is a restricted category.

Google Ads campaign

Separate Google Ads campaigns for every store and its country, each reported per market.

  • Live
  • Built, ready to switch on
  • Every market has its own Google Ads and Meta campaigns; Pixel/CAPI is on in BG, RO and GR and ready for the rest.
  • No business figures: spend, CPA and ROAS stay internal.
Campaigns for every country
Campaigns for every country
BGkanabidiol.comLiveLiveLiveLiveLiveLiveLiveLive
ROcannapopolis.roLiveLiveLiveLiveLiveLiveLiveLive
GRcannapopolis.grLiveLiveLiveLiveLiveLiveLiveLive
HUcannapopolis.huLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
ITcannapopolis.itLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
SIcannapopolis.siLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
CZcannapopolis.czLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
PLcannapopolis.plLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
NLcannapopolis.nlLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
Live9/99/99/99/99/93/99/99/9
Campaigns for every country
Campaigns for every countryGoogle Ads campaignMeta campaignGoogle tagPurchase → Google AdsGA4 per marketMeta Pixel + CAPIMeta catalogueBehaviour & speed
BGkanabidiol.comLiveLiveLiveLiveLiveLiveLiveLive
ROcannapopolis.roLiveLiveLiveLiveLiveLiveLiveLive
GRcannapopolis.grLiveLiveLiveLiveLiveLiveLiveLive
HUcannapopolis.huLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
ITcannapopolis.itLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
SIcannapopolis.siLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
CZcannapopolis.czLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
PLcannapopolis.plLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
NLcannapopolis.nlLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
Live9/99/99/99/99/93/99/99/9
  • Live
  • Built, ready to switch on
  • Every market has its own Google Ads and Meta campaigns; Pixel/CAPI is on in BG, RO and GR and ready for the rest.
  • No business figures: spend, CPA and ROAS stay internal.
01Google Ads campaign
Separate Google Ads campaigns for every store and its country, each reported per market.
02Meta campaign
Separate Meta campaigns for every store and its country, with copy checked for banned claims.
03Google tag
One Google Ads tag across all nine stores, loaded only after marketing consent.
04Purchase → Google Ads
The purchase is sent with its local currency, value and order number, deduplicated. Reports are split by each market’s campaigns.
05GA4 per market
One GA4 property, split by domain so markets can be compared.
06Meta Pixel + CAPI
Browser and server events share one ID and are sent only with consent and hashed data. On in Bulgaria, Romania and Greece; ready for the rest.
07Meta catalogue
A separate product catalogue feed for every country.
08Behaviour & speed
Microsoft Clarity and Cloudflare RUM after consent, kept off the checkout, cart and account pages.
Campaigns for every country
Campaigns for every countryGoogle Ads campaignMeta campaignGoogle tagPurchase → Google AdsGA4 per marketMeta Pixel + CAPIMeta catalogueBehaviour & speed
BGkanabidiol.comLiveLiveLiveLiveLiveLiveLiveLive
ROcannapopolis.roLiveLiveLiveLiveLiveLiveLiveLive
GRcannapopolis.grLiveLiveLiveLiveLiveLiveLiveLive
HUcannapopolis.huLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
ITcannapopolis.itLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
SIcannapopolis.siLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
CZcannapopolis.czLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
PLcannapopolis.plLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
NLcannapopolis.nlLiveLiveLiveLiveLiveBuilt, ready to switch onLiveLive
Live9/99/99/99/99/93/99/99/9
  • Live
  • Built, ready to switch on
  • Every market has its own Google Ads and Meta campaigns; Pixel/CAPI is on in BG, RO and GR and ready for the rest.
  • No business figures: spend, CPA and ROAS stay internal.
01Google Ads campaign
Separate Google Ads campaigns for every store and its country, each reported per market.
02Meta campaign
Separate Meta campaigns for every store and its country, with copy checked for banned claims.
03Google tag
One Google Ads tag across all nine stores, loaded only after marketing consent.
04Purchase → Google Ads
The purchase is sent with its local currency, value and order number, deduplicated. Reports are split by each market’s campaigns.
05GA4 per market
One GA4 property, split by domain so markets can be compared.
06Meta Pixel + CAPI
Browser and server events share one ID and are sent only with consent and hashed data. On in Bulgaria, Romania and Greece; ready for the rest.
07Meta catalogue
A separate product catalogue feed for every country.
08Behaviour & speed
Microsoft Clarity and Cloudflare RUM after consent, kept off the checkout, cart and account pages.

CH. 04 / 06 — Reliability

A checkout that never sleeps

A flight recorder follows every checkout step, from the cart to the confirmation, in all nine markets. Recording is pseudonymous and never stops a sale if the recording itself fails.

  • 99

    checkout event types

  • 117

    error codes, each with a clear cause

  • 9

    markets under watch

Bulgarian checkout on a phone: Econt, Speedy, Pigeon, BOX NOW and cash on delivery, with the Profile / Cart / Quick order / AI bar
  • Events are pseudonymous, and recording never blocks an order.

CH. 05 / 06 — Content & trust

It sells by explaining

More than 100 localised articles, a label guide, an archive of lab analyses and reviews with their source stated. The content describes the product, with no health claims and no dosing.

Label guide

One bottle, three numbers: %, mg and ml, explained in one place.

  • BG · pilot
  • Describes content, not dose

PL. 01 — Label guide

  1. The Bulgarian store’s label-reading guide

    01 / 09 — Label guide

    One bottle, three numbers: %, mg and ml, explained in one place.

    • BG · pilot
    • Describes content, not dose
  2. Interactive mg/ml calculator inside the label-reading guide, linked to the matching product

    02 / 09 — mg/ml calculator

    Total mg ÷ ml = mg/ml, linked to the matching product.

    • Interactive
  3. Certificates page: archived lab analyses per strength, openly labelled as previous batches

    03 / 09 — Certificates

    Archived lab analyses per strength, openly labelled as previous batches.

    • 6 strengths
    • Archive
  4. Dutch reviews: historical reviews from the original store with a source note and ‘verified purchase’ badges (names blurred)

    04 / 09 — Reviews with provenance

    Historical reviews from the original store, with a note on source and translation; a badge only for verified purchases.

    • No invented rating
  5. Dutch ‘from plant to product data’ section: planting, growth, flowering, ripening, drying, extraction

    05 / 09 — From plant to product data

    Six field photos: planting, growth, flowering, ripening, drying and extraction.

    • Real photos
  6. Greek blog hub ‘CBD in plain words’: the header, the intro and the start of a four-article reading path for first-time visitors

    06 / 09 — A blog in 9 languages

    “CBD in plain words”: a four-article path for first-time visitors.

    • 102 articles
    • Cited sources
  7. Polish article comparing full spectrum, broad spectrum and isolate, with contents and a cited study

    07 / 09 — Articles that compare

    Full spectrum, broad spectrum and isolate compared, with contents and a cited study.

    • PL
  8. Map of the brand’s partner locations in Bulgaria

    08 / 09 — Partner map

    56 partner locations in Bulgaria, filterable by city and type.

    • 56 locations in Bulgaria
    • OpenStreetMap
  9. The Dutch store’s AI assistant on a phone, showing only its greeting

    09 / 09 — An AI assistant in 9 languages

    Answers questions on strength, mg/ml, spectrum, price and delivery, with no medical claims, no dosing and no invented stock.

    • 9 languages
    • Clear guardrails
  1. The Bulgarian store’s label-reading guide

    01 / 09 — Label guide

    One bottle, three numbers: %, mg and ml, explained in one place.

    • BG · pilot
    • Describes content, not dose
  2. Interactive mg/ml calculator inside the label-reading guide, linked to the matching product

    02 / 09 — mg/ml calculator

    Total mg ÷ ml = mg/ml, linked to the matching product.

    • Interactive
  3. Certificates page: archived lab analyses per strength, openly labelled as previous batches

    03 / 09 — Certificates

    Archived lab analyses per strength, openly labelled as previous batches.

    • 6 strengths
    • Archive
  4. Dutch reviews: historical reviews from the original store with a source note and ‘verified purchase’ badges (names blurred)

    04 / 09 — Reviews with provenance

    Historical reviews from the original store, with a note on source and translation; a badge only for verified purchases.

    • No invented rating
  5. Dutch ‘from plant to product data’ section: planting, growth, flowering, ripening, drying, extraction

    05 / 09 — From plant to product data

    Six field photos: planting, growth, flowering, ripening, drying and extraction.

    • Real photos
  6. Greek blog hub ‘CBD in plain words’: the header, the intro and the start of a four-article reading path for first-time visitors

    06 / 09 — A blog in 9 languages

    “CBD in plain words”: a four-article path for first-time visitors.

    • 102 articles
    • Cited sources
  7. Polish article comparing full spectrum, broad spectrum and isolate, with contents and a cited study

    07 / 09 — Articles that compare

    Full spectrum, broad spectrum and isolate compared, with contents and a cited study.

    • PL
  8. Map of the brand’s partner locations in Bulgaria

    08 / 09 — Partner map

    56 partner locations in Bulgaria, filterable by city and type.

    • 56 locations in Bulgaria
    • OpenStreetMap
  9. The Dutch store’s AI assistant on a phone, showing only its greeting

    09 / 09 — An AI assistant in 9 languages

    Answers questions on strength, mg/ml, spectrum, price and delivery, with no medical claims, no dosing and no invented stock.

    • 9 languages
    • Clear guardrails

CH. 06 / 06 — Scale & pace

Nine stores in 23 days

From the first line of code on 11 June to the ninth store on 4 July. Then the platform kept growing: card payments, fulfilment, tracking and content in nine languages.

  1. First line of code
  2. Bulgaria live
  3. 8 stores live
  4. The ninth: Hungary
  • 9

    stores, one core

  • 553

    indexable pages with hreflang

  • 102

    localised articles

  • 15

    local carriers

  • 5

    currencies

  • 3,000+

    automated tests

  • Technical facts as of 26 Sep 2026. No business figures.

Plates

PL. 01—03

cannapopolis.ro
Cannapopolis Core: the Romanian store’s homepage with a field video and the product row — Scroll preview
PL. 01 — Cannapopolis Core · Scroll previewOpen the full-page image (opens in a new tab)
The Bulgarian checkout: Econt, Speedy, Pigeon, BOX NOW and cash on delivery
PL. 02 — Cannapopolis Core · desktop
Dutch product page on a phone with the Profile / Cart / AI bar
PL. 03 — Cannapopolis Core · mobile

Palette & type

  • #173127Forest ink
  • #0E6B3DMoss
  • #1F9D55Leaf
  • #EEF8F0Mint
  • #FBFCF8Cream
  • Cormorant Garamond
  • Inter

Contact

Want something like this?

Your project could be Fig. 07.

30 minutes, no commitment. You’ll leave with concrete ideas for your website, processes or product.

FIG. 07 — Your project30 minutes · no commitment · we reply within a few hours on business days