Skip to content
Online store and company website. No cut of your revenue. Start for free.

Partner frontend

You do not have to assemble a client's design and frontend from the platform template. You can change the look through files, or build your own application on top of the Shop API. Checkout, payments and the customer account always stay on the platform.

Two ways

  • Look as files. The store runs on a platform template and you change its theme, the store layout, the home page, custom CSS and website pages. You keep the files in git and upload them with portican vzhlad as a draft; the merchant publishes it. See the section Look as files below.
  • Your own frontend. You write your own application that reads the store catalogue and content through the Shop API using the @portican/storefront SDK. It runs on your side, not on Portican. See the section SDK client below.
  • You can combine either way with what Markup hooks, Blocks and fields and Website preset describe. Read the content the merchant is meant to edit from the store (settings, website pages, products): the admin edits only what the platform knows, not blocks you invent in your own code.

From the key to a deployed frontend

  1. The store operator creates a frontend key in the admin under Shop › Integrations: they name it and enter the website addresses the browser will call from. An address is https without a path and must not belong to the platform or its subdomain; at most 5 addresses per key and 5 keys per market. The key is shown only once.
  2. The market token and the Shop API address of the store are on the same screen, with a button to copy the address; the server builds the address from the market domain, so do not guess it from examples. The key is valid only with the token of its own market, sent in the portican-kluc-frontendu header together with the vendure-token header.
  3. Install the SDK from npm with npm install @portican/storefront. The package is public on npm and has no dependencies; every version is published only by Portican CI from the main branch.
  4. On the server (SSR) create the client with the key; in the browser create it without the key. The example is below in the section SDK client.
  5. Read the catalogue, settings and website pages. Keep the cart on your side and hand it to the platform with a one-time code at checkout (section Cart and checkout).
  6. You deploy the frontend on your own hosting. Portican does not host or run it; the website address must match the address you entered with the key.

What the key allows

  • A frontend key allows only public read queries from the list below and a single mutation, odovzdajKosik. Every other operation ends with the error KLUC_FRONTENDU_OPERACIA.
  • A request with the key, or from the registered website address, carries no customer session. Partner code does not create a Vendure cart and cannot see the account, orders, payments or links with a token.
  • The limit is 3,000 requests per minute per key. To the platform a partner server is a single address for all its visitors, so it can sign the visitor's address with the key secret in the x-portican-navstevnik header (the SDK does that when you pass adresaNavstevnika); the limits then apply per visitor. Without a signature, a limit per server address applies alongside the key limit.
  • When the limit is hit you get the PRILIS_VELA_POZIADAVIEK error with the number of seconds to wait. A wrong, revoked or foreign key returns KLUC_FRONTENDU_NEPLATI. The operator revokes a key in the admin and the website stops loading products.
  • The key belongs on the server only. The browser calls the Shop API without the key, and only from the registered website address (CORS). A key in code delivered to the browser could be used by anyone.

Queries the key allows

The public catalogue and store content. Nothing about the customer, the order or links with a token. The list is an allow list, not a block list: a new plugin query is not open by itself.

From the platform code. This list is built directly from the platform source code, and every deployment checks that the two still match.

  • activeChannel
  • availableCountries
  • collections
  • collection
  • facets
  • facet
  • products
  • product
  • search
  • storefrontSettings
  • schemaBlokov
  • strankyWebu
  • strankaWebu
  • suboroveStrankyObchodu
  • suborovaStrankaObchodu
  • pravneTextyObchodu
  • pravnyTextObchodu
  • vypisBlogu
  • clankyBlogu
  • clanokBlogu
  • adresyClankov
  • jazykyClanku
  • mapaClankov
  • akcioveProdukty
  • produktyPodlaId
  • najpredavanejsieProdukty
  • novinkyProdukty
  • odporucaniaKProduktu
  • vacsieVarianty
  • recenzieProduktu
  • socialnyDokazProduktu
  • nastavenieVypredanych
  • skryteProdukty
  • cenovePasma
  • presmerovaneKategorie
  • presmerovaneKarty
  • presmerovaniaObchodu
  • zobrazenieTrhu
  • sviatocneTerminy
  • blokyPartnera

SDK client

The SDK is a typed Shop API client with no dependencies. It runs in Node 18 and later, in Cloudflare Workers, in Deno and in the browser. It reads store settings, categories, products, search and website pages.

Errors carry a code (kod), the HTTP status (stav) and, at the limit, cakajSekund. The headers and error codes in the SDK match the platform core; a package test guards that.

What the SDK cannot do yet: legal texts of the store through the Shop API, and rendering page blocks and home page sections. You assemble those in your frontend yourself.

import { vytvorKlienta, ChybaObchodu } from '@portican/storefront';

