profound-logoProfound CMS
⌘K
Admin
Theme
DocsTutorialBlogPhilosophy
DocsTutorialBlogPhilosophy

Tutorials

Build & Ship an Airport DirectoryDeploymentsBuild & Ship a Stripe Storefront

Feature

Documentation Site TemplateFeature Template BuilderTranslation ServiceOrganizations & Website HeirarchyConnect Profound CMS to your AI clientSettings IntegrationsSettings API KeysSettings UsageSettings Websites
All Systems Operational
Powered Byprofound-logo
Theme

Build & Ship a Stripe Storefront

En praktisk gennemgang: byg en indholdsbaseret Stripe-butik på Profound CMS — et katalog, en forhandler kan redigere uden kode, to parametriske ruter, en headless kurv og Stripe-hostet checkout.

Den færdige butik i bevægelse — gennemse en kategori, åbn et produkt, læg i kurv, gennemfør betaling.

En praktisk gennemgang, der bygger en indholdsbaseret butik på Profound CMS: et produktkatalog (kategorier + varer) modelleret i CMS'et, liste- og detaljesider fra ét sæt ruter og en Stripe-hostet checkout, leveret som en headless komponent.

Rygraden er håndskrevet Next.js plus Profound-admin. Claude Code (via Profound MCP) tager sig af det tunge arbejde på tre opgaver — seedning af kataloget, tilkobling af designsystemet og skrivning af butikskomponenterne (inklusive den headless kurv). Tre dele: Opsætning, Opbygning, Produktion.

Betalinger på én linje. Vi bruger Stripe-hostet Checkout: kunden betaler på Stripes side, ikke din. Din app gør kun to ting server-side — opretter en Checkout Session og verificerer ét webhook. Ingen kortfelter, ingen Stripe Elements, ingen PCI-byrde.

Det bygger du

  • Et lille publiceret katalog i CMS'et — tre kategorier og otte produkter ("Edison's Inventions"-demoen) — hver kan redigeres af en forhandler uden kode.
  • To parametriske ruter (/products/{item_code}, /categories/{category_code}) plus en statisk /cart, alle fra ét sæt komponenter.
  • En headless kurv (useCart) og Stripe-hostet checkout, hvor prisen altid løses server-side fra et Stripe Price ID.
  • Butikken udrullet til Vercel med live preview og redigering på stedet for teamet.

Forudsætninger

  • Bun ≥ 1.3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code med Profound MCP (Del 1 installerer den).
  • En Profound CMS-konto.
  • En Stripe-konto. Denne vejledning kører i testtilstand, så intet trækker rigtige penge, mens du bygger — men flowet er identisk med live-nøgler, så brug dine rigtige kontonøgler, hvis du foretrækker det. (Testtilstand kræver ingen virksomheds- eller bankoplysninger.)
  • Stripe CLI (stripe login) til lokale webhooks.
  • Til deploy: GitHub CLI (gh) og en Vercel-konto forbundet til GitHub.

Sådan passer delene sammen

Profound adskiller indhold fra rendering:

  • Komponenter definerer indholdets form. En Custom Component med et Route Slug-felt er rutbar (category, item); en med tagget UI Element kan placeres på en side (nav, product_grid, …).
  • Dokumenter er indholdet (et produkt, en kategori).
  • UI-elementer er sideafsnit; hvert skalart felt tager en statisk værdi eller et CEL-udtryk, evalueret ved rendering.
  • Parametriske ruter mapper en URL til et dokument + UI-elementer og videregiver rutens parametre (meta.params.* i CEL, routeParams i React).
  • Din Next.js-app læser det gennem cms-renderer; Stripe tilføjes som almindelige API-ruter.

Den ene regel, der former byggeriet: CEL binder kun string/number-felter. Så skalart krom (nav-mærke, footer, overskrifter) bindes med CEL, mens alt rigere eller en samling (et produktgrid, et billedgalleri, rich text) hentes inde i React-komponenten via rutens parameter. Og Stripe er prisens sandhedskilde — CMS-feltet price er kun til visning; betalingen afgøres altid server-side fra et Stripe Price ID.

Del 1 — Opsætning

Sluttilstand: et lille publiceret katalog, appen forbundet til at læse det, Stripe installeret, design på plads — intet renderet endnu.

