profound-logoProfound CMS
⌘K
Admin
Theme
DocsTutorialBlogPhilosophy
DocsTutorialBlogPhilosophy

Tutorials

Build & Ship an Airport DirectoryDeploymentsBuild & Ship a Stripe Storefront

TVS funkcijos

Documentation Site TemplateFeature Template BuilderVertimo funkcijaOrganizations & 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

Praktinis vadovas: sukurkite turiniu paremtą Stripe vitriną Profound CMS sistemoje — katalogą, kurį pirklys redaguoja be kodo, du parametrinius maršrutus, be galvos krepšelį ir Stripe talpinamą atsiskaitymą.

Baigta parduotuvė veiksme — naršykite kategoriją, atidarykite produktą, įdėkite į krepšelį, atsiskaitykite.

Praktinis žingsnis po žingsnio vadovas, kuriame Profound CMS platformoje sukuriama turiniu paremta parduotuvė: produktų katalogas (kategorijos + prekės), modeliuotas CMS sistemoje, sąrašų ir detalių puslapiai iš vieno maršrutų rinkinio ir „Stripe“ talpinamas atsiskaitymas, pateikiamas kaip be galvos komponentas.

Stuburas — ranka rašytas „Next.js“ ir Profound administravimo sąsaja. Claude Code (per Profound MCP) atlieka didžiąją dalį darbo trijuose užduotyse — katalogo užpildymas, dizaino sistemos paruošimas ir vitrinos komponentų (įskaitant be galvos krepšelį) kūrimas. Trijų dalių planas: Paruošimas, Kūrimas, Perkėlimas į gamybą.

Atsiskaitymai vienoje eilutėje. Naudojame „Stripe“ talpinamą „Checkout“: pirkėjas atsiskaito Stripe puslapyje, ne jūsų. Jūsų programai tereikia atlikti du serverio veiksmus — sukurti „Checkout Session“ ir patvirtinti vieną žiniatinklio kablį. Jokio kortelių laukų, jokių „Stripe Elements“, jokios PCI naštos.

