@base44/app-plugin-commerce
v0.10.6
Published
Base44 Commerce plugin — entities, backend functions, shared commerce engine, admin UI and the commerce skill, shipped as copyable source
Readme
Base44 Commerce Template
A Commerce backend + admin UI for Base44 apps, delivered as a copyable file set. Drop base44/ and src/commerce/ into an existing Base44 app to add a full store: catalog, orders, coupons, customers, reviews, tax, shipping, webhooks, reports and transactional emails — plus a public storefront API for building your own shopfront.
It provides a full-featured commerce data model and behavior (variant-driven products, order lifecycle, coupon rules, per-location shipping and tax) using Base44-idiomatic primitives (entity JSON schemas, Deno functions, the Base44 SDK).
What's included
- 20 entities — Products (a product sells variants when it carries attributes; no type field), variations, categories, ribbons, attributes + values, reviews, orders (embedded line/shipping/tax/fee/coupon lines), order notes, refunds, coupons, customers, Shipping & Tax Locations (shipping rates + tax groups per location), payment gateways, store settings, webhooks + deliveries, carts, download permissions, email log.
- 16 backend functions — 9 admin (
commerce/admin-products,commerce/admin-orders,commerce/admin-refunds,commerce/admin-coupons,commerce/admin-customers,commerce/admin-reviews,commerce/admin-webhooks,commerce/admin-reports,commerce/admin-tools), 4 storefront (commerce/storefront-catalog,commerce/storefront-cart,commerce/storefront-checkout,commerce/storefront-account), 2 payment (commerce/payments,commerce/payment-webhook), and an idempotentcommerce/seed-store— one call seeds the business defaults and the whole catalog (products with attributes in, variants/categories/taxonomy created internally). - Payments: manual methods work out of the box; online cards are opt-in — the seed enables the manual
offlinemethod (bank transfer, cash on delivery, pickup: on-hold + instructions, no code) and leaves thecardgateway disabled. The order side of card payments is premade — checkout routing, payment links for unpaid orders, two idempotent confirmation paths (customer return + webhook) and refund records — so a store that opts in wires a provider by implementing four functions in one file,base44/shared/commerce/card-payment.ts. For Stripe there is nothing to write:base44/shared/commerce/card-payment.stripe.tsis a complete implementation used as-is — copy it over the stub and enable the gateway. Any other provider (PayPal, Adyen, a local PSP) follows the same shape. Enable the gateway only with a provider behind it, or checkout answers503 no_card_payment_provider. The rule and timing:skills/commerce/installation/install.md; provider mechanics:skills/commerce/references/online-payments.md. The admin can add more manual methods in Settings → Payments. - Shared commerce engine (
base44/shared/commerce/) — totals, tax, shipping, coupons, stock, order lifecycle, webhook dispatch (HMAC-signed), emails, card-payment plumbing, plus static country/currency/continent data. - Admin UI (
src/commerce/admin/) — a React/Tailwind/shadcn admin with a familiar store back-office information architecture: dashboard, orders, products, coupons, customers, reports, and full settings including webhooks. Admin-role gated. Renders in the store's own theme, with a topbar toggle to a neutral Base44-dashboard palette and font for stores whose site theme makes the back office hard to read (colors and fonts only; remembered per browser). Localized — ships in English (default), German, Spanish, French, Japanese and Portuguese, switched by one line of code, with a documented recipe for adding any other language (no i18n dependency; seesrc/commerce/admin/README.mdand the skill'sreferences/admin-localization.md). - Storefront helpers (
src/commerce/utils/) — framework-free, dependency-free modules for the shopfront you build:storefront.jsis the API client (createStorefront(base44)— cart-token lifecycle, cached store-info, catalog/cart/checkout/reviews/return-page calls);variants.jsmaps an attribute selection (Size, Color) onto aProductVariationand back, plus per-option availability and price ranges;price.jsencodes the from-price and price-range rules;totals.jsprojects a cart or an order into one summary shape;address-spec.jsis the checkout address form as data;images.jsandribbons.jsnormalize the two catalog fields that are arrays of objects ({src, name, alt}images,{id, name}ribbons) rather than strings;types.jswrites the catalog shapes down as JSDoc typedefs (StorefrontProductand the rest), so what a field holds is answerable from the frontend;shipping-promos.jsreads the store's real free-shipping configuration so "Free shipping over €150" states a configured rule rather than an invented number. - Storefront React layer (
src/commerce/storefront/) — headless: the logic is premade, the UI never is. Nothing in the layer renders markup or carries CSS; every element, class and word of copy in the catalog pages you build is yours, so a brief like "make it feel like " applies to the pages that carry the store's identity. It ships no customer-facing copy either: where a state needs words you get the state —buy.state, a picker'shint.code, the checkout'sblockers, a review'sstatus— and write the sentence. What ships is every piece of logic that is the same in all stores:StorefrontProvider(+useStorefront/useStoreInfo/useFormatMoney/useCountries),useProductList/useCategories/useRibbons,useProduct/useAddToCart,useCart/useCartLine(+useCartUI/CartUIProviderfor a drawer),useCheckout/CheckoutProvider/useCheckoutContext,useOrderReturn/orderReceivedUrl— plus three render-prop components that stay just as headless (ShippingMethodPicker/PaymentMethodPickerfor the two checkout choices that are store data,CartLinefor per-row cart bindings), one deliberately rendered-but-unstyled component (AddressFields— the checkout address form, whose state/province andautoCompletemechanics are where hand-rolled forms break; it ships no CSS and styles viadata-partselectors or class props), and the framework-free view-model helpers re-exported so one import line covers a page (variantAxes,productPrice,productImages,productRibbons,productSpecs,attributesLabel,cartTotalsLines/orderTotalsLines,addressFieldSpec). Each hook's doc comment states the render rules that keep a store correct (an unbuyable variant option renders disabled, not hidden; a receipt page must renderpaymentInstructions; …) and names its return type fromstorefront/types.js, so a page reads a field's shape off the hook instead of off a backend function. Needs React and nothing else. - Shipped conversion surfaces (
src/commerce/storefront-ui/) — the four pages that must convert, finished:<CartPage />,<MiniCart />(a real dialog: portal, focus trap, scroll-lock, opens on add-to-cart),<CheckoutPage />(addresses, shipping/payment choice, blockers, offline instructions and card redirect) and<OrderReceivedPage />(all return states incl. payment instructions), plus an optional<CartButton />header trigger. Built on the headless layer above; themed through a paired--sfui-*token block with shadcn-variable fallbacks and a runtime contrast guard (an unreadable pair falls back to the defaults), functional labels localized in six languages (storefront-ui/i18n/), brand wording viabrandprops, behavior viasections/slots. Kit-owned and re-copied on updates — customization goes through tokens/props/slots (skills/commerce/references/storefront-ui.md), never file edits. - StoreAdmin agent + bot — an AI copilot (
base44/agents/commerce/StoreAdmin.jsonc, registered ascommerce/StoreAdmin) with thecommerce/*functions attached directly as tools (calls run as the chatting user →requireAdmin()still applies), variant-aware order editing, plus a chat panel in the admin sidebar with GFM markdown-table rendering. - Docs — this README plus the commerce skill folder
skills/commerce/:SKILL.mdis the map every agent starts from (and the only path the platform needs to know);install/holds the three stage files that are the whole install (01-install→02-storefront→03-data, each read at the moment its work starts and dropped when its checklist passes);references/holds per-topic guides opened only on demand;docs/holds the data-model map (entities.md) and the two API references. The whole folder is installed into the app at.agents/skills/commerce/so agents pick it up natively.
Repo map
base44-commerce-template/
├── base44/
│ ├── entities/ 20 .jsonc entity schemas (commerce.*.jsonc)
│ ├── functions/
│ │ └── commerce/ 16 Deno functions (entry.ts each), invoked as "commerce/<name>"
│ ├── agents/
│ │ └── commerce/ StoreAdmin.jsonc — AI admin copilot ("commerce/StoreAdmin")
│ └── shared/
│ └── commerce/ commerce engine + static data (bundled into every function)
├── src/
│ └── commerce/
│ ├── admin/ React admin UI (copy into your app's src/commerce/)
│ ├── utils/ storefront helpers — API client, variants, price/totals rules
│ ├── storefront/ storefront React layer — headless hooks (catalog, cart,
│ │ checkout, receipt); no markup, CSS or copy ships
│ └── storefront-ui/ shipped conversion surfaces — CartPage, MiniCart,
│ CheckoutPage, OrderReceivedPage; tokens + brand props
├── scripts/
│ └── install.js static installer (run from <app>/examples/commerce/scripts/)
├── skills/
│ └── commerce/ commerce skill — copied into the app's .agents/skills/
│ │ so agents know the store natively
│ ├── SKILL.md the map: what to read, when, and what to skip
│ ├── install/ the whole install, in three staged files
│ │ ├── 01-install.md files, admin mount, role gating, the schedule
│ │ ├── 02-storefront.md storefront pages on the headless hooks
│ │ └── 03-data.md seeding, shipping zones, images, payments decision
│ ├── references/ opened on demand (catalog rendering, shipping & tax,
│ │ online payments, reviews, store settings, emails,
│ │ admin product form, StoreAdmin agent, security, operations)
│ └── docs/
│ ├── entities.md the data-model map (addressing, all 20 entities)
│ ├── api-admin.md admin function reference + the seed contract
│ └── api-storefront.md storefront function reference
└── README.mdGet it from npm
The template is published as @base44/app-plugin-commerce — a source-only package whose tarball is exactly the base44/, scripts/, skills/ and src/ folders of this repo, with no build or bundling step. Unpack it into your app at examples/commerce/ and the install flow below works unchanged:
npm pack @base44/app-plugin-commerce # → base44-app-plugin-commerce-<version>.tgz
mkdir -p examples/commerce
tar -xzf base44-app-plugin-commerce-*.tgz --strip-components=1 -C examples/commerce
node examples/commerce/scripts/install.jsscripts/install.js resolves the app root relative to its own location (<app>/examples/commerce/scripts/), so run it from the unpacked copy rather than from inside node_modules/.
Quick start (Base44 CLI)
From your existing Base44 app:
- Copy the files — either copy this whole repo into your app at
examples/commerce/and runnode examples/commerce/scripts/install.js, or mergeentities/,functions/,shared/into your app'sbase44/directory by hand (seeskills/commerce/installation/install.md). Confirm yourbase44/config.jsoncentitiesDir/functionsDirpoint at these folders. - Push the schema, functions and agent:
npx base44 entities push npx base44 functions deploy npx base44 agents push - Copy the UI files:
src/commerce/admin/→src/commerce/admin/,src/commerce/utils/→src/commerce/utils/andsrc/commerce/storefront/→src/commerce/storefront/. - Confirm UI deps —
sonner,rechartsandreact-markdownall ship with the default Base44 template and are the only ones the admin needs, so usually there is nothing to install. Read your app'spackage.jsonfirst and install only the names missing from it — never re-install a package that is already a dependency:
Seegrep -E '"(sonner|recharts|react-markdown)"' package.json # all three listed → skip the install npx npq install <only the missing names> # npq audits the package before npm installs itsrc/commerce/admin/README.mdfor the exact shadcn component list. - Mount the admin as a layout route in your app's
src/App.jsx— Base44 discovers an app's pages by reading the literal<Route>JSX in that file, so the screens that should be listed as pages are declared there and the rest run off a splat handled by the kit's own router:
Name the section they group under inimport AdminApp, { AdminRoutes } from "@/commerce/admin"; // inside your <Routes>: <Route path="/store-admin" element={<AdminApp />}> <Route index element={<Dashboard />} /> <Route path="orders" element={<OrdersList />} /> {/* …products, customers, coupons, reports… */} <Route path="*" element={<AdminRoutes />} /> {/* editors, settings, webhooks */} </Route>base44/ui.jsonc(app-owned — edit in place):{ "version": 1, "sections": [{ "path": "/store-admin/*", "name": "Store Management" }] } - Grant yourself the
adminrole (Base44 dashboard → users, orusers.inviteUser(email, "admin")). The admin UI refuses non-admins. - Seed the store. Either open
/store-adminand click Initialize store defaults on the first-run setup screen, or callcommerce/seed-storedirectly — it creates the settings groups, the payment gateway rows (offlineenabled,cardoff — enable it only with a provider wired) and — unless you pass your ownlocations— a fallback Shipping & Tax Location, plus the catalog: passproducts(whole products with attributes — variants, categories, ribbons and taxonomy are created internally) orwith_sample_data: truefor the generic demo. Either way passstore_name(the app's name) — it is required on a first seed and becomes both the email subject prefix and the sender name. Once thegeneralsettings group exists the store counts as ready and the first-run screen stops appearing. Worked example:skills/commerce/installation/install.md; the full payload contract:skills/commerce/docs/api-admin.md. Shipping zones are part of the same call —locationstakescontinents: ["EU"]andrest_of_world: true, so "€20 in Europe, €100 worldwide" is six lines.
Quick start (Base44 MCP / hosted apps)
If you build on Base44's hosted platform, use the Base44 agent/MCP to write the files instead of the CLI:
- Copy this whole repo into the target app at
examples/commerce/(e.g. download + extract a tarball withrun_command), then runnode examples/commerce/scripts/install.jsviarun_command— or usewrite_fileto copy every file underbase44/andsrc/commerce/individually (uselist_directory/read_fileto adapt to the app's actual layout — e.g. the@/api/base44Clientpath and your router file). - Wait for the app to build (
get_app_status), then confirm entities exist (list_entity_schemas). - Grant your user the
adminrole, then seed the store's data — onecommerce/seed-storecall takes the whole catalog viaproducts, orwith_sample_data: truefor the demo catalog; leave both out for defaults only, or skip the call for the admin's first-run Initialize store defaults screen (skills/commerce/installation/install.md).
What's NOT included
- No storefront design. The parts of a shopfront that carry a brand — the home page, the collection grid, the product card, the product page's layout, the theme — ship as nothing at all, on purpose: that is the work a build should spend its effort on. Everything under those surfaces does ship: the storefront API and the hooks that own the logic of every surface (catalog, product, cart, checkout, order-received, reviews) — the markup, styling and copy on top of them stay yours, including the commodity screens — see
skills/commerce/installation/install.mdfor how the two tiers fit together,skills/commerce/references/catalog-rendering.mdfor what each catalog call returns, andskills/commerce/docs/api-storefront.mdfor the raw API. - No payment provider — and cards are off by default. The order side of card payments is premade (see above), but charging a card needs a provider, so
commerce/seed-storeenables the manualofflinemethod (bank transfer, cash on delivery, pickup — no code, no credentials) and leaves thecardgateway switched off. Enable cards only if a provider is wired, or is about to be — implement the four functions inbase44/shared/commerce/card-payment.ts, or for Stripe copy the shippedcard-payment.stripe.tsover it and use it as-is (skills/commerce/references/online-payments.md), then enable the gateway via the seed'spayment_methods: ["offline", "card"]; enabled with nothing behind it, checkout answers503 no_card_payment_provider. The rule and why it belongs at the end of a build rather than its start:skills/commerce/installation/install.md. - No scheduled workflows shipped. Base44 does have a scheduler, but this template ships no workflow files — time-based jobs (stock-hold release, cart expiry, webhook-log pruning) run opportunistically where possible, and for the rest you (or the Base44 agent) create scheduled workflows that call
commerce/admin-tools/commerce/admin-ordersactions — seeskills/commerce/references/operations.md.
Next steps
- Install into your app:
skills/commerce/installation/install.md - Operate & extend: the commerce skill —
skills/commerce/SKILL.md - Build a storefront:
skills/commerce/docs/api-storefront.md - Admin automation / alternative admin:
skills/commerce/docs/api-admin.md
Releasing (maintainers)
Publishing is manual: Actions → Manual Package Publish → Run workflow (.github/workflows/manual-publish.yml).
Inputs: version (patch/minor/major or an explicit 0.2.0), npm_tag (latest, beta, …) and dry_run. The workflow bumps package.json, prints the tarball contents, runs npm publish, then commits the bump, tags v<version> and cuts a GitHub release. A dry run publishes nothing and leaves no tag or commit.
Registry auth uses npm trusted publishing — the workflow holds no npm token. It authenticates over OIDC (id-token: write plus npm install -g npm@latest, which needs npm ≥ 11.5.1), which also signs a provenance attestation for each release. This requires a trusted publisher on the npm package (Settings → Trusted Publisher → GitHub Actions, repository base44/app-plugin-commerce, workflow manual-publish.yml, no environment); if that config is missing or the workflow filename changes, publishing fails with ENEEDAUTH.
Pushing the release commit and tag additionally needs the org's BASE44_GITHUB_ACTIONS_APP_ID variable and BASE44_GITHUB_ACTIONS_APP_PRIVATE_KEY secret.