1. Tilmeld dig og opret websitet

Tilmeld dig hos Profound (WorkOS-auth). Opret et website med navnet store, kopier derefter dets website ID (UUID'en i admin-URL'en) og en read-tier API key (Deployments → Create API key). Appen læser kun; katalogseedningen kører senere gennem MCP'en, som autentificerer separat.

2. Scaffold appen, forbind den og tilføj Stripe

bunx create-profound-next store
cd store
bun add stripe

Scaffoldet er et Next.js App Router-projekt forudtrådet til Profound (cms-renderer-SDK'et, en catch-all-rute, et generate-schemas-script, en <Refresher>). Det leveres uden styling. bun add stripe henter server-SDK'et — den eneste betalingsafhængighed hosted checkout behøver.

Tilføj dine værdier til .env.local:

# CMS
PROFOUND_API_KEY=<din read key>
NEXT_PUBLIC_PROFOUND_WEBSITE_ID=<dit website-id>
NEXT_PUBLIC_CMS_API_URL=https://cms.dev.tryprofound.com
NEXT_PUBLIC_BUNNY_CDN_URL=https://cms-profound.b-cdn.net   # leverer CMS-hostede billeder

# Stripe
STRIPE_SECRET_KEY=sk_test_...            # testnøgle her; skift til din live-nøgle, når du går live
STRIPE_WEBHOOK_SECRET=whsec_...          # udfyldes i Opbygning, trin 4
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Hent STRIPE_SECRET_KEY fra Stripe → Developers → API keys. Vi bruger en testnøgle (sk_test_…), så byggeriet aldrig flytter rigtige penge; skift til din live-nøgle, når du er klar til at tage imod rigtige betalinger. Kør bun dev og åbn localhost:3000 — starteren renderes.

Hosted checkout omdirigerer browseren til en Stripe-URL, så serverens hemmelige nøgle er alt, Stripe behøver — ingen publicerbar nøgle, intet klient-Stripe-SDK.

3. Definér komponenterne category, product_image og item

Opret tre Custom Components (Components → Create new component) — datakilden, så ingen UI Element-tag. Sæt hver til Active.

CMS'et har intet felt "array of image", så et galleri er et array af referencer til en lille product_image-komponent. Opret category og product_image (og sæt dem aktive) før item — et referencefelt kan kun pege på aktive komponenter.

  • category — name (Text), code (Text, Route Slug), description (Rich text), heroImage (Image)
  • product_image — image (Image)
  • item — name (Text), code (Text, Route Slug), description (Rich text), images (array af referencer → product_image), price (Number, cents — kun visning), currency (Select, usd), stripePriceId (Text), category (Reference → category), active (Boolean)

Lad alle felter være valgfrie. Admin'en laver felt-navnene om til lower_snake_case ("Stripe Price Id" → stripe_price_id) — det er det, din kode bruger, så læs de rigtige navne tilbage fra generate-schemas bagefter. Vi navngiver den rutbare nøgle code (ikke slug): den er Route Slug og nøglen til et rent documents.getByCode-opslag senere.

Komponenten item — code som Route Slug, images som referencer til product_image, plus stripePriceId og en category-reference.

4. Hent komponenterne ned som lokale typer

bun run generate-schemas

Skriver Zod-schemas + typer til generated/cms-schemas.ts (categorySchema/Category, itemSchema/Item). Fungerer også som forbindelsestjek — forkerte legitimationsoplysninger fejler her.

5. Seed kataloget via Profound MCP

Installer og autentificér MCP'en én gang:

claude mcp add --transport http Profound http://107.21.107.99:8081/mcp

Kør mcp__Profound__authenticate, gennemfør WorkOS-flowet, og prompt derefter Claude:

Generér et lille e-handelskatalog til en butik kaldet Edison's Inventions — tre kategorier og disse produkter med en kort tidsvarende description for hver, en price i cents, currency: "usd", og active: true:

  • Lighting & Power (code: lighting): Incandescent Lightbulb (incandescent-lightbulb, $24), Electric Dynamo (electric-dynamo, $890), Electric Pen (electric-pen, $49)
  • Sound Recording (code: sound): Tinfoil Phonograph (tinfoil-phonograph, $249), Carbon Microphone (carbon-microphone, $59), Dictaphone (dictaphone, $179)
  • Motion Pictures (code: motion): Kinetoscope (kinetoscope, $399), Kinetograph Camera (kinetograph, $549)

Hver kategori skal have et name og den code i små bogstaver; hver vare skal have et name, den code i små bogstaver, description, price (i cents), currency og active. Gem det i data/catalog.json og valider det mod vores komponenter category og item. Brug derefter Profound MCP til at oprette hver som et publiceret dokument: opret kategorierne først, fang deres ID'er, og opret derefter varerne med category sat til en reference — { "_type": "reference", "_ref": "<category-id>", "_schema": "category" }. Lad stripePriceId stå tomt for nu. Kør varerne parallelt.

Claude skriver data/catalog.json, validerer det og skyder parallelle create_document-kald af (status: "published"). Seed kategorier før varer, så referencerne peger på ID'er, der allerede findes.

De tre seedede kategorier, publiceret og live.

De otte seedede produkter, hver knyttet til en kategori.

6. Opret Stripe-priser og forbind et par produkter

Kataloget ligger i CMS'et; giv nu et par produkter en rigtig Stripe-pris — forhandlerens opgave, gjort i to administrationspaneler, uden kode:

  1. Stripe Dashboard → Products → + Add product, sæt en engangspris, kopiér Price ID'et (price_…).
  2. Gør dette for cirka 3 udvalgte produkter (f.eks. Lightbulb, Phonograph, Kinetoscope).
  3. Profound-admin → item → Documents → indsæt hvert Price ID i stripePriceId, gem.

CMS'et holder kataloget; Stripe holder prisen som kilde til sandhed; forbindelsen er én streng, som forhandleren indsætter. (Vil du automatisere det? Den officielle Stripe MCP kan oprette produkterne/priserne for dig — indsæt de returnerede ID'er på samme måde.)