Ką sukursite

  • Nedidelį publikuotą katalogą CMS sistemoje — trys kategorijos ir aštuoni produktai („Edison's Inventions“ demonstracija) — kiekvieną pirklys gali redaguoti be kodo.
  • Du parametrinius maršrutus (/products/{item_code}, /categories/{category_code}) ir statinį /cart, visus iš vieno komponentų rinkinio.
  • Be galvos krepšelį (useCart) ir „Stripe“ talpinamą atsiskaitymą, kai kaina visada nustatoma serverio pusėje pagal „Stripe Price ID“.
  • Parduotuvę, išdiegtą į „Vercel“, su tiesiogine peržiūra ir komandai pritaikytu redagavimu vietoje.

Reikalavimai

  • Bun ≥ 1.3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code su Profound MCP (pirma dalis jį įdiegia).
  • Profound CMS paskyra.
  • Stripe paskyra. Šis vadovas veikia bandomuoju režimu, tad niekas nėra apmokestinamas realiais pinigais kūrimo metu — tačiau eiga identiška su aktyviais raktais, tad, jei pageidaujate, naudokite tikrus paskyros raktus. (Bandomajam režimui nereikia įmonės ar banko duomenų.)
  • Stripe CLI (stripe login) vietiniams žiniatinklio kabliams.
  • Diegimui: GitHub CLI (gh) ir su GitHub susieta Vercel paskyra.

Kaip visos dalys tarpusavyje dera

Profound atskiria turinį nuo vaizdavimo:

  • Komponentai apibrėžia turinio struktūrą. Pasirinktinis komponentas su Route Slug lauku yra pasiekiamas (category, item); vienas pažymėtas UI Element gali būti patalpintas puslapyje (nav, product_grid, …).
  • Dokumentai yra turinys (produktas, kategorija).
  • UI elementai yra puslapio sekcijos; kiekvienas skaliarinis laukas priima statinę reikšmę arba CEL išraišką, įvertinamą renderinimo metu.
  • Parametriniai maršrutai susieja URL su dokumentu + UI elementais, perduodami maršruto parametrus (meta.params.* CEL, routeParams React).
  • Jūsų „Next.js“ programa juos skaito per cms-renderer; „Stripe“ pridedamas kaip paprasti API maršrutai.

Pagrindinė taisyklė, formuojanti kūrimą: CEL sieja tik string/number laukus. Taigi skaliariniai apvalkalai (navigacijos ženklelis, poraštė, antraštės) susiejami per CEL, o visa, kas yra turtingesnė ar kolekcija (produktų tinklelis, vaizdų galerija, turtingas tekstas), gaunama React komponente pagal maršruto parametrą. Ir Stripe yra kainų tiesos šaltinis — CMS price skirtas tik rodymui; apmokestinimas visada nustatomas serverio pusėje pagal „Stripe Price ID“.

1 dalis — Paruošimas

Galutinis rezultatas: nedidelis publikuotas katalogas, programa prijungta prie jo, „Stripe“ įdiegta, dizainas vietoje — dar nieko nerodoma.

1. Užsiregistruokite ir sukurkite svetainę

Prisiregistruokite Profound (WorkOS autentifikacija). Sukurkite svetainę pavadinimu store, tada nukopijuokite jos svetainės ID (UUID administratoriaus URL) ir skaitymo lygio API raktą (Deployments → Create API key). Programa tik skaitys; katalogo užpildymas vėliau vyks per MCP, kuris autentifikuojasi atskirai.

2. Sugeneruokite programą, prijunkite ją ir pridėkite „Stripe“

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

Sugeneruota struktūra — „Next.js App Router“ projektas, iš anksto sujungtas su Profound (cms-renderer SDK, viską apimantis maršrutas, scenarijus generate-schemas, <Refresher>). Stilistikos nėra. bun add stripe įtraukia serverio SDK — vienintelę mokėjimų priklausomybę, kurios reikia talpinamam atsiskaitymui.

Įrašykite savo reikšmes į .env.local:

# CMS
PROFOUND_API_KEY=<your read key>
NEXT_PUBLIC_PROFOUND_WEBSITE_ID=<your website id>
NEXT_PUBLIC_CMS_API_URL=https://cms.dev.tryprofound.com
NEXT_PUBLIC_BUNNY_CDN_URL=https://cms-profound.b-cdn.net   # serves CMS-hosted images

# Stripe
STRIPE_SECRET_KEY=sk_test_...            # test key here; swap to your live key when you go live
STRIPE_WEBHOOK_SECRET=whsec_...          # filled in Build step 4
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Gaukite STRIPE_SECRET_KEY Stripe → Developers → API keys. Naudojame bandomąjį raktą (sk_test_…), kad kūrimo metu pinigai nebūtų pajudinami; kai būsite pasirengę priimti tikrus mokėjimus, pakeiskite į aktyvų raktą. Paleiskite bun dev ir atidarykite localhost:3000 — pradinė versija rodoma.

Talpinamas atsiskaitymas nukreipia naršyklę į Stripe URL, todėl serverio slaptasis raktas yra viskas, ko Stripe reikia — jokių viešų raktų, jokio kliento Stripe SDK.

3. Apibrėžkite komponentus category, product_image ir item

Sukurkite tris Custom Components (Components → Create new component) — duomenų šaltinius, tad be UI Element žymos. Nustatykite kiekvieną Active.

CMS neturi „masyvo iš paveikslėlių“ lauko, tad galerija yra nuorodų masyvas į nedidelį product_image komponentą. Sukurkite category ir product_image (ir nustatykite Active) prieš item — nuorodos laukas gali rodyti tik į Active komponentus.

  • 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 of references → product_image), price (Number, cents — display only), currency (Select, usd), stripePriceId (Text), category (Reference → category), active (Boolean)

Palikite visus laukus pasirenkamus. Administratorius laukų pavadinimus paverčia mažosiomis su pabraukimais („Stripe Price Id“ → stripe_price_id) — būtent į juos remsis jūsų kodas, tad vėliau per generate-schemas perskaitykite tikruosius pavadinimus. Maršrutuojamą lauką vadiname code (ne slug): tai ir Route Slug, ir raktas švariam documents.getByCode paieškos iškvietimui vėliau.

Komponentas item — code kaip Route Slug, images kaip nuorodos į product_image, be to stripePriceId ir category nuoroda.

4. Atsisiųskite komponentus į vietinius tipus

bun run generate-schemas

Sugeneruoja Zod schemas + tipus į generated/cms-schemas.ts (categorySchema/Category, itemSchema/Item). Tai kartu ir ryšio patikrinimas — neteisingi prisijungimo duomenys čia nepraeis.

5. Užpildykite katalogą per Profound MCP

