diff --git a/astro.config.ts b/astro.config.ts index 625e9d8e..55001042 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -232,6 +232,8 @@ export default defineConfig({ "/api/**", // Custom Astro page outside docs content collection. "/contact", + // Custom documentation hub outside docs content collection. + "/docs", // Custom help hub with dynamic sections rendered from Astro pages. "/help", "/help/**", @@ -261,8 +263,8 @@ export default defineConfig({ label: "Get Started", items: [ { - label: "Home", - link: "/", + label: "Overview", + link: "/docs/", }, ], }, diff --git a/ec.config.mjs b/ec.config.mjs index cffc1459..6b91cae9 100644 --- a/ec.config.mjs +++ b/ec.config.mjs @@ -11,7 +11,7 @@ export default defineEcConfig({ borderRadius: "0", borderWidth: "0", codeFontFamily: "var(--cui-font-stack-mono)", - codeBackground: "var(--cui-bg-subtle)", + codeBackground: "#fff", gutterBorderWidth: "0", frames: { editorTabBarBorderBottomColor: "var(--cui-border-subtle)", diff --git a/public/img/landing/sumup-sky-v01.webp b/public/img/landing/sumup-sky-v01.webp new file mode 100644 index 00000000..02bceb38 Binary files /dev/null and b/public/img/landing/sumup-sky-v01.webp differ diff --git a/src/components/ApiDocs/EndpointList.tsx b/src/components/ApiDocs/EndpointList.tsx index 11bd83b8..0168d004 100644 --- a/src/components/ApiDocs/EndpointList.tsx +++ b/src/components/ApiDocs/EndpointList.tsx @@ -5,7 +5,6 @@ import styles from "./EndpointList.module.css"; interface Props { operations: OperationObject[]; - selectedOperationSlug?: string; tagSlug: string; } @@ -22,11 +21,7 @@ const EndpointDetails = ({ operation }: { operation: OperationObject }) => { ); }; -export default function EndpointList({ - operations, - selectedOperationSlug, - tagSlug, -}: Props) { +export default function EndpointList({ operations, tagSlug }: Props) { return ( , href: `/api/${tagSlug}/${operation.slug}/`, variant: "navigation", - selected: selectedOperationSlug === operation.slug, }))} /> ); diff --git a/src/components/ApiDocs/TagSection.astro b/src/components/ApiDocs/TagSection.astro index 00de07c1..c1b56988 100644 --- a/src/components/ApiDocs/TagSection.astro +++ b/src/components/ApiDocs/TagSection.astro @@ -84,11 +84,7 @@ const coreObjectSections = coreObjects.map((schema, index) => { { operations.length > 0 && ( - + ) } diff --git a/src/components/Code/CodeBlock.astro b/src/components/Code/CodeBlock.astro index d46c40da..6ef45220 100644 --- a/src/components/Code/CodeBlock.astro +++ b/src/components/Code/CodeBlock.astro @@ -72,7 +72,7 @@ const { align-self: start; border: var(--cui-border-width-kilo) solid var(--cui-border-subtle); border-radius: var(--cui-border-radius-byte); - background-color: var(--cui-bg-subtle); + background-color: #fff; } .header { @@ -82,7 +82,7 @@ const { padding: var(--cui-spacings-bit) var(--cui-spacings-byte) var(--cui-spacings-bit) var(--cui-spacings-kilo); border-bottom: var(--cui-border-width-kilo) solid var(--cui-border-subtle); - background: var(--cui-bg-subtle); + background: #fff; } .options { diff --git a/src/components/Landing/Brands.astro b/src/components/Landing/Brands.astro index e06041e1..8c37e55e 100644 --- a/src/components/Landing/Brands.astro +++ b/src/components/Landing/Brands.astro @@ -1,28 +1,96 @@ --- -import LogoSlider from "@components/LogoSlider.astro"; - const brands = [ - { title: "Airpos", src: "/img/logos/airpos.svg" }, - { title: "Booking.com", src: "/img/logos/booking.com.svg" }, - { title: "Bookingkit", src: "/img/logos/bookingkit.svg" }, - { title: "DHL", src: "/img/logos/dhl.svg" }, - { title: "Decathlon", src: "/img/logos/decathlon.svg" }, - { title: "Dominos", src: "/img/logos/dominos.svg" }, - { title: "Flixbus", src: "/img/logos/flixbus.svg" }, - { title: "Lightspeed", src: "/img/logos/lightspeed.svg" }, - { title: "Loyverse", src: "/img/logos/loyverse.svg" }, - { title: "Taxicaller", src: "/img/logos/taxicaller.svg" }, - { title: "Transdev", src: "/img/logos/transdev.svg" }, - { title: "Treatwell", src: "/img/logos/treatwell.svg" }, - { title: "ready2order", src: "/img/logos/ready2order.svg" }, + { + name: "Booking.com", + src: "/img/logos/booking.com.svg", + width: 119, + height: 21, + }, + { + name: "Decathlon", + src: "/img/logos/decathlon.svg", + width: 1000, + height: 249, + }, + { name: "DHL", src: "/img/logos/dhl.svg", width: 100, height: 15 }, + { + name: "Domino's", + src: "/img/logos/dominos.svg", + width: 667, + height: 148, + }, + { + name: "FlixBus", + src: "/img/logos/flixbus.svg", + width: 596, + height: 106, + }, + { + name: "Treatwell", + src: "/img/logos/treatwell.svg", + width: 185, + height: 35, + }, ]; - -const splitIndex = Math.ceil(brands.length / 2 + 1); -const firstRow = brands.slice(0, splitIndex); -const secondRow = brands.slice(splitIndex); --- -
- - -
+
    + { + brands.map(({ name, src, width, height }) => ( +
  • + {name} +
  • + )) + } +
+ + diff --git a/src/components/Landing/DocsBrands.astro b/src/components/Landing/DocsBrands.astro new file mode 100644 index 00000000..e06041e1 --- /dev/null +++ b/src/components/Landing/DocsBrands.astro @@ -0,0 +1,28 @@ +--- +import LogoSlider from "@components/LogoSlider.astro"; + +const brands = [ + { title: "Airpos", src: "/img/logos/airpos.svg" }, + { title: "Booking.com", src: "/img/logos/booking.com.svg" }, + { title: "Bookingkit", src: "/img/logos/bookingkit.svg" }, + { title: "DHL", src: "/img/logos/dhl.svg" }, + { title: "Decathlon", src: "/img/logos/decathlon.svg" }, + { title: "Dominos", src: "/img/logos/dominos.svg" }, + { title: "Flixbus", src: "/img/logos/flixbus.svg" }, + { title: "Lightspeed", src: "/img/logos/lightspeed.svg" }, + { title: "Loyverse", src: "/img/logos/loyverse.svg" }, + { title: "Taxicaller", src: "/img/logos/taxicaller.svg" }, + { title: "Transdev", src: "/img/logos/transdev.svg" }, + { title: "Treatwell", src: "/img/logos/treatwell.svg" }, + { title: "ready2order", src: "/img/logos/ready2order.svg" }, +]; + +const splitIndex = Math.ceil(brands.length / 2 + 1); +const firstRow = brands.slice(0, splitIndex); +const secondRow = brands.slice(splitIndex); +--- + +
+ + +
diff --git a/src/components/Landing/LinkButton.astro b/src/components/Landing/LinkButton.astro new file mode 100644 index 00000000..46998bc7 --- /dev/null +++ b/src/components/Landing/LinkButton.astro @@ -0,0 +1,69 @@ +--- +import type { HTMLAttributes } from "astro/types"; + +interface Props extends HTMLAttributes<"a"> { + href: string; + variant?: "primary" | "secondary" | "minimal"; + icon?: string; +} + +const { + href, + variant = "primary", + icon, + class: className, + ...attributes +} = Astro.props; +const external = /^https?:\/\//.test(href); +--- + + + + {icon === "external" && } + + + diff --git a/src/components/Landing/PaymentScenes.astro b/src/components/Landing/PaymentScenes.astro new file mode 100644 index 00000000..bfbb6a0d --- /dev/null +++ b/src/components/Landing/PaymentScenes.astro @@ -0,0 +1,472 @@ +--- +import { CardIn, Code, Globe, Nfc } from "@sumup-oss/icons"; +--- + + + + diff --git a/src/overrides/Hero.astro b/src/overrides/Hero.astro index 4077434a..e73d414c 100644 --- a/src/overrides/Hero.astro +++ b/src/overrides/Hero.astro @@ -4,28 +4,35 @@ import { Display, Body } from "@sumup-oss/circuit-ui"; const { data: { title }, } = Astro.locals.starlightRoute.entry; + +const { custom } = Astro.locals.starlightRoute; +const hideForLandingPage = custom && Astro.url.pathname === "/"; --- -
- - {title} - - - Docs, guides, and resources to help you accept payments with SumUp. - -
+{ + !hideForLandingPage && ( +
+ + {title} + + + Docs, guides, and resources to help you accept payments with SumUp. + +
+ ) +} + + diff --git a/src/pages/index.astro b/src/pages/index.astro index b774a17e..89851321 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,303 +1,1005 @@ --- +import { getCollection } from "astro:content"; + +import Brands from "@components/Landing/Brands.astro"; +import PaymentScenes from "@components/Landing/PaymentScenes.astro"; +import LinkButton from "@components/Landing/LinkButton.astro"; import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; import type { StarlightPageProps } from "@astrojs/starlight/props"; -import Brands from "@components/Landing/Brands.astro"; -import { Headline, ListItem } from "@sumup-oss/circuit-ui"; import { - Globe, Apps, CardIn, - VirtualTerminal, - Code, + Code as CodeIcon, Customise, File, - InterestOnBalance, + Globe, + History, Key, - NoCosts, Play, SecurePayments, Sparkles, + VirtualTerminal, } from "@sumup-oss/icons"; +const latestUpdates = (await getCollection("changelog")) + .sort( + (a, b) => b.data.publishedDate.valueOf() - a.data.publishedDate.valueOf(), + ) + .slice(0, 3); + +const dateFormatter = new Intl.DateTimeFormat("en", { + day: "numeric", + month: "short", + year: "numeric", +}); + +const products = [ + { + variant: "online", + icon: Globe, + title: "Online payments", + description: + "Accept cards and local payment methods with hosted, embedded, or mobile checkout experiences.", + links: [ + { + icon: Customise, + label: "Compare checkouts", + href: "/online-payments/checkouts/", + }, + { + icon: Globe, + label: "Browse payment methods", + href: "/online-payments/payment-methods/", + }, + { + icon: SecurePayments, + label: "Test payment flows", + href: "/online-payments/testing/", + }, + ], + cta: { label: "Start online", href: "/online-payments/" }, + }, + { + variant: "terminal", + icon: CardIn, + title: "In-person payments", + description: + "Add card-present payments to mobile apps, kiosks, and point-of-sale systems with SumUp readers.", + links: [ + { + icon: CodeIcon, + label: "Explore mobile SDKs", + href: "/terminal-payments/sdks/", + }, + { + icon: VirtualTerminal, + label: "Use the Cloud API", + href: "/terminal-payments/cloud-api/", + }, + { + icon: Play, + label: "Run your first payment", + href: "/terminal-payments/quickstart/", + }, + ], + cta: { label: "Explore in-person", href: "/terminal-payments/" }, + }, +]; + +const quickstartSteps = [ + { + title: "Create a sandbox", + description: "Get a test merchant account in Developer Settings.", + label: "Open Developer Settings", + href: "https://me.sumup.com/settings/developer?tab=sandboxes", + }, + { + title: "Get credentials", + description: "Choose an API key or OAuth flow for your integration.", + label: "Set up authorization", + href: "/tools/authorization/", + }, + { + title: "Create a checkout", + description: "Send an API request and open the hosted payment page.", + label: "Follow the guide", + href: "/online-payments/checkouts/hosted-checkout/", + }, +]; + +const toolkitItems = [ + { + icon: File, + title: "API reference", + description: "Endpoints, schemas, responses, and errors", + href: "/api/", + }, + { + icon: Apps, + title: "Server SDKs", + description: "Official libraries for popular languages", + href: "/tools/sdks/", + }, + { + icon: Key, + title: "Authorization", + description: "API keys, OAuth, and affiliate keys", + href: "/tools/authorization/", + }, + { + icon: SecurePayments, + title: "Testing", + description: "Sandbox accounts, test cards, and 3DS", + href: "/online-payments/testing/", + }, + { + icon: Sparkles, + title: "Build with AI", + description: "Docs context and tools for coding agents", + href: "/tools/llms/", + }, + { + icon: History, + title: "Changelog", + description: "Recent platform and SDK updates", + href: "/changelog/", + }, +]; + +const productionLinks = [ + { + icon: SecurePayments, + title: "Test safely", + description: "Success, failure, and 3D Secure scenarios", + href: "/online-payments/testing/", + }, + { + icon: Key, + title: "Protect credentials", + description: "Keep secret keys on your server", + href: "/tools/authorization/api-keys/", + }, + { + icon: Apps, + title: "Handle updates", + description: "Confirm asynchronous payment states", + href: "/online-payments/webhooks/", + }, +]; + const props = { frontmatter: { title: "SumUp Developer Portal", description: - "Welcome to SumUp portal for developers. We’ve got everything you need to build your own payment acceptance solutions for your business.", + "APIs, SDKs, and prebuilt experiences for accepting payments online and in person with SumUp.", tableOfContents: false, hero: { - title: "SumUp developer platform", + title: "Build payments with SumUp", }, }, + hasSidebar: false, custom: true, } as StarlightPageProps; --- -
-
-
- Accept Online Payments -
-
- Accept In-Person Payments - -
-
- Build and Operate - + +
+
+
+

One platform, wherever customers pay

+

+ Start with a prebuilt experience or use the APIs and SDKs to shape + the flow around your product. +

+
+ +
+ { + products.map( + ({ variant, icon: Icon, title, description, links, cta }) => ( + + ), + ) + }
-
-
-
-

Our Anti-fraud Protection

-
-
-
-
-
-
-
-

Brands That Build With SumUp

- -
-
+
+ { + latestUpdates.map(({ id, data }) => ( + + )) + } +
+ + +
+ +
+ +
-