7. Læg designsystemet ind og forbind det med AI

Scaffoldet leveres ustylet. Læg en DESIGN.md (et Tailwind v4 @theme-blok + tokens) i projektrødder — din egen, eller hent en fra refero.design. Prompt derefter Claude, begrænset til styling:

Læs designfilen, jeg lige har tilføjet. Opsæt Tailwind om nødvendigt, og forbind derefter temaet og skrifterne, så stylingen virker. Brug next/font til skrifter — indlæs dem ikke fra Google ved kørsel. Kun stylingen — byg ikke sider eller komponenter endnu.

Bekræft, at src/app/globals.css har @import "tailwindcss"; + @theme-blokken, og at localhost:3000 viser tokens. Hold prompten stram (åben prompt, en agent scaffold'er en hel hjemmeside), og indlæs skrifter via next/font, aldrig en kørende Google-import.

8. Tilføj produktbilleder (valgfrit)

Valgfrit — du kan nå en fungerende checkout uden billeder. Vil du tilføje dem: Opret et product_image-dokument pr. billede (upload i dets image-felt), og referér derefter disse fra produktets images-array. Medbring dine egne produktfotos, eller generér et sammenhængende sæt med en billedmodel (lad Claude udlede on-brand prompts fra DESIGN.md og lås en Midjourney --sref, så hvert billede matcher).

Det selvstændige cms-renderer har ingen helper til billed-URL, så importér buildAssetUrl til src/lib/image.ts (~40 linjer) — den præfikser NEXT_PUBLIC_BUNNY_CDN_URL og tilføjer filtype. Komponenterne i Opbygning, trin 3 bruger den.

Del 2 — Opbygning

Byg renderingslaget og checkout'en, og slut af med et rigtigt køb i testtilstand.

1. Definér de fem UI-elementkomponenter

Fem komponenter, hver Active og tagget UI Element (Settings → Tags), ingen Route Slug:

  • nav → brand · product_grid → heading · product_detail → heading · cart_summary → heading · footer → text (alle Text)

Tagget UI Element er det, der får en komponent til at dukke op i Page Builders liste Add UI Element — Active alene er ikke nok. Hvert felt er en skalar (den slags, CEL binder); selve katalogdataene er ikke et felt her — ProductGrid/ProductDetail henter dem via rutens parameter (trin 3).

2. Regenerér typerne

bun run generate-schemas

3. Generér kataloglæseren, komponenterne og headless-kurven

Én prompt bygger read-helperen, de fem komponenter, kurven og registret:

Byg vores butik i src/ ved hjælp af Profound cms-renderer-SDK'et.

src/lib/catalog.ts — en server-side CMS-læser. Opret en klient med getCmsClient({ cmsUrl: process.env.NEXT_PUBLIC_CMS_API_URL!, apiKey: process.env.PROFOUND_API_KEY, websiteId: process.env.NEXT_PUBLIC_PROFOUND_WEBSITE_ID! }) fra cms-renderer/lib/cms-api. Eksportér getItemByCode(code) → cms.documents.getByCode.query({ websiteId, schemaName: "item", code }), der returnerer res.document.published_content. Eksportér listItems(categoryCode?) → cms.documents.list.query({ websiteId, schemaName: "item", status: "published", limit: 100 }), map res.documents til .published_content, filtrér active !== false, og hvis categoryCode er angivet, behold varer hvis category._ref matcher kategoriens document.id. Eksportér resolveImages(refs), der opløser hver item.images-reference via cms.documents.get.query({ websiteId, id: ref._ref }) og gør feltet image til en URL med den importerede buildAssetUrl (Del 1, trin 8).

src/components/ — fem UI-elementkomponenter registreret i catch-all-rutens register efter komponentnavn, snake_case for at matche admin: { nav, product_grid, product_detail, cart_summary, footer }. Nav og Footer læser deres skalare felt via content-proppen (typet BlockComponentProps<T> fra cms-renderer/lib/types). ProductGrid og ProductDetail er asynkrone serverkomponenter, der læser routeParams og henter fra catalog.ts: routeParams.<param> er { value, … } — læs .value, så ProductGrid kalder listItems(routeParams.category_code?.value) (kort linker til /products/{code}), og ProductDetail kalder getItemByCode(routeParams.item_code?.value) (galleri via resolveImages, rich-text-beskrivelse, pris, Læg i kurv). CartSummary render kurven fra useCart med en Betal-knap. Behold formatPrice i en ren src/lib/format.ts, så klientkomponenter ikke importerer server-only catalog.ts.

src/components/AddToCartButton.tsx — en "use client"-knap, der tager { code, name, priceLabel } og kalder useCart().addItem({ code, name, priceLabel, quantity: 1 }). Brug den i ProductDetail.

src/lib/useCart.ts — en headless kurv: linjeposter { code, name, priceLabel, quantity } i state, gemt i localStorage, der eksponerer addItem/removeItem/updateQty/subtotal og en checkout(), der POST'er { lines: [{ code, quantity }] } (kun koder og mængder — aldrig priser) til /api/stripe/checkout og derefter omdirigerer til den returnerede url.

Style det hele med vores designsystem, som vores egne komponenter — kopier ikke kilde-sidens layout.

Tre ting, du skal vide, når det er kørt:

  • Skalart krom kommer ind via content ({ content }: BlockComponentProps<T>) — destrukturer felter som topniveau-propper, og blokken render tom. Katalogdata hentes fra routeParams + et kald til catalog.ts, fordi CEL ikke kan binde lister eller gallerier. Kurven bærer varens koder, aldrig priser.
  • routeParams.<param> er { value, schemaName, document } — læs .value. Læsninger returnerer published_content, ikke .content. Registreringsnøgler er snake_case for at matche admin.
  • Opdater @types/react/@types/react-dom til v19 — scaffoldet leverer v18, som bryder asynkrone serverkomponentblokke mod React 19.

4. Skriv Stripe-serverkoden (rygraden)

Tre korte serverfiler — den eneste betalingskode i appen. De genbruger getItemByCode, så betalingen afgøres server-side.

src/lib/stripe.ts:

import Stripe from "stripe";
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

src/app/api/stripe/checkout/route.ts — opløs hver vare fra CMS'et, opkræv Stripe-prisen:

import { NextResponse } from "next/server";
import { stripe } from "@/lib/stripe";
import { getItemByCode } from "@/lib/catalog"; // server-side, read-tier-nøgle

export async function POST(req: Request) {
  const { lines } = await req.json();                // [{ code, quantity }] — ingen priser fra klienten
  const line_items = await Promise.all(
    lines.map(async ({ code, quantity }: { code: string; quantity: number }) => {
      const item = await getItemByCode(code);          // serveren slår op i CMS'et
      return { price: item!.stripe_price_id, quantity }; // pris fra CMS, aldrig klient
    })
  );
  const session = await stripe.checkout.sessions.create({
    mode: "payment",
    line_items,
    success_url: `${process.env.NEXT_PUBLIC_SITE_URL}/cart?status=success`,
    cancel_url: `${process.env.NEXT_PUBLIC_SITE_URL}/cart?status=cancelled`,
  });
  return NextResponse.json({ url: session.url });     // klienten omdirigerer hertil
}

src/app/api/stripe/webhook/route.ts — det betroede fuldførelsessignal:

import { stripe } from "@/lib/stripe";

export async function POST(req: Request) {
  const body = await req.text();                      // RÅ body — krævet for signaturverificering
  const sig = req.headers.get("stripe-signature")!;
  let event;
  try {
    event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
  } catch {
    return new Response("Bad signature", { status: 400 });
  }
  if (event.type === "checkout.session.completed") {
    // fulfill: registrér ordren / send kvittering.
  }
  return new Response(null, { status: 200 });
}

Nødvendig scaffold-fix: scaffoldets src/proxy.ts videresender alle /api/* til CMS'et, så dine Stripe-ruter aldrig kører. Lad dem passere først:

import { createCmsProxy } from "cms-renderer/lib/proxy";
import { NextResponse, type NextRequest } from "next/server";
import { cmsConfig } from "@/lib/cms-config";

const cmsProxy = createCmsProxy({ upstream: cmsConfig.cmsUrl });
const LOCAL_API_PREFIXES = ["/api/stripe"];

export const proxy = async (request: NextRequest) => {
  if (LOCAL_API_PREFIXES.some((p) => request.nextUrl.pathname.startsWith(p))) {
    return NextResponse.next();                       // håndtér lokalt
  }
  return cmsProxy(request as unknown as Parameters<typeof cmsProxy>[0]);
};
// behold scaffoldets `export const config = { matcher: [...] }` uændret

Bekræft: curl -X POST localhost:3000/api/stripe/webhook -d x returnerer Bad signature.

Kør Stripe CLI til lokale webhooks:

stripe login
stripe listen --forward-to localhost:3000/api/stripe/webhook
# kopiér whsec_... til STRIPE_WEBHOOK_SECRET, genstart bun dev

whsec_… er per session. To regler bærer sikkerheden: checkout genudleder prisen fra CMS'et efter code (en manipuleret kurv kan ikke ændre den), og webhooken verificerer signaturen mod den rå body.

5. Opret ruterne

Admin → Pages → Create page, tre gange. Kortlæg hver parameter til sin komponent (slug-felt code):

  1. /products/{item_code} → item
  2. /categories/{category_code} → category
  3. /cart — en statisk side (indtast bogstaveligt /cart, ikke /{cart})

6. Tilføj UI-elementer, bind CEL, publicér

For hver rute: Page Builder → Add UI Element → Custom → tilføj komponenter i rækkefølge, udfyld skalare felter (statisk værdi eller CEL), Publicér.

  • /products/{item_code}: nav, product_detail, footer
  • /categories/{category_code}: nav, product_grid, footer
  • /cart: nav, cart_summary, footer

Sæt nav.brand og footer.text til statiske strenge; overskrifter til statiske etiketter.

Page Builder på kategori-ruten — elementet product_grid valgt, dets heading bundet via CEL.

Page Builder på produkt-ruten — elementet product_detail på en produktbinding.

Parametrisk Page Builder-faldgrube: på de to parametriske ruter gemmes tilføjede UI-elementer ikke (blokke bliver forladte, og siden render tom). Indtil det er rettet, forbind disse siders block_ids direkte via Profound MCP update_page, og publicér derefter. (Statisk /cart knytter fint.) Af samme grund henter ProductGrid sin heading fra den kategori, den læser, i stedet for via CEL.

7. Render og køb

  • /categories/lighting → grid'et. Klik på et produkt → detalje + Læg i kurv. /cart → Betal.
  • Betal omdirigerer til Stripe-hostet checkout. Brug testkortet 4242 4242 4242 4242, valgfri fremtidig udløbsdato/CVC. Du returneres til /cart?status=success, og stripe listen viser checkout.session.completed.

En renderet produktside — galleri, pris og Læg i kurv.

Kurven — linjeposter og en enkelt Betal-med-Stripe-knap.

Kun prissatte varer kan købes — køb en af de ~3, du prissatte i trin 6.

Valgfrit — internationalisér. Oversæt hver komponent (alle 35 sprog på én gang), tilføj et segment /{language}/… map til den indbyggede System-komponent language, og skift CEL-bundne felter til documents.translated. Se tutorialen for lufthavnsoversigten, Del 2, trin 7.

Del 3 — Produktion

1. Send den af sted: GitHub, dernæst Vercel

git init && git add -A && git commit -m "Stripe storefront"
gh repo create store --private --source=. --push   # --public er også fint

Build-kommando: generated/cms-schemas.ts er i .gitignore, så lås buildet til at regenerere den — tilføj vercel.json:

{ "$schema": "https://openapi.vercel.sh/vercel.json", "buildCommand": "bun run generate-schemas && next build" }

I Vercel: Add New → Project, importér store, og tilføj miljøvariablerne — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL, NEXT_PUBLIC_BUNNY_CDN_URL, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET (værdien for den deployede endpoint, nedenfor) og NEXT_PUBLIC_SITE_URL (din prod-URL). Deploy.

Kobl derefter det deployede webhook på (den lokale stripe listen-hemmelighed var kun lokal): Stripe → Developers → Webhooks → + Add endpoint → https://<prod>/api/stripe/webhook, event checkout.session.completed. Kopiér dens whsec_… til Vercel, og deploy igen.

Manglende miljøvariabler = "virker lokalt, tom i prod" — deploy-faldgrube nr. 1. Vi deployer med testnøgler her; skift STRIPE_SECRET_KEY og webhook-hemmeligheden til dine live værdier, når du er klar til at modtage rigtige betalinger.

2. Live preview og redigering på stedet

Begge følger med scaffoldet.

  • Live preview: <Refresher> opdaterer siden, du forhåndsviser, når en redaktør gemmer i admin — ingen redeploy. (Det er en forhåndsvisning for redaktøren; besøgende ser publiceret indhold med normal revalidering.)
  • Redigering på stedet: tilføj ?edit_mode=true til enhver URL for redigeringsoverlays. Offentlige besøgende får den rene side.

Tilføj preview-ruten, som scaffoldet udelader. Admin'en indlæser sin preview-iframe på /cms-preview_<path>; uden den rute giver hver preview 404. Tilføj den:

// src/app/cms-preview_/[...slug]/page.tsx
import { ParametricRoutePreviewPage } from "cms-renderer/lib/renderer";
import { registry } from "../../registry";   // træk dit register ud i et delt modul
export default async function Page({ params, searchParams }) {
  const { slug } = await params;
  const PreviewPage = ParametricRoutePreviewPage as any; // async RSC; React 19-typer
  return <PreviewPage registry={registry} apiKey={process.env.PROFOUND_API_KEY ?? ""}
    websiteId={process.env.NEXT_PUBLIC_PROFOUND_WEBSITE_ID ?? ""}
    cmsUrl={process.env.NEXT_PUBLIC_CMS_API_URL ?? "https://cms.dev.tryprofound.com"}
    params={Promise.resolve({ slug })} searchParams={searchParams} />;
}

Tilføj også src/app/cms-preview_/page.tsx (samme, slug: []) til segmentroden.

Det var byggeriet

En indholdsbaseret Stripe-butik: et CMS-katalog, liste + detaljesider fra ét sæt ruter og en fungerende hosted checkout. AI seedede kataloget, forbandt designet og skrev kataloglæseren + komponenterne + den headless kurv; du lavede komponenterne, Stripe-prislinkene, de tre ruter, CEL-kromet og tre korte Stripe-filer. CEL binder kromet; komponenterne henter kataloget. Og Stripe forblev lille — ét sessions.create-kald og én signeret webhook, med kunden, der betaler på Stripes egen side.

Continue Reading
Previous‹Deployments