Įdiekite ir autentifikuokite MCP vieną kartą:

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

Paleiskite mcp__Profound__authenticate, užbaikite WorkOS eigą, tada paprašykite Claude:

Sugeneruok nedidelį elektroninės prekybos katalogą parduotuvei Edison's Inventions — trys kategorijos ir šie produktai, su trumpu savo laikmečiui būdingu description, price centais, currency: "usd" ir active: true:

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

Kiekvienai kategorijai reikia name ir to mažosiomis parašyto code; kiekvienam elementui reikia name, to paties mažosiomis code, description, price (centais), currency ir active. Įrašyk į data/catalog.json ir patikrink pagal mūsų category ir item komponentus. Tada naudok Profound MCP, kad kiekvieną sukurtum kaip publikuotą dokumentą: pirmiausia sukurk kategorijas, užfiksuok jų ID, tuomet sukurk elementus su category, nustatytu kaip nuoroda — { "_type": "reference", "_ref": "<category-id>", "_schema": "category" }. stripePriceId palik tuščią. Elementus kurk lygiagrečiai.

Claude sukuria data/catalog.json, patvirtina jį ir lygiagrečiai išsiunčia create_document užklausas (status: "published"). Kategorijas kurkite prieš elementus, kad nuorodos nukreiptų į jau esančius ID.

Trys užpildytos kategorijos, publikuotos ir Live.

Aštuoni užpildyti produktai, kiekvienas susietas su kategorija.

6. Sukurkite „Stripe“ kainas ir susiekite kelis produktus

Katalogas yra CMS; dabar keliems produktams suteikite tikrą „Stripe“ kainą — prekybininko darbas, atliekamas dviejuose administravimo skydeliuose, be kodo:

  1. Stripe valdymo pultas → Products → + Add product, nustatykite vienkartinę kainą, nukopijuokite Price ID (price_…).
  2. Tai atlikite ~3 pavyzdiniams produktams (pvz., lemputei, fonografui, kinetoskopui).
  3. Profound administravimas → item → Documents → įklijuokite kiekvieną Price ID į stripePriceId, išsaugokite.

CMS saugo katalogą; Stripe saugo oficialią kainą; jungtis — vienas simbolių rinkinys, kurį įklijuoja prekybininkas. (Pageidaujate automatizuoti? Oficiali Stripe MCP gali sukurti produktus/kainas už jus — įklijuokite grąžintus ID taip pat.)

7. Įkelkite dizaino sistemą ir sujunkite ją su dirbtiniu intelektu

Sugeneruota struktūra be stiliaus. Įdėkite DESIGN.md (Tailwind v4 @theme blokas + žetonai) projekto šaknyje — galite naudoti savą arba parsisiųsti iš refero.design. Tada duokite Claude tikslią užduotį, apsiribojančią stiliumi:

Perskaityk ką tik pridėtą dizaino failą. Nustatyk Tailwind, jei reikia, tada įdiek temą ir šriftus, kad stilistika veiktų. Šriftams naudok next/font — nekrauk jų iš Google vykdymo metu. Tik stilistika — jokio puslapių ar komponentų kūrimo.

Įsitikinkite, kad src/app/globals.css turi @import "tailwindcss"; + @theme bloką ir kad localhost:3000 rodo žetonus. Laikykite užduotį konkrečią (atvira užklausa gali priversti agentą sukurti visą pagrindinį puslapį) ir naudokite next/font, niekada ne Google importą vykdymo metu.

8. Pridėkite produktų paveikslėlius (nebūtina)

Pasirinktinai — iki veikiančio atsiskaitymo galite praeiti be paveikslėlių. Norėdami juos pridėti: sukurkite po product_image dokumentą kiekvienam paveikslėliui (įkelkite į jo image lauką), tada susiekite juos iš produkto images masyvo. Naudokite savo produktų nuotraukas arba sugeneruokite vientisą rinkinį su vaizdų modeliu (leiskite Claude išvesti prekės ženklui tinkamas užklausas iš DESIGN.md ir užrakinkite vieną Midjourney --sref, kad visi kadrai atitiktų).

Atskirame cms-renderer nėra pagalbininko vaizdų URL, tad src/lib/image.ts faile įveskite savo buildAssetUrl (~40 eilučių) — jis prie NEXT_PUBLIC_BUNNY_CDN_URL prideda plėtinį. Komponentai iš 2 dalies 3 žingsnio juo naudojasi.

