Online shop
Theme development
A theme is the look of a BaxPay storefront: colours, fonts, homepage sections and optional custom CSS. Build one in Theme studio, share it as a file, or sell it on the BaxPay theme store.
Who can make themes
Any BaxPay business, on any plan, without needing an online shop of its own. Join the theme developer program in the Business dashboard: Theme studio (sidebar → Workspace), with a public developer profile (name, support email, optional website and description) and the developer terms. Payouts go to the business's BaxPay account.
| Action | Owner / Admin | Manager | Viewer / Attendant |
|---|---|---|---|
| See themes and sales | ✓ | ✓ | ✓ |
| Create and design themes, edit the listing, delete | ✓ | ✓ | — |
| Join the program, set a price, submit, withdraw | ✓ | — | — |
What a theme contains
TokensSectionsCustom CSSoptionalA theme never carries content. When it is saved to the store or exported, your texts, photos, links and chosen products are removed. When a merchant applies it, their own texts, photos and products are laid into your layout; sections your theme leaves out are kept but hidden, so nothing they wrote is lost. Design for content you have never seen: long and short names, with and without photos, few or many products, services only.
Quick start
Join the program
New theme
Design
Store listing
Submit
The theme file
Themes travel as a baxpay-theme JSON file (version 1). Theme studio can start from one, and
Online shop → Design → Themes → Export my theme downloads a shop's design as one (content
already removed). The importer also accepts a bare { "tokens": …, "sections": … } object.
{
"format": "baxpay-theme",
"version": 1,
"name": "Atelier Nord",
"category": "crafts",
"description": "Warm, editorial look for makers and small workshops.",
"author": "Studio Nord",
"theme": {
"tokens": {
"primaryColor": "#2B2420",
"accentColor": "#A4552E",
"backgroundColor": "#F7F3EE",
"surfaceColor": "#FFFDF9",
"textColor": "#2B2420",
"mutedColor": "#7A6E66",
"fontHeading": "Fraunces",
"fontBody": "Lora",
"borderRadius": "0.25rem",
"colorMode": "light"
},
"sections": [
{ "id": "announcement", "type": "announcement", "visible": true, "props": {} },
{ "id": "hero", "type": "hero", "visible": true, "props": { "layout": "split", "align": "left", "height": "lg", "overlayOpacity": 30 } },
{ "id": "categories", "type": "categories", "visible": true, "props": { "style": "tiles" } },
{ "id": "featuredProducts", "type": "featuredProducts", "visible": true, "props": { "limit": 8 } },
{ "id": "imageText", "type": "imageText", "visible": true, "props": { "imageSide": "left" } },
{ "id": "contact", "type": "contact", "visible": true, "props": { "showHours": true, "showMap": false } },
{ "id": "footer", "type": "footer", "visible": true, "props": { "showPoweredBy": true } }
],
"customCss": ".shop-root h1,.shop-root h2{letter-spacing:-.02em}"
}
}formatstringrequired"baxpay-theme".versionnumberrequired1. A higher number is refused as made for a newer version of BaxPay.namestringcategorystringgeneral, fashion, home, food, beauty, tech, crafts, services, kids, sports, luxury, florist or books; anything else becomes general.descriptionstringauthorstringthemeobjectrequiredtokens and sections, plus optional customCss.Everything is cleaned on import: a value outside the rules falls back to the default instead of failing the import. Check the result in the builder.
Tokens
| Token | Allowed values |
|---|---|
primaryColor, accentColor, backgroundColor, surfaceColor, textColor, mutedColor | Hex colour, #RGB or #RRGGBB (#RGB is stored as #RRGGBB) |
fontHeading, fontBody | Inter, DM Sans, Space Grotesk, Outfit, Manrope, Sora, Playfair Display, Fraunces, Libre Baskerville, Cormorant Garamond, Poppins, Montserrat, Lora, Nunito, Quicksand, Syne, Archivo, Josefin Sans, EB Garamond, Work Sans, Rubik, or system-ui (Google Fonts, weights 400–700) |
borderRadius | 0 to 99 (up to three decimals) in rem or px, e.g. 0.75rem, 12px |
colorMode | light or dark |
containerWidth | narrow, normal, wide, full |
sectionSpacing | compact, normal, spacious |
headingWeight | 400, 500, 600, 700, 800 |
headingCase | normal, uppercase |
headingTracking | tight, normal, wide |
baseFontSize | sm, md, lg |
buttonStyle | pill, rounded, square |
buttonSize | sm, md, lg |
cardStyle | flat, bordered, shadow, filled |
imageRatio | square, portrait, landscape, tall |
imageFit | cover, contain |
hoverEffect | zoom, lift, fade, none |
priceStyle | default, accent, muted |
catalogColumns | 2 to 5 |
headerLayout | left, center, split |
headerStyle | solid, blur, transparent |
headerSticky, showSearch, showAccount | true or false |
The text colour on primary and accent buttons is picked automatically (dark or white) for contrast.
Sections
Up to 40 sections, drawn in order. id is free text (up to 64 characters); visible: false keeps
a section but hides it. Only style props are part of a theme; content props (titles, text,
links, images, items) belong to the merchant and are dropped from saved and exported themes.
Every section also takes a design object: paddingY (default, none, sm, md, lg, xl),
background (default, surface, tint, primary, accent, custom with backgroundColor),
width (default, narrow, wide, full), titleAlign (left, center) and headingSize
(sm, md, lg).
| Type | Main style props |
|---|---|
announcement | variant: bar | marquee; dismissible |
hero | layout: overlay | split | stacked; align: left | center | right; height: sm | md | lg | full; overlayOpacity: 0–80 |
featuredProducts, catalogGrid | limit: 1–48; layout: grid | carousel; columns: 2–6; columnsMobile: 1–2; showPrice, showCategory, showQuickAdd, showViewAll |
categories | style: tiles | chips | circles | list | cards; columns: 2–6; limit: 1–24; showCount |
about | align: left | center; columns: 1–2 |
imageText | imageSide: left | right |
richText | align: left | center; size: sm | md | lg |
video | autoplay |
countdown | style: banner | card |
features | layout: grid | list | centered; columns: 2–4 |
steps | layout: row | column | cards |
testimonials | layout: grid | carousel | single; columns: 1–4; showRating |
faq | layout: accordion | twoColumn | cards; openFirst |
ctaBanner | align: left | center; size: sm | md | lg |
trustBadges | layout: inline | cards | centered; columns: 2–6 |
logoBar | size: sm | md | lg |
gallery | layout: grid | masonry | featured | carousel; columns: 2–6 |
productSpotlight | imageSide: left | right; showPrice |
promoTiles | Tile layout |
team | columns: 2–5 |
services | limit: 1–24; layout: cards | list | grid; columns: 1–4; showDescription, showDuration, showPrice, showViewAll |
contact | layout: card | split | centered; showEmail, showPhone, showAddress, showSocials, showHours, showMap |
divider | height: sm | md | lg | xl |
footer | layout: columns | simple | centered; showPoweredBy, showSocials, showPolicies, showContact, showPayments |
A value outside these rules falls back to the section's default.
Unknown section types are dropped. Product, catalog, cart, checkout and order pages are not sections: they follow your tokens and custom CSS.
Custom CSS
Your CSS is added after the storefront's base styles on every page, so it can override them. Style with the variables below so the merchant's colour changes keep working.
--shop-primary, --shop-on-primary--shop-accent, --shop-on-accent--shop-bg, --shop-surface--shop-text, --shop-muted--shop-border--shop-radiusborderRadius token.--shop-font-heading.shop-root).Stable hooks: .shop-root (the storefront wrapper), [data-section="hero"] and the like
(every section of a type), and the base classes .shop-btn,
.shop-btn-primary (accent), .shop-btn-dark (primary), .shop-btn-ghost (outlined),
.shop-card, .shop-input, .shop-muted, .shop-heading. Utility class names in the
storefront's markup can change without notice; these hooks stay. Don't style #section-<id> in a
theme: when a merchant applies it, section ids are renamed to their own.
/* Square, outlined buttons everywhere */
.shop-btn { border-radius: 0; text-transform: uppercase; letter-spacing: .08em; }
.shop-btn-primary { background: transparent; color: var(--shop-accent); border: 2px solid var(--shop-accent); }
/* A tinted band behind the FAQ */
[data-section="faq"] { background: color-mix(in srgb, var(--shop-accent) 6%, var(--shop-bg)); }Test light and dark mode, a phone-width screen, a long shop name, a hero without a photo and a shop with only services. Never hide or disguise prices, taxes, delivery costs, the cart, the checkout, legal or consent links, or the merchant's "Powered by" choice.
Review
Every submission is reviewed by BaxPay before it appears on the store. Reviewers check that:
- It works: readable and usable on phone and desktop, with real-world content.
- It is honest: name, description, category and preview image show what the buyer gets.
- It keeps the shop safe and legal: nothing hidden or disguised (see above), no imitation of BaxPay's payment page or another brand.
- It is original: no copy of another theme or company's look, no third-party assets you may not sell.
- The price is fair compared with the free BaxPay themes.
Private (DRAFT)
In review (IN_REVIEW)
On the store (PUBLISHED) or Changes needed (REJECTED)
Withdrawn (UNPUBLISHED)
Changing a published theme's look or price sends it back to review (it is off the store until approved again); name, category, description, demo link and preview changes do not. Shops are not updated automatically: a theme is copied into a shop when applied, so buyers apply it again to get a new version. A theme can only be deleted while no shop holds a licence for it.
Selling and getting paid
- A paid theme is sold through your own BaxPay payment link: you are the seller and the money reaches your BaxPay account and payouts like any other sale.
- BaxPay takes a commission on each paid sale (15 % by default), fixed when the sale starts and taken with the usual payment fee. You keep the rest. Prices are in euros, within the range BaxPay sets for the marketplace.
- A paid price needs card payments set up on your business (Settings → Payments).
- The buyer's licence turns active as soon as the link is paid. Free themes are available at once and carry no commission.
- A full refund or a lost dispute withdraws the buyer's licence automatically; the design already saved in their shop stays.
- Theme studio → Sales lists every sale with the price, the commission and what you keep.
Theme studio API
The dashboard uses these endpoints with a signed-in dashboard session (not an API key). Paths are
under https://api.baxpay.com/v1.
/business/theme-studioprogram terms, my profile, totals/business/theme-studio/join{ displayName, supportEmail, websiteUrl?, bio?, acceptTerms: true }/business/theme-studio/profile/business/theme-studio/themes/business/theme-studio/themes{ name, category, start: preset | shop | file | blank, presetId?, package? }/business/theme-studio/themes/{id}/business/theme-studio/themes/{id}name, category, description, demoUrl, previewImageKey, priceMinor, theme/business/theme-studio/themes/{id}/submit/business/theme-studio/themes/{id}/unpublish/business/theme-studio/themes/{id}only without licences/business/theme-studio/sales?page=priceMinor is in cents: 0, or inside the marketplace range. previewImageKey is the key of an
image uploaded as shop media.
Related
- Online shop — how storefronts work
- Storefront API — headless front ends
- Payment links — how paid themes are sold