1<!DOCTYPE html><html lang="en" class="h-full light" style="color-scheme:light"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/00_qip6bxs0c-.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/09940m05ilqsr.js"/>
1<script src="/_next/static/chunks/05pxe.pkwelhe.js" async=""></script>
1<script src="/_next/static/chunks/07lhk_q6pmm3r.js" async=""></script>
1<script src="/_next/static/chunks/turbopack-16nhj.bv36ch7.js" async=""></script>
1<script src="/_next/static/chunks/04piwhr-abret.js" async=""></script>
1<script src="/_next/static/chunks/16yqonoji0zr5.js" async=""></script>
1<script src="/_next/static/chunks/0dbhjjzl8qfwv.js" async=""></script>
1<script src="/_next/static/chunks/0hf5o765f_qpv.js" async=""></script>
1<title>Checkout API breakdown</title><meta name="description" content="Tag a checkout with your own order number, pay for it without leaving the page, and watch that number come back on the payment. Companion demo for the article on integrating Whop's checkout API."/>
1<script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script>
1</head><body class="min-h-full"><div hidden=""><!--$--><!--/$--></div><style> 2:root, .light, .light-theme { --color-page-background: white; } 3.dark, .dark-theme { --color-page-background: var(--gray-1); } 4body { background-color: var(--color-page-background); } 5</style><div data-is-root-theme="true" data-accent-color="blue" data-danger-color="red" data-warning-color="amber" data-success-color="green" data-info-color="sky" data-gray-color="gray" data-has-background="false" class="frosted-ui"><main class="min-h-screen bg-[#F1F1F1]"><div class="mx-auto flex max-w-6xl flex-col gap-6 px-4 py-8 sm:px-6 lg:flex-row lg:items-start"><aside class="order-2 flex shrink-0 flex-col gap-5 lg:order-1 lg:sticky lg:top-8 lg:w-[380px]"><div class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5"><h1 class="fui-Heading fui-r-size-4 fui-r-weight-bold">Checkout API breakdown</h1><p data-accent-color="gray" class="fui-Text mt-2 fui-r-size-2">A sale has two sides. Whop knows about the money. Only we know which order the money was for. This page joins them up.</p><p data-accent-color="gray" class="fui-Text mt-2 fui-r-size-2">Running on Whop's test sandbox, so the card is fake and no money moves.</p></div><div class="flex flex-col gap-1.5"><button data-accent-color="gray" type="button" class="fui-reset fui-BaseButton fui-Button step-rail-start w-full fui-r-size-3 fui-variant-surface">Start the walkthrough â</button><span data-accent-color="gray" class="fui-Text fui-r-size-1 fui-r-ta-center">6<!-- --> short steps, highlighted on the page as you go.</span></div></aside><section class="order-1 min-w-0 flex-1 lg:order-2"><div class="flex flex-col gap-4"><section data-annotation-id="catalogue" class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5"><div class="mb-3 flex items-center gap-2"><span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[#E5E4E0] text-[11px] font-semibold text-[#151515]/70">1</span><h2 class="fui-Heading fui-r-size-3 fui-r-weight-bold">What we are selling</h2></div><div class="flex flex-col gap-2"><div class="flex flex-wrap items-center gap-2"><span data-accent-color="gray" class="fui-Badge fui-r-size-1 fui-variant-soft">Product</span><code class="fui-Code fui-r-size-1 fui-variant-soft fui-r-weight-undefined">prod_jLdfTmqf1NAUr</code><span class="fui-Text fui-r-size-2">Pro pass</span></div><div class="flex flex-wrap items-center gap-2"><span data-accent-color="gray" class="fui-Badge fui-r-size-1 fui-variant-soft">Plan</span><code class="fui-Code fui-r-size-1 fui-variant-soft fui-r-weight-undefined">plan_KLVqo8rN40n3B</code><span class="fui-Text fui-r-size-2">$49.99<!-- -->, <!-- -->one_time</span></div><p data-accent-color="gray" class="fui-Text fui-r-size-1">Both were made with two terminal commands, then read back from Whop just now.</p></div></section><section data-annotation-id="order" class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5"><div class="mb-3 flex items-center gap-2"><span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[#E5E4E0] text-[11px] font-semibold text-[#151515]/70">2</span><h2 class="fui-Heading fui-r-size-3 fui-r-weight-bold">Our own order number</h2></div><div class="flex flex-col gap-2"><code class="fui-Code fui-r-size-2 fui-variant-soft fui-r-weight-undefined">order-a0eeb06e</code><p data-accent-color="gray" class="fui-Text fui-r-size-1">Ours, not Whop's. A real app would write a row in its database and use that row's id here.</p></div></section><section data-annotation-id="session" class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5"><div class="mb-3 flex items-center gap-2"><span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[#E5E4E0] text-[11px] font-semibold text-[#151515]/70">3</span><h2 class="fui-Heading fui-r-size-3 fui-r-weight-bold">Tag a checkout with it</h2></div><div class="flex flex-col gap-3"><p data-accent-color="gray" class="fui-Text fui-r-size-2">We attach the order number now, before the buyer sees a payment form.</p><button data-accent-color="gray" type="button" class="fui-reset fui-BaseButton fui-Button w-fit fui-r-size-2 fui-variant-surface">Make the checkout</button></div></section><section data-annotation-id="replay" class="rounded-xl border border-[#
5E5E4E0] bg-white p-4 shadow-sm sm:p-5"><div class="mb-3 flex items-center gap-2"><span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[#E5E4E0] text-[11px] font-semibold text-[#151515]/70">4</span><h2 class="fui-Heading fui-r-size-3 fui-r-weight-bold">Ask twice, get one</h2></div><div class="flex flex-col gap-3"><p data-accent-color="gray" class="fui-Text fui-r-size-2">The same request, sent again. A second checkout would mean a second chance to be charged.</p><button data-accent-color="gray" type="button" class="fui-reset fui-BaseButton fui-Button w-fit fui-r-size-2 fui-variant-soft" data-disabled="true" disabled="">Send it again</button></div></section><section data-annotation-id="pay" class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5"><div class="mb-3 flex items-center gap-2"><span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[#E5E4E0] text-[11px] font-semibold text-[#151515]/70">5</span><h2 class="fui-Heading fui-r-size-3 fui-r-weight-bold">Pay without leaving</h2></div><p data-accent-color="gray" class="fui-Text fui-r-size-2">Make the checkout in step 3 first.</p></section><section data-annotation-id="receipt" class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5"><div class="mb-3 flex items-center gap-2"><span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[#E5E4E0] text-[11px] font-semibold text-[#151515]/70">6</span><h2 class="fui-Heading fui-r-size-3 fui-r-weight-bold">The payment knows our number</h2></div><p data-accent-color="gray" class="fui-Text fui-r-size-2">Pay in step 5 and the answer lands here.</p></section><div class="rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm" data-annotation-id="activity"><div class="mb-2 flex items-center justify-between"><span class="fui-Text fui-r-size-2 fui-r-weight-bold">Activity log</span><span data-accent-color="gray" class="fui-Text fui-r-size-1">live</span></div><p data-accent-color="gray" class="fui-Text fui-r-size-1">Everything the page does behind the scenes shows up here.</p></div></div></section></div></main><!--$--><!--/$--></div>
5<script src="/_next/static/chunks/09940m05ilqsr.js" id="_R_" async=""></script>
5<script>(self.__next_f=self.__next_f||[]).push([0])</script>
5<script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57909,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"Theme\"]\n3:I[39756,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"default\"]\n4:I[37457,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"default\"]\n6:I[97367,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\n9:I[97367,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"ViewportBoundary\"]\nb:I[97367,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"MetadataBoundary\"]\nd:I[68027,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/00_qip6bxs0c-.css\",\"style\"]\n"])</script>
5<script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/00_qip6bxs0c-.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/04piwhr-abret.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/16yqonoji0zr5.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/0dbhjjzl8qfwv.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"h-full light\",\"style\":{\"colorScheme\":\"light\"},\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"min-h-full\",\"children\":[\"$\",\"$L2\",null,{\"appearance\":\"inherit\",\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[\"$L5\",[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0hf5o765f_qpv.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,null]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/00_qip6bxs0c-.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":false,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"hsuv27wa9RJLk6MVxnMCh\"}\n"])</script>
5<script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n8:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"Checkout API breakdown\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Tag a checkout with your own order number, pay for it without leaving the page, and watch that number come back on the payment. Companion demo for the article on integrating Whop's checkout API.\"}]]\n"])</script>
5<script>self.__next_f.push([1,"e:I[49778,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\",\"/_next/static/chunks/0hf5o765f_qpv.js\"],\"StepRail\"]\nf:I[23296,[\"/_next/static/chunks/04piwhr-abret.js\",\"/_next/static/chunks/16yqonoji0zr5.js\",\"/_next/static/chunks/0dbhjjzl8qfwv.js\",\"/_next/static/chunks/0hf5o765f_qpv.js\"],\"CheckoutLab\"]\n"])</script>
5<script>self.__next_f.push([1,"5:[\"$\",\"main\",null,{\"className\":\"min-h-screen bg-[#F1F1F1]\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto flex max-w-6xl flex-col gap-6 px-4 py-8 sm:px-6 lg:flex-row lg:items-start\",\"children\":[[\"$\",\"aside\",null,{\"className\":\"order-2 flex shrink-0 flex-col gap-5 lg:order-1 lg:sticky lg:top-8 lg:w-[380px]\",\"children\":[[\"$\",\"div\",null,{\"className\":\"rounded-xl border border-[#E5E4E0] bg-white p-4 shadow-sm sm:p-5\",\"children\":[[\"$\",\"h1\",null,{\"children\":\"Checkout API breakdown\",\"data-accent-color\":\"$undefined\",\"className\":\"fui-Heading fui-r-size-4 fui-r-weight-bold\",\"ref\":null}],[\"$\",\"p\",null,{\"children\":\"A sale has two sides. Whop knows about the money. Only we know which order the money was for. This page joins them up.\",\"data-accent-color\":\"gray\",\"className\":\"fui-Text mt-2 fui-r-size-2\",\"ref\":null}],[\"$\",\"p\",null,{\"children\":\"Running on Whop's test sandbox, so the card is fake and no money moves.\",\"data-accent-color\":\"gray\",\"className\":\"fui-Text mt-2 fui-r-size-2\",\"ref\":null}]]}],[\"$\",\"$Le\",null,{\"steps\":[{\"id\":\"catalogue\",\"title\":\"What we are selling\",\"body\":\"Two things, both made from the terminal with the Whop CLI. A product is the thing, a plan is the price on it. Nothing on this page was typed by hand.\"},{\"id\":\"order\",\"title\":\"Our own order number\",\"body\":\"This number belongs to our app, not to Whop. Everything else here exists to get it out to the checkout and back again.\"},{\"id\":\"session\",\"title\":\"Tag a checkout with it\",\"body\":\"We ask Whop for a checkout and attach our order number to it as `metadata`. That happens before the buyer sees anything.\"},{\"id\":\"replay\",\"title\":\"Ask twice, get one\",\"body\":\"We send the exact same request again with the same `Idempotency-Key`. Whop hands back the checkout it already made instead of a second one.\"},{\"id\":\"pay\",\"title\":\"Pay without leaving\",\"body\":\"The checkout is on this page, not on Whop's. Use `4242 4242 4242 4242` with any future date and any three digits.\"},{\"id\":\"receipt\",\"title\":\"The payment knows our number\",\"body\":\"We ask Whop what that payment was. Our order number comes back on it, which is how a payment finds its way to the right sale.\"}]}]]}],[\"$\",\"section\",null,{\"className\":\"order-1 min-w-0 flex-1 lg:order-2\",\"children\":[\"$\",\"$Lf\",null,{\"plan\":{\"productId\":\"prod_jLdfTmqf1NAUr\",\"productTitle\":\"Pro pass\",\"planId\":\"plan_KLVqo8rN40n3B\",\"priceLabel\":\"$$49.99\",\"planType\":\"one_time\"},\"environment\":\"sandbox\",\"returnUrl\":\"https://nextjs-whop-checkout-api-demo.vercel.app/\",\"initialOrderId\":\"order-a0eeb06e\"}]}]]}]}]\n"])</script>
5</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.