2 dalis — Kūrimas

Sukurkite vaizdavimo sluoksnį ir atsiskaitymą, galiausiai atlikdami tikrą bandomojo režimo pirkimą.

1. Apibrėžkite penkis UI elementų komponentus

Penki komponentai, kiekvienas Active ir pažymėtas UI Element (Settings → Tags), be Route Slug:

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

UI Element žyma sukelia komponento atsiradimą Page Builder sąraše Add UI Element — vien Active nepakanka. Kiekvienas laukas yra skaliaras (tokį CEL sieja); tikras katalogo turinys čia nėra laukas — ProductGrid/ProductDetail jį gauna pagal maršruto parametrą (3 žingsnis).

2. Iš naujo sugeneruokite tipus

bun run generate-schemas

3. Sugeneruokite katalogo skaitytuvą, komponentus ir be galvos krepšelį

Viena užklausa sukuria skaitymo pagalbininką, penkis komponentus, krepšelį ir registrą:

Sukurk mūsų vitrinos funkcijas src/ kataloge, naudodamas Profound cms-renderer SDK.

src/lib/catalog.ts — serverio pusės CMS skaitytuvas. Sukurk klientą su getCmsClient({ cmsUrl: process.env.NEXT_PUBLIC_CMS_API_URL!, apiKey: process.env.PROFOUND_API_KEY, websiteId: process.env.NEXT_PUBLIC_PROFOUND_WEBSITE_ID! }) iš cms-renderer/lib/cms-api. Eksportuok getItemByCode(code) → cms.documents.getByCode.query({ websiteId, schemaName: "item", code }), grąžinantį res.document.published_content. Eksportuok listItems(categoryCode?) → cms.documents.list.query({ websiteId, schemaName: "item", status: "published", limit: 100 }), res.documents paversk į .published_content, filtruok active !== false, o jei pateikiamas categoryCode, palik elementus, kurių category._ref sutampa su kategorijos document.id. Eksportuok resolveImages(refs), kuris kiekvieną item.images nuorodą išsprendžia per cms.documents.get.query({ websiteId, id: ref._ref }) ir jo vaizdo lauką paverčia URL naudodamas ranka įvestą buildAssetUrl (1 dalies 8 žingsnis).

src/components/ — penki UI elementų komponentai, užregistruoti gaudymo maršruto registre pagal komponento pavadinimą, snake_case, kad sutaptų su administravimu: { nav, product_grid, product_detail, cart_summary, footer }. Nav ir Footer skaliarinius laukus skaito iš content parametro (tipas BlockComponentProps<T> iš cms-renderer/lib/types). ProductGrid ir ProductDetail yra asinchroniniai serverio komponentai, kurie skaito routeParams ir gauna duomenis iš catalog.ts: routeParams.<param> yra { value, … } — naudok .value, tad ProductGrid iškviečia listItems(routeParams.category_code?.value) (kortelės veda į /products/{code}), o ProductDetail iškviečia getItemByCode(routeParams.item_code?.value) (galerija per resolveImages, turiningas aprašas, kaina, mygtukas „Add to cart“). CartSummary pateikia krepšelį iš useCart su „Pay“ mygtuku. formatPrice laikyk atskirame src/lib/format.ts, kad kliento komponentai neimportuotų tik serveriui skirto catalog.ts.

src/components/AddToCartButton.tsx — "use client" mygtukas su { code, name, priceLabel }, kuris kviečia useCart().addItem({ code, name, priceLabel, quantity: 1 }). Naudok jį ProductDetail viduje.

src/lib/useCart.ts — be galvos krepšelis: eilučių elementai { code, name, priceLabel, quantity } būsenoje, saugomi localStorage, pateikiantys addItem/removeItem/updateQty/subtotal ir checkout(), kuris siunčia POST { lines: [{ code, quantity }] } (tik kodai ir kiekiai — niekada kainos) į /api/stripe/checkout, tada nukreipia į grąžintą url.

Visą stilistiką pritaikykite pagal mūsų dizaino sistemą, naudodami savo komponentus — nekopijuokite šaltinio svetainės išdėstymo.