const obchod = vytvorKlienta({
    adresaApi: process.env.PORTICAN_ADRESA_SHOP_API!, // Shop API obchodu
    tokenTrhu: process.env.PORTICAN_TOKEN_TRHU!,
    kluc: process.env.PORTICAN_KLUC_FRONTENDU, // len na serveri, nikdy v prehliadači
    jazyk: 'sk',
});

try {
    // Na serveri s adresou návštevníka, aby stropy platili na neho, nie na celý server.
    const produkt = await obchod.produkt('kytica-ruzi', { adresaNavstevnika: request.ip });
    const vysledky = await obchod.hladaj({ vyraz: 'ruže', take: 24 });
    const nastavenia = await obchod.nastavenia();
    const stranka = await obchod.stranka('o-nas');
} catch (e) {
    // Pri strope príde kód chyby so sekundami, ktoré treba počkať.
    if (e instanceof ChybaObchodu && e.strop) await pockaj(e.cakajSekund ?? 1);
    else throw e;
}

Cart and checkout

  • The cart is a list of variants and quantities in your frontend, at most 50 lines and 999 units of one variant. The platform does not accept a bigger cart and does not round it quietly: the partner sees an error.
  • At checkout you call odovzdajKosik. You get a one-time code that is valid for 10 minutes and works once. At most 120 hand-overs per minute are allowed per key or website address.
  • The customer brings the code in a POST form to /prevziat-kosik of the store (or /<language>/prevziat-kosik), never in the address. Checkout takes the cart over only from the website that handed it over, so the form must be sent from the registered website address.
  • Prices, stock, delivery and discounts are calculated by the platform, not by your code. A variant outside the store is rejected at hand-over, and a sold-out unit simply drops out of the cart on take-over. The order is created only by checkout, in the customer's session.
import { nacitajKosik, pridajDoKosika, ulozKosik, formularPokladne } from '@portican/storefront';

// Košík je zoznam variantov a množstiev u vás (localStorage, cookie, KV).
const kosik = pridajDoKosika(nacitajKosik(localStorage), variantId, 1);
ulozKosik(localStorage, kosik);

// Pri pokladni ho odovzdáte platforme; ceny, sklad a dopravu prepočíta ona.
const { kod } = await obchod.odovzdajDoPokladne(kosik);
const f = formularPokladne(kod, 'https://www.obchod-klienta.sk', 'sk');
// <form method="POST" action={f.action}><input type="hidden" name="kod" value={f.polia.kod} /></form>

Look as files: command line

  • The portican vzhlad command downloads the store look (theme, store layout, home page, custom CSS and website pages) as files that you keep in git, and uploads them back as a draft. The merchant previews the draft and publishes it on their own in the admin on the Look versions screen. The command line publishes nothing.
  • It needs an API key with the Look drafts scope (Shop › Integrations, see Webhooks and API). The key belongs in the PORTICAN_API_KLUC environment variable, never in the command: it would stay in the shell history. For a store with several markets set the market token in PORTICAN_TRH.
  • verzie lists the look versions, pull downloads the published (or a chosen) version, push uploads the folder as a new draft and prints how many parts it changes compared with the live look, and nahlad prints a preview link that is valid for an hour. A package must not exceed 2 MB.
  • The JSON files have sorted keys and indentation, so the git diff shows only the real change. Run the command line without installing it via npx @portican/cli vzhlad, or add it to your project (npm install --save-dev @portican/cli).
export PORTICAN_API_KLUC="..."   # kľúč s rozsahom Vzhľad, nikdy v príkaze

portican vzhlad verzie
portican vzhlad pull --do vzhlad
portican vzhlad push --z vzhlad --nazov "Jesenná kampaň"
portican vzhlad nahlad

Block schema

  • The Shop API serves the schemaBlokov query: a machine-readable description of page block and home page section kinds with fields, types, length and count limits, options and a version. With it you can check which fields a block carries without reading the platform code.
  • The schema is public and read-only, the same for every market and free of store data. The version rises with every change of fields, types or limits and is confirmed by a fingerprint, so you can tell whether you know exactly that version.
  • The schemaBlokov query is in the list of frontend key queries above, so the SDK can call it with the key too. The schema is public and the same for every market, so the key reveals nothing new.

What the platform does not do

  • Checkout, sign-in, the customer account, payments and refunds are always on the platform. A partner frontend has no access to them and payment data does not pass through it.
  • Portican does not host, build or deploy a partner frontend. For your own frontend the platform gives you today a key, the Shop API, the SDK and the cart hand-over.
  • Do not hard-code texts and images that the merchant is meant to change: read them from the settings, website pages and products the merchant edits in the admin.