Trys išmokimai po atlikimo:

  • Skaliariniai apvalkalai ateina per content ({ content }: BlockComponentProps<T>) — destruktūrizuokite laukus kaip aukščiausio lygmens parametrus ir blokas liks tuščias. Katalogo duomenys gaunami pagal routeParams + catalog.ts, nes CEL nesuriša sąrašų ar galerijų. Krepšelis saugo prekių kodus, niekada kainas.
  • routeParams.<param> yra { value, schemaName, document } — naudokite .value. Skaitymai grąžina published_content, o ne .content. Registracijos raktai yra snake_case, atitinkantys administratorių.
  • Atnaujinkite @types/react/@types/react-dom į v19 — sugeneruota struktūra pateikia v18, kuris sugadina asinchroninius serverio komponentų blokus su React 19.

4. Parašykite „Stripe“ serverio kodą (stuburas)

Trys trumpi serverio failai — vienintelis mokėjimų kodas programoje. Jie pakartotinai naudoja getItemByCode, tad mokestis nustatomas serverio pusėje.

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 — kiekvieną elementą išspręskite iš CMS, mokestį priskirkite pagal Stripe kainą:

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

export async function POST(req: Request) {
  const { lines } = await req.json();                // [{ code, quantity }] — no prices from the client
  const line_items = await Promise.all(
    lines.map(async ({ code, quantity }: { code: string; quantity: number }) => {
      const item = await getItemByCode(code);          // server resolves from the CMS
      return { price: item!.stripe_price_id, quantity }; // price from CMS, never client
    })
  );
  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 });     // client redirects here
}

src/app/api/stripe/webhook/route.ts — patikima įvykdymo nuoroda:

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

export async function POST(req: Request) {
  const body = await req.text();                      // RAW body — required for signature verification
  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: record the order / send a receipt.
  }
  return new Response(null, { status: 200 });
}

Reikalingas sugeneruotos struktūros pataisymas: src/proxy.ts viską /api/* nukreipia į CMS, tad jūsų Stripe maršrutai niekada neveikia. Pirmiausia praleiskite juos:

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();                       // handle locally
  }
  return cmsProxy(request as unknown as Parameters<typeof cmsProxy>[0]);
};
// keep the scaffold's `export const config = { matcher: [...] }` unchanged

Patikra: curl -X POST localhost:3000/api/stripe/webhook -d x grąžina Bad signature.

Paleiskite Stripe CLI vietiniams žiniatinklio kabliams:

stripe login
stripe listen --forward-to localhost:3000/api/stripe/webhook
# copy the whsec_... into STRIPE_WEBHOOK_SECRET, restart bun dev

whsec_… galioja vienai sesijai. Saugumą garantuoja dvi taisyklės: atsiskaitymas pakartotinai nustato kainą iš CMS pagal code (suklastotas krepšelis jos nepakeis), o žiniatinklio kablis patikrina parašą pagal neapdorotą kūną.

5. Sukurkite maršrutus

Administratoriaus sąsaja → Pages → Create page, triskart. Susiekite kiekvieną parametrą su jo komponentu (slug laukas code):

  1. /products/{item_code} → item
  2. /categories/{category_code} → category
  3. /cart — statinis puslapis (įveskite pažodžiui /cart, ne /{cart})

6. Pridėkite UI elementus, sujunkite per CEL, publikuokite

Kiekvienam maršrutui: Page Builder → Add UI Element → Custom → pridėkite komponentus eilės tvarka, užpildykite skaliarinius laukus (statine reikšme arba CEL), Publish.

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

nav.brand ir footer.text nustatykite kaip statines eilutes; antraštes kaip statines etiketes.

Page Builder kategorijos maršrute — pasirinktas product_grid elementas, jo antraštė sujungta per CEL.

Page Builder produkto maršrute — product_detail elementas su produktu.

Parametrinių Page Builder ypatybė: dviejuose parametriniuose maršrutuose pridėti UI elementai neišlieka (blokai atsiskiria ir puslapis nerodo). Kol tai neištaisyta, tų puslapių block_ids sujunkite tiesiogiai per Profound MCP update_page, tada publikuokite. (Statinis /cart prisiriša normaliai.) Dėl tos pačios priežasties ProductGrid antraštę išveda pagal pasirinktą kategoriją, o ne per CEL.

7. Parodykite ir pirkite

  • /categories/lighting → tinklelis. Spustelėkite produktą → detalės + „Add to cart“. /cart → „Pay“.
  • Apmokėjimas nukreipia į „Stripe“ talpinamą atsiskaitymą. Naudokite bandomąją kortelę 4242 4242 4242 4242, bet kurią ateities galiojimo datą/CVC. Grįžtate į /cart?status=success, o stripe listen rodo checkout.session.completed.

Atvaizduotas produkto puslapis — galerija, kaina ir „Add to cart“.

Krepšelis — eilutės ir vienas „Pay with Stripe“ mygtukas.

Pirkti galima tik tuos elementus, kuriems 6 žingsnyje priskyrėte kainą.

Papildoma galimybė — internacionalizuokite. Išverskite kiekvieną komponentą (iškart į 35 kalbas), pridėkite /{language}/… segmentą, susietą su įmontuotu System komponentu language, ir pakeiskite CEL susietus laukus į documents.translated. Žiūrėkite oro uostų katalogo mokymą, 2 dalies 7 žingsnį.

3 dalis — Perkėlimas į gamybą

1. Išleisite: GitHub, tada Vercel

git init && git add -A && git commit -m "Stripe storefront"
gh repo create store --private --source=. --push   # --public is fine too

Kompiliavimo komanda: generated/cms-schemas.ts neįtrauktas į git, tad užtikrinkite, kad diegiant jis būtų sugeneruotas iš naujo — pridėkite vercel.json:

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

Vercel: Add New → Project, importuokite store, pridėkite aplinkos kintamuosius — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL, NEXT_PUBLIC_BUNNY_CDN_URL, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET (diegiamosios galinės reikšmės, žr. žemiau) ir NEXT_PUBLIC_SITE_URL (jūsų gamybos URL). Diekite.

Tada sujunkite diegiamą žiniatinklio kablį (vietinis stripe listen raktas buvo tik vietinis): Stripe → Developers → Webhooks → + Add endpoint → https://<prod>/api/stripe/webhook, įvykis checkout.session.completed. Nukopijuokite jo whsec_… į Vercel ir paleiskite diegimą iš naujo.

Trūkstami aplinkos kintamieji = „veikia lokaliai, gamyboje tuščia“ — dažniausia diegimo klaida. Čia diegiame su bandomaisiais raktais; kai būsite pasirengę priimti tikrus mokėjimus, pakeiskite STRIPE_SECRET_KEY ir žiniatinklio kablio raktą į aktyvias reikšmes.

2. Tiesioginė peržiūra ir redagavimas vietoje

Abi funkcijos pateikiamos su sugeneruota struktūra.

  • Tiesioginė peržiūra: <Refresher> atnaujina puslapį, kurį peržiūri redaktorius, kai administravimo aplinkoje išsaugoma — nereikia iš naujo diegti. (Tai redaktoriaus peržiūra; lankytojai mato publikuotą turinį įprasto revalidavimo metu.)
  • Redagavimas vietoje: pridėkite ?edit_mode=true prie bet kurio URL, kad pritaikytumėte redagavimo perdangas. Vieši lankytojai mato švarų puslapį.

Pridėkite sugeneruotos struktūros praleistą peržiūros maršrutą. Administratoriaus peržiūros iframe įkraunamas adresu /cms-preview_<path>; be šio maršruto kiekviena peržiūra grąžina 404. Pridėkite jį:

// src/app/cms-preview_/[...slug]/page.tsx
import { ParametricRoutePreviewPage } from "cms-renderer/lib/renderer";
import { registry } from "../../registry";   // extract your registry to a shared module
export default async function Page({ params, searchParams }) {
  const { slug } = await params;
  const PreviewPage = ParametricRoutePreviewPage as any; // async RSC; React 19 types
  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} />;
}

Pridėkite ir src/app/cms-preview_/page.tsx (tas pats, slug: []) segmentų šakniniam adresui.

Štai ir kūrinys

Turiniu paremta Stripe vitrina: CMS katalogas, sąrašų ir detalių puslapiai iš vieno maršrutų rinkinio, veikiantis talpinamas atsiskaitymas. Dirbtinis intelektas užpildė katalogą, sujungė dizainą ir parašė katalogo skaitytuvą + komponentus + be galvos krepšelį; jūs pasirūpinote komponentais, Stripe kainų saitais, trimis maršrutais, CEL apvalkalu ir trimis trumpais Stripe failais. CEL sieja apvalkalą; komponentai gauna katalogą. O Stripe liko minimalus — vienas sessions.create iškvietimas ir vienas pasirašytas žiniatinklio kablis, o pirkėjas atsiskaito Stripe puslapyje.

Continue Reading
Previous‹Deployments