A runnable demo app that puts a Pro plan behind a login: checkout with the user’s ID, a success page and a webhook that unlock Pro, an access check, the user’s invoices with PDFs, and cancel and upgrade.
The demo on this page is a Notes app with a Pro plan. A signed-in user clicks Upgrade to Pro, pays on the checkout, and comes back with Pro unlocked. The home page then shows the plan and its next charge, a Manage plan section to cancel or upgrade, and My invoices with the invoice PDF and the receipt for each payment. Every call goes to the AgentaOS API through the @agentaos/pay SDK, from the app’s server.
The demo after a paid checkout: the plan, its renewal, Manage plan, and My invoices.
The app is in examples/paywall-demo in the AgentaOS repository. It uses Node.js, Express, and plain HTML. The login is fake (you pick a user) and the database is a JSON file, so every other line is the integration itself.
File
What it does
src/checkout.ts
Creates the checkout (POST /upgrade) and confirms it (GET /success)
You need Node.js 20 or later, pnpm, and an AgentaOS account in test mode.
1
Install
Clone the AgentaOS repository, then install and build the SDK from its root:
pnpm installpnpm -F @agentaos/pay build
2
Create the plan
In the dashboard, create a monthly subscription plan. The steps and screens are in Sell a subscription. On the plan’s page, open Building this into your site? and click Copy ID. For the upgrade button, create a second plan in the same currency and with the same interval, and copy its ID too.
3
Fill in the settings
cd examples/paywall-democp .env.example .env
In .env, set AGENTAOS_API_KEY to a test key: in the dashboard, open Developers → API keys in the sidebar and click Generate Test Key. Set PRO_LINK_ID and PRO_PLUS_LINK_ID to the two plan IDs. Set AGENTAOS_WEBHOOK_SECRET to the signing secret from Settings → Developers → Webhooks, Reveal signing secret.
4
Make a local certificate
The checkout sends the buyer back only to an https address, and https://localhost is refused. The demo therefore runs on https://127.0.0.1:4567 with a self-signed certificate:
pnpm cert
5
Start the app
pnpm dev
Open https://127.0.0.1:4567 and accept the browser’s certificate warning once. Sign in as Ada. The plan says Free.
6
Upgrade and pay
Click Upgrade to Pro. The checkout opens with Ada’s email already filled in. Pick a country and click Continue to payment. Pay with the test card 4242 4242 4242 4242, any future expiry date, and any CVC.
The checkout for a plan with a 14-day free trial: nothing is due today.
After payment, the checkout sends you to /success?sessionId=.... The page reads the checkout from the API. While the checkout is still open, it says “Still processing” with a Refresh button. Once the checkout is completed, it says “You are on Pro”.
Back on the home page, the plan shows the status and the date of the first charge.
When the user clicks Upgrade to Pro, the server creates a checkout from the plan’s link ID. It puts the user’s own ID in metadata, so the success page and the webhook can tell who paid. Do not send signed-in users the plan’s shared link: that link carries no metadata.
src/checkout.ts
export async function upgrade(_req: Request, res: Response): Promise<void> { const user: User = res.locals.user; // A second click reuses the open checkout instead of creating another one. if (user.pendingSessionId) { const pending = await agentaos.checkouts.retrieve(user.pendingSessionId); if (pending.status === 'open') { res.redirect(303, pending.checkoutUrl); return; } } const checkout = await agentaos.checkouts.create({ linkId: config.proLinkId, buyerEmail: user.email, metadata: { customerId: user.id }, successUrl: `${config.appUrl}/success`, cancelUrl: `${config.appUrl}/`, }); updateUser(user.id, { pendingSessionId: checkout.sessionId }); res.redirect(303, checkout.checkoutUrl);}
The SDK sends an idempotency key with every create call and reuses it when it retries after a network error or a server error, so one call makes one checkout. The success URL must start with https://. The checkout adds ?sessionId= to it when it sends the buyer back.
Anyone can open the success URL, so the page never unlocks from the redirect alone. It reads the checkout with checkouts.retrieve, checks that the checkout belongs to the signed-in user, and unlocks Pro only when the status is completed.
metadata.subscriptionId is the ID of the new subscription. grantPro stores it on the user, because it is the only link between later events and the user. In the demo run, the checkout for the paid plan was completed at the first load of the success page. The checkout for the plan with a free trial was open at first and became completed after a few refreshes.
The webhook unlocks the user even when they close the tab before the success page loads. It verifies the signature over the raw body, so the route is mounted with express.raw() before any body parser. See Receive webhooks in Express.
src/webhooks.ts
switch (event.type) { case 'checkout.session.completed': { const { sessionId, metadata } = event.data; const subscriptionId = typeof metadata.subscriptionId === 'string' ? metadata.subscriptionId : null; if (typeof metadata.customerId === 'string') { // First payment, or the start of a free trial. grantPro({ userId: metadata.customerId, subscriptionId, sessionId }); } else if (subscriptionId) { // A renewal carries no customerId: match it by the stored subscription ID. recordRenewal({ subscriptionId, sessionId }); } break; } case 'subscription.updated': case 'subscription.canceled': { const user = findUserBySubscription(event.data.id); if (user) updateUser(user.id, { subscriptionStatus: event.data.status }); break; } } res.sendStatus(200);
A renewal’s checkout.session.completed has its own sessionId and does not carry your customerId, so the stored subscription ID is the only way to find the user. webhooks.verify() returns every key in camelCase, including the keys inside metadata. The route answers 400 to a bad signature and 200 to every verified event.AgentaOS does not deliver webhooks to a private address such as 127.0.0.1, so the demo on your machine receives no events. The success page unlocks Pro without them. To test the route locally, run pnpm webhook:test: it signs sample events with AGENTAOS_WEBHOOK_SECRET and posts them to /webhooks.
bad signature -> 400renewal -> 200same renewal again -> 200subscription.updated -> 200
To receive real events, expose the app through a public HTTPS tunnel, enter its /webhooks URL as the Webhook URL in Settings → Developers → Webhooks, and click Send test event.
The same event can arrive more than once, and the success page and the webhook both report the first payment. grantPro and recordRenewal record each sessionId and do nothing for a session they have already seen. In the demo run, the webhook replay of Grace’s first payment logged already handled. In your database, a unique constraint on the session ID does the same when two requests arrive at the same moment.
With a free trial, the buyer pays nothing at checkout and the subscription starts as trialing. The webhook still receives checkout.session.completed, with amount"0" and metadata.trial set to true: treat it as a trial start, not as money received. The checkout that checkouts.retrieve returns has no trial key in its metadata, so read the trial state from the subscription’s status. The first charge happens when the trial ends. See Free trials.
Before the Pro page, requirePro reads the user’s subscription by the stored ID and allows active or trialing. subscriptions.list() does not return your metadata, so the stored ID is the lookup key.
src/access.ts
export async function findSubscription(id: string | null): Promise<Subscription | null> { if (!id) return null; for (let offset = 0; ; offset += 100) { const page = await agentaos.subscriptions.list({ limit: 100, offset }); const found = page.items.find((s) => s.id === id); if (found) return found; if (!page.hasMore) return null; }}export function isPro(subscription: Subscription | null): boolean { return subscription?.status === 'active' || subscription?.status === 'trialing';}
The home page reads the same subscription for its plan card:
currentPeriodEnd: the end of the current period and the date of the next charge.
cancelAtPeriodEnd: true after the user cancels. Access ends at effectiveCancelDate.
planName and unitAmountMinor: the plan and the charge per period in integer minor units, tax included. For the €29.00 plan, the demo run returned 3596 (€35.96).
pendingPlanChange: set when a downgrade waits for the period end.
subscriptions.invoices(id) returns the invoice of each billing cycle of one subscription, newest first. Its amount is in currency units, not minor units: 60.76 for Grace’s first payment. The invoice list has no filter by buyer, so the subscription ID is the key here too.invoices.downloadPdf(id) and invoices.getReceipt(id) return the PDF as a Buffer, not a URL. The demo’s server checks that the invoice belongs to the user’s subscription, then sends the bytes. An invoice ID from another user gets a 404.
src/invoices.ts
export async function userInvoices(user: User): Promise<SubscriptionInvoice[]> { if (!user.subscriptionId) return []; return agentaos.subscriptions.invoices(user.subscriptionId);}export async function downloadInvoice(req: Request, res: Response): Promise<void> { const user: User = res.locals.user; const id = String(req.params.id); const kind = req.path.endsWith('/receipt') ? 'receipt' : 'invoice'; const invoice = (await userInvoices(user)).find((i) => i.id === id); if (!invoice) { res.status(404).send('Not found'); return; } const pdf = kind === 'receipt' ? await agentaos.invoices.getReceipt(id) : await agentaos.invoices.downloadPdf(id); res.type('application/pdf').attachment(`${kind}-${invoice.invoiceNumber}.pdf`).send(pdf);}
A subscription in its free trial has no invoice yet. The first one comes with the first charge, when the trial ends. In test mode the PDF is marked “TEST MODE: not a tax invoice” and its number starts with TEST-.
Cancel plan calls subscriptions.cancel. The subscription ends at the end of the current period, nothing is refunded, and the user keeps Pro until then. The server rejects an immediate cancellation.
Upgrade to Pro Plus quotes the change with previewPlanChange and shows the amounts. Confirm upgrade applies it with the quote’s prorationDate, so the charge equals the quote.
await agentaos.subscriptions.changePlan(subscriptionOf(res), { targetLinkId: config.proPlusLinkId, // The quote's prorationDate makes the charge equal the amount the user saw. prorationDate: Number(req.body.prorationDate), });
The quote’s direction is upgrade, downgrade, or revert. An upgrade charges the prorated difference now and applies at once. A downgrade charges nothing and starts at the end of the period. A revert cancels a pending downgrade. During a free trial, the upgrade quote is €0.00 due today. See Upgrade and downgrade.
Login: replace the demo’s cookie login in src/session.ts with your own authentication.
Database: replace the JSON file in src/store.ts with tables. Put a unique constraint on the processed session ID.
Webhook: register https://yourapp.com/webhooks in the dashboard and set its signing secret in AGENTAOS_WEBHOOK_SECRET.
Live key: use your live key (sk_live_...) on the live server. Keep it out of the browser and out of git.
Test and live: every event carries livemode. Ignore events with livemode: false on the live server.
Address: set APP_URL to your public https address, and remove TLS_CERT and TLS_KEY when a proxy handles TLS in front of the app.
To keep the user on your site, you can embed the checkout instead of redirecting: create the checkout on your server as above and pass its sessionId to the embedded checkout.
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"AgentaOS","colors":{"primary":"#4F46E5","light":"#A5B4FC","dark":"#4338CA"},"logo":{"light":"https://mintcdn.com/agentokratia/m99r4jmD11JEgdx5/images/agentaos-icon.png?fit=max\u0026auto=format\u0026n=m99r4jmD11JEgdx5\u0026q=85\u0026s=0b6178b7724b65d6c92a4e09b7f7f577","dark":"https://mintcdn.com/agentokratia/m99r4jmD11JEgdx5/images/agentaos-icon.png?fit=max\u0026auto=format\u0026n=m99r4jmD11JEgdx5\u0026q=85\u0026s=0b6178b7724b65d6c92a4e09b7f7f577","href":"https://agentaos.ai"},"favicon":"https://mintcdn.com/agentokratia/m99r4jmD11JEgdx5/images/agentaos-icon.png?fit=max\u0026auto=format\u0026n=m99r4jmD11JEgdx5\u0026q=85\u0026s=0b6178b7724b65d6c92a4e09b7f7f577","api":{"openapi":"openapi.json"},"appearance":{"default":"system"},"background":{"decoration":"grid","color":{"light":"#FFFFFF","dark":"#0B1533"}},"navbar":{"links":[{"href":"https://agentaos.ai","label":"Website"}],"primary":{"type":"button","label":"Dashboard","href":"https://app.agentaos.ai"}},"footer":{"socials":{"github":"https://github.com/AgentaOS/agentaos","x":"https://x.com/agentaos","linkedin":"https://linkedin.com/company/agentaos"},"links":[{"header":"Product","items":[{"label":"Pricing","href":"/mor/pricing"},{"label":"Supported countries","href":"/mor/supported-countries"},{"label":"Product release phases","href":"/getting-started/release-phases"}]},{"header":"Developers","items":[{"label":"API reference","href":"/api-reference/introduction"},{"label":"SDK","href":"/sdk/pay-overview"},{"label":"CLI","href":"/cli/install"},{"label":"Changelog","href":"/changelog/overview"}]},{"header":"Company","items":[{"label":"Website","href":"https://agentaos.ai"},{"label":"Support","href":"mailto:contact@agentaos.ai"},{"label":"Why was I charged?","href":"/for-customers/why-charged"}]}]},"search":{"prompt":"Search docs..."},"fonts":{"heading":{"family":"Bricolage Grotesque"},"body":{"family":"Inter"}},"icons":{"library":"fontawesome"},"styling":{"eyebrows":"section","codeblocks":"system","latex":false},"banner":{"content":"AgentaOS is the Merchant of Record for AI founders. [Sell software globally →](https://agentaos.ai)","dismissible":true},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"thumbnails":{"appearance":"dark"},"navigation":{"global":{"anchors":[{"anchor":"llms.txt","icon":"file-lines","href":"/llms-full.txt"},{"anchor":"Support","icon":"life-ring","href":"mailto:contact@agentaos.ai"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"agentokratia","hasAudioNarration":false,"actualSubdomain":"agentokratia","customDomains":["docs.agentaos.ai"],"gitSource":{"type":"github","owner":"agentaos","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{},"buildId":"6ae7c2fe766ca8399e8318b9","clientVersion":"0.0.4124","searchFilterCounts":[{"language":"default","tag":"Reference","count":75},{"language":"default","tag":"API Reference","count":51},{"language":"default","tag":"Documentation","count":38},{"language":"default","tag":"SDK","count":13},{"language":"default","tag":"Guides","count":12},{"language":"default","tag":"CLI","count":11},{"language":"default","tag":"Invoices","count":8},{"language":"default","tag":"Subscriptions","count":8},{"language":"default","tag":"Sell","count":8},{"language":"default","tag":"Payouts","count":7}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[{"filePath":"custom.css","content":"[data-component-part=\"card-icon\"]{background:rgba(79, 70, 229, 0.08);border-radius:0.5rem;padding:0.4rem}.dark [data-component-part=\"card-icon\"]{background:rgba(165, 180, 252, 0.12)}.card{border:1px solid rgba(79, 70, 229, 0.08);transition:all 0.2s ease}.card:hover{border-color:rgba(79, 70, 229, 0.22);box-shadow:0 8px 24px rgba(79, 70, 229, 0.07);transform:translateY(-1px)}.dark .card:hover{box-shadow:0 8px 24px rgba(79, 70, 229, 0.14)}h1{letter-spacing:-0.02em}h2{margin-top:2rem}table th{background:rgba(79, 70, 229, 0.04);font-weight:600}.dark table th{background:rgba(79, 70, 229, 0.10)}table tr:hover{background:rgba(79, 70, 229, 0.02)}pre{border:1px solid rgba(11, 21, 51, 0.08)!important;border-radius:8px!important}#content-area a.link,.prose a.link{color:#4F46E5!important;text-decoration:underline;text-decoration-color:rgba(79, 70, 229, 0.35);text-underline-offset:2px;font-weight:500}#content-area a.link:hover,.prose a.link:hover{text-decoration-color:#4F46E5!important}.dark #content-area a.link,.dark .prose a.link{color:#A5B4FC!important;text-decoration-color:rgba(165, 180, 252, 0.4)}#banner{background-color:#0B1533!important}.preview-pill{display:inline-block;vertical-align:baseline;margin-right:0.35rem;padding:0.1rem 0.55rem;border-radius:9999px;font-size:0.72rem;font-weight:600;letter-spacing:0.02em;line-height:1.4;color:#4338CA;background:rgba(79, 70, 229, 0.12);white-space:nowrap}.dark .preview-pill{color:#C7D2FE;background:rgba(165, 180, 252, 0.16)}.preview-pill-public{color:#047857;background:rgba(16, 185, 129, 0.12)}.dark .preview-pill-public{color:#A7F3D0;background:rgba(52, 211, 153, 0.16)}"}],"page":{"pagePath":"sdk/paywall-for-logged-in-users","slug":"/sdk/paywall-for-logged-in-users","pageMetadata":{"title":"Paywall for logged-in users","description":"A runnable demo app that puts a Pro plan behind a login: checkout with the user's ID, a success page and a webhook that unlock Pro, an access check, the user's invoices with PDFs, and cancel and upgrade.","icon":"lock","href":"/sdk/paywall-for-logged-in-users"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"A runnable demo app that puts a Pro plan behind a login: checkout with the user’s ID, a success page and a webhook that unlock Pro, an access check, the user’s invoices with PDFs, and cancel and upgrade.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Card,CodeBlock,Columns,Frame,Heading,OptimizedImage,Step,Steps,Table}=_components;if(!Card)_missingMdxReference(`Card`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Columns)_missingMdxReference(`Columns`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Table)_missingMdxReference(`Table`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`The demo on this page is a Notes app with a Pro plan. A signed-in user clicks `,_jsx(_components.strong,{children:`Upgrade to Pro`}),`, pays on the checkout, and comes back with Pro unlocked. The home page then shows the plan and its next charge, a `,_jsx(_components.strong,{children:`Manage plan`}),` section to cancel or upgrade, and `,_jsx(_components.strong,{children:`My invoices`}),` with the invoice PDF and the receipt for each payment. Every call goes to the AgentaOS API through the `,_jsx(_components.code,{children:`@agentaos/pay`}),` SDK, from the app’s server.`]}),`\n`,_jsx(Frame,{caption:`The demo after a paid checkout: the plan, its renewal, Manage plan, and My invoices.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=ea570f66a7e156f1231eebc4d97e1718`,alt:`The Notes demo signed in as Grace: Your plan Pro Plus, active, Renews on Oct 29, 2026: €60.76 per month, a Cancel plan button, and My invoices with INV-2026-0006, Sep 29, 2026, €60.76, paid, and the links Invoice PDF and Receipt.`,\"data-og-width\":`1440`,width:`1440`,\"data-og-height\":`900`,height:`900`,\"data-path\":`images/paywall/demo-invoices.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?w=280\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=1e9810e9e62b4e4e0b4e4e14f172e4a6 280w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?w=560\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=5402d4f488166da800f04b457a32f74d 560w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?w=840\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=c756b519b33ad0321bc92cb078b1cd13 840w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?w=1100\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=4525efb073eef2aac123fd659df1d2c6 1100w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?w=1650\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=6654700c219268d21d355a2cdc0d9399 1650w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-invoices.png?w=2500\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=06fb952b735f5143d26f37cdf4306d3f 2500w`})}),`\n`,_jsx(Heading,{level:`2`,id:`the-demo-app`,children:`The demo app`}),`\n`,_jsxs(_components.p,{children:[`The app is in `,_jsx(_components.code,{children:`examples/paywall-demo`}),` in the `,_jsx(_components.a,{href:`https://github.com/AgentaOS/agentaos/tree/main/examples/paywall-demo`,children:`AgentaOS repository`}),`. It uses Node.js, Express, and plain HTML. The login is fake (you pick a user) and the database is a JSON file, so every other line is the integration itself.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`File`}),_jsx(_components.th,{children:`What it does`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`src/checkout.ts`})}),_jsxs(_components.td,{children:[`Creates the checkout (`,_jsx(_components.code,{children:`POST /upgrade`}),`) and confirms it (`,_jsx(_components.code,{children:`GET /success`}),`)`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`src/webhooks.ts`})}),_jsxs(_components.td,{children:[`Verifies and handles events (`,_jsx(_components.code,{children:`POST /webhooks`}),`)`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`src/grant.ts`})}),_jsx(_components.td,{children:`Unlocks Pro once per checkout`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`src/access.ts`})}),_jsx(_components.td,{children:`Reads the subscription and guards the Pro page`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`src/invoices.ts`})}),_jsx(_components.td,{children:`Lists the user’s invoices and sends the PDFs`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`src/plan.ts`})}),_jsx(_components.td,{children:`Cancels, quotes an upgrade, and applies it`})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`run-it`,children:`Run it`}),`\n`,_jsx(_components.p,{children:`You need Node.js 20 or later, pnpm, and an AgentaOS account in test mode.`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Install`,children:[_jsxs(_components.p,{children:[`Clone the `,_jsx(_components.a,{href:`https://github.com/AgentaOS/agentaos`,children:`AgentaOS repository`}),`, then install and build the SDK from its root:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pnpm`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` install`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pnpm`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -F`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @agentaos/pay`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` build`})]}),`\n`]})})})]}),_jsx(Step,{title:`Create the plan`,children:_jsxs(_components.p,{children:[`In the dashboard, create a monthly subscription plan. The steps and screens are in `,_jsx(_components.a,{href:`/guides/sell-a-subscription#create-the-plan`,children:`Sell a subscription`}),`. On the plan’s page, open `,_jsx(_components.strong,{children:`Building this into your site?`}),` and click `,_jsx(_components.strong,{children:`Copy ID`}),`. For the upgrade button, create a second plan in the same currency and with the same interval, and copy its ID too.`]})}),_jsxs(Step,{title:`Fill in the settings`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`cd`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` examples/paywall-demo`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`cp`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .env.example`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .env`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`In `,_jsx(_components.code,{children:`.env`}),`, set `,_jsx(_components.code,{children:`AGENTAOS_API_KEY`}),` to a test key: in the dashboard, open `,_jsx(_components.strong,{children:`Developers → API keys`}),` in the sidebar and click `,_jsx(_components.strong,{children:`Generate Test Key`}),`. Set `,_jsx(_components.code,{children:`PRO_LINK_ID`}),` and `,_jsx(_components.code,{children:`PRO_PLUS_LINK_ID`}),` to the two plan IDs. Set `,_jsx(_components.code,{children:`AGENTAOS_WEBHOOK_SECRET`}),` to the signing secret from `,_jsx(_components.strong,{children:`Settings → Developers → Webhooks`}),`, `,_jsx(_components.strong,{children:`Reveal signing secret`}),`.`]})]}),_jsxs(Step,{title:`Make a local certificate`,children:[_jsxs(_components.p,{children:[`The checkout sends the buyer back only to an `,_jsx(_components.code,{children:`https`}),` address, and `,_jsx(_components.code,{children:`https://localhost`}),` is refused. The demo therefore runs on `,_jsx(_components.code,{children:`https://127.0.0.1:4567`}),` with a self-signed certificate:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pnpm`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` cert`})]}),`\n`]})})})]}),_jsxs(Step,{title:`Start the app`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pnpm`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` dev`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`Open `,_jsx(_components.code,{children:`https://127.0.0.1:4567`}),` and accept the browser’s certificate warning once. Sign in as Ada. The plan says `,_jsx(_components.strong,{children:`Free`}),`.`]}),_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=ffaffa012d1e05ee16d43914ec7ec3ec`,alt:`The Notes demo signed in as Ada: Your plan Free, Pro unlocks unlimited notes and sharing, and an Upgrade to Pro button.`,\"data-og-width\":`1440`,width:`1440`,\"data-og-height\":`900`,height:`900`,\"data-path\":`images/paywall/demo-home-free.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?w=280\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=6e024a95be799a9a9ff43dd0eb6ac8e8 280w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?w=560\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=7c320b8c81530a783f1ce2b52cb145c2 560w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?w=840\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=7101ae40dc14ad3fff61308376d71e2d 840w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?w=1100\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=e69bc60e5aff2b97391d4340beb50e00 1100w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?w=1650\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=3a05db009dc82f505490cbd5defbec4c 1650w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-free.png?w=2500\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=10a2cc470139734897b5500b62d0ae21 2500w`})})]}),_jsxs(Step,{title:`Upgrade and pay`,children:[_jsxs(_components.p,{children:[`Click `,_jsx(_components.strong,{children:`Upgrade to Pro`}),`. The checkout opens with Ada’s email already filled in. Pick a country and click `,_jsx(_components.strong,{children:`Continue to payment`}),`. Pay with the test card `,_jsx(_components.code,{children:`4242 4242 4242 4242`}),`, any future expiry date, and any CVC.`]}),_jsx(Frame,{caption:`The checkout for a plan with a 14-day free trial: nothing is due today.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=0cfd937711ea500cf0b5d4c2eb53e475`,alt:`The checkout for Pro: €29.00, DUE TODAY €0.00, Then €29.00/mo after your 14-day free trial, the email ada@example.com Set by AgencyOne, Country Germany, and a Continue to payment button.`,\"data-og-width\":`1440`,width:`1440`,\"data-og-height\":`900`,height:`900`,\"data-path\":`images/paywall/checkout.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?w=280\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=fda602d353c9b2bb46732c1bc08b41f9 280w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?w=560\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=d8e8f32175b9b30c032976690745492a 560w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?w=840\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=5fdec781da38e8866b808ea4438b6dfa 840w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?w=1100\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=620a1ba1102ab0cb8202b78a18dbcfa3 1100w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?w=1650\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=e21762a87193a1a0209b11439e17d0b8 1650w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/checkout.png?w=2500\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=558c646a5f287ff95870c30798114cff 2500w`})}),_jsxs(_components.p,{children:[`After payment, the checkout sends you to `,_jsx(_components.code,{children:`/success?sessionId=...`}),`. The page reads the checkout from the API. While the checkout is still `,_jsx(_components.code,{children:`open`}),`, it says “Still processing” with a `,_jsx(_components.strong,{children:`Refresh`}),` button. Once the checkout is `,_jsx(_components.code,{children:`completed`}),`, it says “You are on Pro”.`]}),_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=d304458a5ff898f7f4a0e723e8dce5c8`,alt:`The success page: You are on Pro. Thanks. Your payment is confirmed and Pro is unlocked. A Go to Notes button.`,\"data-og-width\":`1440`,width:`1440`,\"data-og-height\":`900`,height:`900`,\"data-path\":`images/paywall/demo-success.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?w=280\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=f0f1d2d5706747efdf46234714f4bc7e 280w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?w=560\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=4dbeab2f00dfa407fffa7ed3e4571740 560w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?w=840\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=17b5b1c610ea6fae2ff21a5336190802 840w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?w=1100\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=e3d4d5c27c6e1a7e7fcf1ed68222858f 1100w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?w=1650\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=c43eb043344cdec78eedefaccb563332 1650w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-success.png?w=2500\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=96b0008ba1705b26909fcaa482b7cb04 2500w`})}),_jsx(_components.p,{children:`Back on the home page, the plan shows the status and the date of the first charge.`}),_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=476d151fcc2783d0f03660e209b84c1f`,alt:`The Notes demo for Ada after the checkout: Your plan Pro, trialing, Free trial. First charge on Oct 13, 2026: €35.96 per month. Buttons Upgrade to Pro Plus and Cancel plan. My invoices: No invoices yet.`,\"data-og-width\":`1440`,width:`1440`,\"data-og-height\":`900`,height:`900`,\"data-path\":`images/paywall/demo-home-pro.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?w=280\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=17bba513c95b7d61e23285ad5e1c113b 280w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?w=560\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=74b5c0a7dcd0959e5ad58d459b5f3d84 560w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?w=840\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=e81cd941891359eed705a048d7845aef 840w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?w=1100\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=049161e44ed0cccde82c648662857aff 1100w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?w=1650\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=472710c7acf0da45147b6a5671c49d96 1650w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-home-pro.png?w=2500\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=6736d735e15755e0cea90d0d839e0d2a 2500w`})})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`how-it-works`,children:`How it works`}),`\n`,_jsx(Heading,{level:`3`,id:`the-checkout-carries-your-user-id`,children:`The checkout carries your user ID`}),`\n`,_jsxs(_components.p,{children:[`When the user clicks `,_jsx(_components.strong,{children:`Upgrade to Pro`}),`, the server creates a checkout from the plan’s link ID. It puts the user’s own ID in `,_jsx(_components.code,{children:`metadata`}),`, so the success page and the webhook can tell who paid. Do not send signed-in users the plan’s shared link: that link carries no `,_jsx(_components.code,{children:`metadata`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:`src/checkout.ts`,numberOfLines:`22`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`22`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` upgrade`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`_req`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Request`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Promise`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`void`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` user`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` User`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`locals`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`\t// A second click reuses the open checkout instead of creating another one.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pendingSessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` pending`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkouts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`retrieve`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pendingSessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pending`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'open'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\t\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`redirect`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`303`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pending`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkoutUrl`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\t\treturn`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` checkout`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkouts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`create`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tlinkId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` config`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`proLinkId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tbuyerEmail:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`email`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tmetadata:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`customerId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tsuccessUrl:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`config`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`appUrl`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"/success`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tcancelUrl:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`config`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`appUrl`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"/`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t});`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\tupdateUser`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pendingSessionId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` checkout`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`redirect`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`303`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkout`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkoutUrl`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The SDK sends an idempotency key with every create call and reuses it when it retries after a network error or a server error, so one call makes one checkout. The success URL must start with `,_jsx(_components.code,{children:`https://`}),`. The checkout adds `,_jsx(_components.code,{children:`?sessionId=`}),` to it when it sends the buyer back.`]}),`\n`,_jsx(Heading,{level:`3`,id:`the-success-page-asks-the-api`,children:`The success page asks the API`}),`\n`,_jsxs(_components.p,{children:[`Anyone can open the success URL, so the page never unlocks from the redirect alone. It reads the checkout with `,_jsx(_components.code,{children:`checkouts.retrieve`}),`, checks that the checkout belongs to the signed-in user, and unlocks Pro only when the status is `,_jsx(_components.code,{children:`completed`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:`src/checkout.ts`,numberOfLines:`15`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`15`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` checkout`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkouts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`retrieve`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkout`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`customerId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` !==`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`status`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`404`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'Not found'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\treturn`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkout`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'completed'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\tconst`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` checkout`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\t\tgrantPro`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\t\tuserId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\t\tsubscriptionId:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` typeof`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` subscriptionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'string'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ?`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` subscriptionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` :`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\t\tsessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t});`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`successPage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`checkout`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`));`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`metadata.subscriptionId`}),` is the ID of the new subscription. `,_jsx(_components.code,{children:`grantPro`}),` stores it on the user, because it is the only link between later events and the user. In the demo run, the checkout for the paid plan was `,_jsx(_components.code,{children:`completed`}),` at the first load of the success page. The checkout for the plan with a free trial was `,_jsx(_components.code,{children:`open`}),` at first and became `,_jsx(_components.code,{children:`completed`}),` after a few refreshes.`]}),`\n`,_jsx(Heading,{level:`3`,id:`the-webhook-unlocks-pro-and-matches-renewals`,children:`The webhook unlocks Pro and matches renewals`}),`\n`,_jsxs(_components.p,{children:[`The webhook unlocks the user even when they close the tab before the success page loads. It verifies the signature over the raw body, so the route is mounted with `,_jsx(_components.code,{children:`express.raw()`}),` before any body parser. See `,_jsx(_components.a,{href:`/sdk/handle-webhooks`,children:`Receive webhooks in Express`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:`src/webhooks.ts`,numberOfLines:`22`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`22`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tswitch`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\tcase`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'checkout.session.completed'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\t\tconst`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`sessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`data`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\t\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` subscriptionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\t\t\ttypeof`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'string'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ?`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` :`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\t\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`typeof`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`customerId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'string'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`\t\t\t\t// First payment, or the start of a free trial.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\t\t\t\tgrantPro`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`userId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`customerId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t\t} `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`else`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`\t\t\t\t// A renewal carries no customerId: match it by the stored subscription ID.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\t\t\t\trecordRenewal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t\t}`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\t\tbreak`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t}`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\tcase`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'subscription.updated'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\tcase`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'subscription.canceled'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\t\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` user`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` findUserBySubscription`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`data`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\t\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUser`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionStatus:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`data`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\t\tbreak`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`sendStatus`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`200`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`A renewal’s `,_jsx(_components.code,{children:`checkout.session.completed`}),` has its own `,_jsx(_components.code,{children:`sessionId`}),` and does not carry your `,_jsx(_components.code,{children:`customerId`}),`, so the stored subscription ID is the only way to find the user. `,_jsx(_components.code,{children:`webhooks.verify()`}),` returns every key in camelCase, including the keys inside `,_jsx(_components.code,{children:`metadata`}),`. The route answers `,_jsx(_components.code,{children:`400`}),` to a bad signature and `,_jsx(_components.code,{children:`200`}),` to every verified event.`]}),`\n`,_jsxs(_components.p,{children:[`AgentaOS does not deliver webhooks to a private address such as `,_jsx(_components.code,{children:`127.0.0.1`}),`, so the demo on your machine receives no events. The success page unlocks Pro without them. To test the route locally, run `,_jsx(_components.code,{children:`pnpm webhook:test`}),`: it signs sample events with `,_jsx(_components.code,{children:`AGENTAOS_WEBHOOK_SECRET`}),` and posts them to `,_jsx(_components.code,{children:`/webhooks`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`bad signature -> 400`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`renewal -> 200`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`same renewal again -> 200`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`subscription.updated -> 200`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`To receive real events, expose the app through a public HTTPS tunnel, enter its `,_jsx(_components.code,{children:`/webhooks`}),` URL as the `,_jsx(_components.strong,{children:`Webhook URL`}),` in `,_jsx(_components.strong,{children:`Settings → Developers → Webhooks`}),`, and click `,_jsx(_components.strong,{children:`Send test event`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`each-payment-unlocks-once`,children:`Each payment unlocks once`}),`\n`,_jsxs(_components.p,{children:[`The same event can arrive more than once, and the success page and the webhook both report the first payment. `,_jsx(_components.code,{children:`grantPro`}),` and `,_jsx(_components.code,{children:`recordRenewal`}),` record each `,_jsx(_components.code,{children:`sessionId`}),` and do nothing for a session they have already seen. In the demo run, the webhook replay of Grace’s first payment logged `,_jsx(_components.code,{children:`already handled`}),`. In your database, a unique constraint on the session ID does the same when two requests arrive at the same moment.`]}),`\n`,_jsx(CodeBlock,{filename:`src/grant.ts`,numberOfLines:`8`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` grantPro`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`input`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`\tuserId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`\tsubscriptionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`\tsessionId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`})`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` void`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` granted`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` onceForSession`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`input`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sessionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, () `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\t\tupdateUser`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`input`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`userId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` input`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pendingSessionId:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t);`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`free-trials`,children:`Free trials`}),`\n`,_jsxs(_components.p,{children:[`With a free trial, the buyer pays nothing at checkout and the subscription starts as `,_jsx(_components.code,{children:`trialing`}),`. The webhook still receives `,_jsx(_components.code,{children:`checkout.session.completed`}),`, with `,_jsx(_components.code,{children:`amount`}),` `,_jsx(_components.code,{children:`\"0\"`}),` and `,_jsx(_components.code,{children:`metadata.trial`}),` set to `,_jsx(_components.code,{children:`true`}),`: treat it as a trial start, not as money received. The checkout that `,_jsx(_components.code,{children:`checkouts.retrieve`}),` returns has no `,_jsx(_components.code,{children:`trial`}),` key in its `,_jsx(_components.code,{children:`metadata`}),`, so read the trial state from the subscription’s `,_jsx(_components.code,{children:`status`}),`. The first charge happens when the trial ends. See `,_jsx(_components.a,{href:`/payments/subscriptions#free-trials`,children:`Free trials`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`the-access-check-reads-the-subscription`,children:`The access check reads the subscription`}),`\n`,_jsxs(_components.p,{children:[`Before the Pro page, `,_jsx(_components.code,{children:`requirePro`}),` reads the user’s subscription by the stored ID and allows `,_jsx(_components.code,{children:`active`}),` or `,_jsx(_components.code,{children:`trialing`}),`. `,_jsx(_components.code,{children:`subscriptions.list()`}),` does not return your `,_jsx(_components.code,{children:`metadata`}),`, so the stored ID is the lookup key.`]}),`\n`,_jsx(CodeBlock,{filename:`src/access.ts`,numberOfLines:`13`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`13`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` findSubscription`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Promise`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Subscription`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tfor`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` offset`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`; ; `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`offset`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 100`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` page`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`list`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`limit:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 100`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`offset`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\t\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` found`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` page`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`items`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`find`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`s`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` s`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`found`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` found`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`page`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`hasMore`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` isPro`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`subscription`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Subscription`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` boolean`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\treturn`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` subscription`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`?.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'active'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ||`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` subscription`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`?.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'trialing'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The home page reads the same subscription for its plan card:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`currentPeriodEnd`}),`: the end of the current period and the date of the next charge.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`cancelAtPeriodEnd`}),`: `,_jsx(_components.code,{children:`true`}),` after the user cancels. Access ends at `,_jsx(_components.code,{children:`effectiveCancelDate`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`planName`}),` and `,_jsx(_components.code,{children:`unitAmountMinor`}),`: the plan and the charge per period in integer minor units, tax included. For the €29.00 plan, the demo run returned `,_jsx(_components.code,{children:`3596`}),` (€35.96).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`pendingPlanChange`}),`: set when a downgrade waits for the period end.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`the-user’s-invoices-with-pdf-and-receipt`,children:`The user’s invoices, with PDF and receipt`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`subscriptions.invoices(id)`}),` returns the invoice of each billing cycle of one subscription, newest first. Its `,_jsx(_components.code,{children:`amount`}),` is in currency units, not minor units: `,_jsx(_components.code,{children:`60.76`}),` for Grace’s first payment. The invoice list has no filter by buyer, so the subscription ID is the key here too.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`invoices.downloadPdf(id)`}),` and `,_jsx(_components.code,{children:`invoices.getReceipt(id)`}),` return the PDF as a `,_jsx(_components.code,{children:`Buffer`}),`, not a URL. The demo’s server checks that the invoice belongs to the user’s subscription, then sends the bytes. An invoice ID from another user gets a `,_jsx(_components.code,{children:`404`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:`src/invoices.ts`,numberOfLines:`22`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`22`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` userInvoices`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` User`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Promise`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`SubscriptionInvoice`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[]> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\treturn`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`invoices`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptionId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` downloadInvoice`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Request`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Promise`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`void`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` user`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` User`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`locals`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`params`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` kind`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`path`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`endsWith`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'/receipt'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`?`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'receipt'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` :`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'invoice'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` invoice`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`await`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` userInvoices`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`find`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`((`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`i`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` i`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`invoice`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`status`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`404`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'Not found'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\t\treturn`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` pdf`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tkind`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'receipt'`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t\t?`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`invoices`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getReceipt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\t\t\t:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`invoices`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`downloadPdf`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'application/pdf'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`attachment`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`\"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`kind`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`-`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`invoice`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`invoiceNumber`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\".pdf`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pdf`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`A subscription in its free trial has no invoice yet. The first one comes with the first charge, when the trial ends. In test mode the PDF is marked “TEST MODE: not a tax invoice” and its number starts with `,_jsx(_components.code,{children:`TEST-`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`cancel-and-upgrade`,children:`Cancel and upgrade`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Cancel plan`}),` calls `,_jsx(_components.code,{children:`subscriptions.cancel`}),`. The subscription ends at the end of the current period, nothing is refunded, and the user keeps Pro until then. The server rejects an immediate cancellation.`]}),`\n`,_jsx(CodeBlock,{filename:`src/plan.ts`,numberOfLines:`4`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` cancel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`_req`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Request`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Promise`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`void`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tawait`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`cancel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`subscriptionOf`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`));`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`redirect`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`303`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'/'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Frame,{children:_jsx(OptimizedImage,{src:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=57ef227f7395ccf52613c7d814016a3c`,alt:`The Notes demo for Grace after Cancel plan: Pro Plus, active, Pro ends on Oct 29, 2026. You keep it until then. Manage plan: Cancellation scheduled.`,\"data-og-width\":`1440`,width:`1440`,\"data-og-height\":`900`,height:`900`,\"data-path\":`images/paywall/demo-cancelled.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?w=280\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=00e3d3a925a2c85ee34a81d05cf29c87 280w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?w=560\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=28b9a57dfb3fee42203461054bc9b774 560w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?w=840\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=90f7c8028a7db47bc5b62b6985661347 840w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?w=1100\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=ea6ae99d5657c65976e2c679a7b79d70 1100w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?w=1650\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=779c05a605c328b606fc71f51f38e105 1650w, https://mintcdn.com/agentokratia/ob7A8SZLgGb2oPrT/images/paywall/demo-cancelled.png?w=2500\u0026fit=max\u0026auto=format\u0026n=ob7A8SZLgGb2oPrT\u0026q=85\u0026s=7ac9c89da529d779bfad94d49f2f9519 2500w`})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Upgrade to Pro Plus`}),` quotes the change with `,_jsx(_components.code,{children:`previewPlanChange`}),` and shows the amounts. `,_jsx(_components.strong,{children:`Confirm upgrade`}),` applies it with the quote’s `,_jsx(_components.code,{children:`prorationDate`}),`, so the charge equals the quote.`]}),`\n`,_jsx(CodeBlock,{filename:`src/plan.ts`,numberOfLines:`5`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tconst`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` quote`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`previewPlanChange`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\t\tsubscriptionOf`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tconfig`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`proPlusLinkId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t);`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tres`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`quotePage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`locals`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`quote`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`));`})]}),`\n`]})})}),`\n`,_jsx(CodeBlock,{filename:`src/plan.ts`,numberOfLines:`5`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`\tawait`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` agentaos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`changePlan`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`subscriptionOf`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\ttargetLinkId:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` config`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`proPlusLinkId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`\t\t// The quote's prorationDate makes the charge equal the amount the user saw.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tprorationDate:`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Number`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`body`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`prorationDate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t});`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The quote’s `,_jsx(_components.code,{children:`direction`}),` is `,_jsx(_components.code,{children:`upgrade`}),`, `,_jsx(_components.code,{children:`downgrade`}),`, or `,_jsx(_components.code,{children:`revert`}),`. An upgrade charges the prorated difference now and applies at once. A downgrade charges nothing and starts at the end of the period. A revert cancels a pending downgrade. During a free trial, the upgrade quote is €0.00 due today. See `,_jsx(_components.a,{href:`/payments/subscriptions#upgrade-and-downgrade`,children:`Upgrade and downgrade`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`take-it-to-production`,children:`Take it to production`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Login`}),`: replace the demo’s cookie login in `,_jsx(_components.code,{children:`src/session.ts`}),` with your own authentication.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Database`}),`: replace the JSON file in `,_jsx(_components.code,{children:`src/store.ts`}),` with tables. Put a unique constraint on the processed session ID.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Webhook`}),`: register `,_jsx(_components.code,{children:`https://yourapp.com/webhooks`}),` in the dashboard and set its signing secret in `,_jsx(_components.code,{children:`AGENTAOS_WEBHOOK_SECRET`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Live key`}),`: use your live key (`,_jsx(_components.code,{children:`sk_live_...`}),`) on the live server. Keep it out of the browser and out of git.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Test and live`}),`: every event carries `,_jsx(_components.code,{children:`livemode`}),`. Ignore events with `,_jsx(_components.code,{children:`livemode: false`}),` on the live server.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Address`}),`: set `,_jsx(_components.code,{children:`APP_URL`}),` to your public `,_jsx(_components.code,{children:`https`}),` address, and remove `,_jsx(_components.code,{children:`TLS_CERT`}),` and `,_jsx(_components.code,{children:`TLS_KEY`}),` when a proxy handles TLS in front of the app.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`To keep the user on your site, you can embed the checkout instead of redirecting: create the checkout on your server as above and pass its `,_jsx(_components.code,{children:`sessionId`}),` to the `,_jsx(_components.a,{href:`/payments/embedded-checkout`,children:`embedded checkout`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`next-steps`,children:`Next steps`}),`\n`,_jsxs(Columns,{cols:2,children:[_jsx(Card,{title:`Receive webhooks in Express`,icon:`bell`,href:`/sdk/handle-webhooks`,children:_jsx(_components.p,{children:`Register the endpoint and verify every event.`})}),_jsx(Card,{title:`Webhook events`,icon:`list`,href:`/webhooks/events`,children:_jsx(_components.p,{children:`Every event and its fields.`})}),_jsx(Card,{title:`Subscriptions`,icon:`rotate`,href:`/payments/subscriptions`,children:_jsx(_components.p,{children:`Statuses, trials, plan changes, and cancellation.`})}),_jsx(Card,{title:`Go live`,icon:`rocket`,href:`/guides/go-live`,children:_jsx(_components.p,{children:`Verify your business and take real payments.`})})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"Paywall for logged-in users","description":"A runnable demo app that puts a Pro plan behind a login: checkout with the user's ID, a success page and a webhook that unlock Pro, an access check, the user's invoices with PDFs, and cancel and upgrade.","icon":"lock","href":"/sdk/paywall-for-logged-in-users"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"The demo app","slug":"the-demo-app","depth":2,"children":[]},{"title":"Run it","slug":"run-it","depth":2,"children":[]},{"title":"How it works","slug":"how-it-works","depth":2,"children":[{"title":"The checkout carries your user ID","slug":"the-checkout-carries-your-user-id","depth":3,"children":[]},{"title":"The success page asks the API","slug":"the-success-page-asks-the-api","depth":3,"children":[]},{"title":"The webhook unlocks Pro and matches renewals","slug":"the-webhook-unlocks-pro-and-matches-renewals","depth":3,"children":[]},{"title":"Each payment unlocks once","slug":"each-payment-unlocks-once","depth":3,"children":[]},{"title":"Free trials","slug":"free-trials","depth":3,"children":[]},{"title":"The access check reads the subscription","slug":"the-access-check-reads-the-subscription","depth":3,"children":[]},{"title":"The user’s invoices, with PDF and receipt","slug":"the-user’s-invoices-with-pdf-and-receipt","depth":3,"children":[]},{"title":"Cancel and upgrade","slug":"cancel-and-upgrade","depth":3,"children":[]}]},{"title":"Take it to production","slug":"take-it-to-production","depth":2,"children":[]},{"title":"Next steps","slug":"next-steps","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"agentokratia","siteName":"AgentaOS","title":"Paywall for logged-in users - AgentaOS","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-29T09:01:01.015Z","originalFileLocation":"sdk/paywall-for-logged-in-users.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"A runnable demo app that puts a Pro plan behind a login: checkout with the user\u0026#x27;s ID, a success page and a webhook that unlock Pro, an access check, the user\u0026#x27;s invoices with PDFs, and cancel and upgrade.\">\u003cmeta data-mint-head name=\"application-name\" content=\"AgentaOS\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Paywall for logged-in users - AgentaOS\">\u003cmeta data-mint-head property=\"og:description\" content=\"A runnable demo app that puts a Pro plan behind a login: checkout with the user\u0026#x27;s ID, a success page and a webhook that unlock Pro, an access check, the user\u0026#x27;s invoices with PDFs, and cancel and upgrade.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"AgentaOS\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://agentokratia.mintlify.site/_mintlify/api/og/v2?division=Recipes\u0026amp;title=Paywall+for+logged-in+users\u0026amp;description=A+runnable+demo+app+that+puts+a+Pro+plan+behind+a+login%3A+checkout+with+the+user%27s+ID%2C+a+success+page+and+a+webhook+that+unlock+Pro%2C+an+access+check%2C+the+user%27s+\u0026amp;theme=9d817a47a5af2aca8bd1b3f5\u0026amp;signature=4fc5fbf43bf252028b2a22f689ae802526c8009d25d31a99a9ad16a8ebbabe58\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Paywall for logged-in users - AgentaOS\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"A runnable demo app that puts a Pro plan behind a login: checkout with the user\u0026#x27;s ID, a success page and a webhook that unlock Pro, an access check, the user\u0026#x27;s invoices with PDFs, and cancel and upgrade.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://agentokratia.mintlify.site/_mintlify/api/og/v2?division=Recipes\u0026amp;title=Paywall+for+logged-in+users\u0026amp;description=A+runnable+demo+app+that+puts+a+Pro+plan+behind+a+login%3A+checkout+with+the+user%27s+ID%2C+a+success+page+and+a+webhook+that+unlock+Pro%2C+an+access+check%2C+the+user%27s+\u0026amp;theme=9d817a47a5af2aca8bd1b3f5\u0026amp;signature=4fc5fbf43bf252028b2a22f689ae802526c8009d25d31a99a9ad16a8ebbabe58\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/agentokratia/-rZsiBgtr8J9o65Q/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"AgentaOS\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#4F46E5\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/sdk/paywall-for-logged-in-users.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.agentaos.ai/#organization\",\"name\":\"AgentaOS\",\"url\":\"https://docs.agentaos.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/agentokratia/m99r4jmD11JEgdx5/images/agentaos-icon.png?fit=max\u0026auto=format\u0026n=m99r4jmD11JEgdx5\u0026q=85\u0026s=0b6178b7724b65d6c92a4e09b7f7f577\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.agentaos.ai#website\",\"name\":\"AgentaOS\",\"url\":\"https://docs.agentaos.ai\",\"publisher\":{\"@id\":\"https://docs.agentaos.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users#webpage\",\"url\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users\",\"name\":\"Paywall for logged-in users\",\"description\":\"A runnable demo app that puts a Pro plan behind a login: checkout with the user's ID, a success page and a webhook that unlock Pro, an access check, the user's invoices with PDFs, and cancel and upgrade.\",\"dateModified\":\"2026-09-29T09:01:01.015Z\",\"isPartOf\":{\"@id\":\"https://docs.agentaos.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"SDK\",\"item\":\"https://docs.agentaos.ai/sdk/pay-overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Paywall for logged-in users\",\"item\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users#article\",\"headline\":\"Paywall for logged-in users\",\"name\":\"Paywall for logged-in users\",\"description\":\"A runnable demo app that puts a Pro plan behind a login: checkout with the user's ID, a success page and a webhook that unlock Pro, an access check, the user's invoices with PDFs, and cancel and upgrade.\",\"url\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users\",\"mainEntityOfPage\":{\"@id\":\"https://docs.agentaos.ai/sdk/paywall-for-logged-in-users#webpage\"},\"dateModified\":\"2026-09-29T09:01:01.015Z\",\"publisher\":{\"@id\":\"https://docs.agentaos.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.agentaos.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"AgentaOS\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"AgentaOS\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/sdk/paywall-for-logged-in-users.md","siteName":"AgentaOS","nav":{"global":{"anchors":[{"anchor":"llms.txt","icon":"file-lines","href":"/llms-full.txt"},{"anchor":"Support","icon":"life-ring","href":"mailto:contact@agentaos.ai"}]},"tabs":[{"tab":"Documentation","icon":"book-open","pages":[{"title":"Documentation","href":"/introduction"}]},{"tab":"Guides","icon":"map","pages":[{"title":"Guides","href":"/guides/introduction"}]},{"tab":"Reference","icon":"code","groups":[{"group":"SDK","icon":"cube","pages":[{"title":"Overview","icon":"cube","href":"/sdk/pay-overview"},{"title":"Checkouts","icon":"cart-shopping","href":"/sdk/pay-checkouts"},{"title":"Payment links","icon":"link","href":"/sdk/pay-payment-links"},{"title":"Subscriptions","icon":"rotate","href":"/sdk/pay-subscriptions"},{"title":"Invoices","icon":"file-invoice","href":"/sdk/pay-invoices"},{"title":"Customers","icon":"users","href":"/sdk/pay-customers"},{"title":"Businesses","icon":"building","href":"/sdk/pay-businesses"},{"title":"Webhooks","icon":"bell","href":"/sdk/pay-webhooks"},{"title":"Errors","description":"The AgentaOSError hierarchy, what triggers each subclass, and exactly how retries and timeouts work.","icon":"triangle-exclamation","href":"/sdk/pay-errors"},{"group":"Recipes","pages":[{"title":"Paywall for logged-in users","icon":"lock","href":"/sdk/paywall-for-logged-in-users"},{"title":"Receive webhooks in Express","description":"Register a webhook URL, verify the signature, and fulfill an order when checkout.session.completed fires. A complete, runnable Express example.","icon":"code-branch","href":"/sdk/handle-webhooks"},{"title":"Better Auth plugin","icon":"key","href":"/sdk/better-auth"},{"title":"Next.js route handlers","icon":"route","href":"/sdk/nextjs"}]}]},{"group":"CLI","icon":"terminal","pages":[{"title":"Install","icon":"download","href":"/cli/install"},{"title":"Login","icon":"right-to-bracket","href":"/cli/login"},{"title":"Verify","icon":"id-card","href":"/cli/verify"},{"title":"agenta products","icon":"box","href":"/cli/products"},{"title":"Pay","icon":"credit-card","href":"/cli/pay"},{"title":"Subscriptions","icon":"rotate","href":"/cli/subscriptions"},{"title":"Discounts","icon":"ticket","href":"/cli/discounts"},{"title":"Customers","icon":"users","href":"/cli/customers"},{"title":"Invoices","icon":"file-invoice","href":"/cli/invoices"},{"title":"Businesses","icon":"building","href":"/cli/businesses"},{"title":"Status","icon":"signal","href":"/cli/status"}]},{"group":"API Reference","icon":"server","pages":[{"title":"Introduction","icon":"book-open","href":"/api-reference/introduction"},{"title":"Error codes","icon":"triangle-exclamation","href":"/api-reference/error-codes"},{"group":"Payment links","expanded":false,"pages":[{"title":"Create a payment link","openapi":"POST /gateway/payment-links","href":"/api-reference/payment-links/create"},{"title":"List payment links","openapi":"GET /gateway/payment-links","href":"/api-reference/payment-links/list"},{"title":"Retrieve a payment link","openapi":"GET /gateway/payment-links/{id}","href":"/api-reference/payment-links/retrieve"},{"title":"Update a payment link","openapi":"PATCH /gateway/payment-links/{id}","href":"/api-reference/payment-links/update"},{"title":"Cancel a payment link","openapi":"DELETE /gateway/payment-links/{id}","href":"/api-reference/payment-links/cancel"},{"title":"Activate a payment link","openapi":"POST /gateway/payment-links/{id}/activate","href":"/api-reference/payment-links/activate"}]},{"group":"Checkouts","expanded":false,"pages":[{"title":"Create a checkout","openapi":"POST /gateway/sessions","href":"/api-reference/checkouts/create"},{"title":"List checkouts","openapi":"GET /gateway/sessions","href":"/api-reference/checkouts/list"},{"title":"Retrieve a checkout","openapi":"GET /gateway/sessions/{sessionId}","href":"/api-reference/checkouts/retrieve"},{"title":"Cancel a checkout","openapi":"POST /gateway/sessions/{sessionId}/cancel","href":"/api-reference/checkouts/cancel"}]},{"group":"Subscriptions","expanded":false,"pages":[{"title":"List subscriptions","openapi":"GET /gateway/subscriptions","href":"/api-reference/subscriptions/list"},{"title":"Preview a plan change","openapi":"GET /gateway/subscriptions/{id}/plan-change/preview","href":"/api-reference/subscriptions/plan-change-preview"},{"title":"Change the plan","openapi":"POST /gateway/subscriptions/{id}/plan-change","href":"/api-reference/subscriptions/plan-change"},{"title":"Cancel a subscription","openapi":"POST /gateway/subscriptions/{id}/cancel","href":"/api-reference/subscriptions/cancel"},{"title":"List a subscription's invoices","openapi":"GET /gateway/subscriptions/{id}/invoices","href":"/api-reference/subscriptions/invoices"},{"title":"List credits given to a subscriber","openapi":"GET /gateway/subscriptions/{id}/credits","href":"/api-reference/subscriptions/credits-list"},{"title":"Give a subscriber credit","openapi":"POST /gateway/subscriptions/{id}/credits","href":"/api-reference/subscriptions/credits-create"},{"title":"Resume a subscription","openapi":"POST /gateway/subscriptions/{id}/resume","href":"/api-reference/subscriptions/resume"}]},{"group":"Discount codes","expanded":false,"pages":[{"title":"Create a discount code","openapi":"POST /gateway/discount-codes","href":"/api-reference/discount-codes/create"},{"title":"List discount codes","openapi":"GET /gateway/discount-codes","href":"/api-reference/discount-codes/list"},{"title":"Retrieve a discount code","openapi":"GET /gateway/discount-codes/{id}","href":"/api-reference/discount-codes/retrieve"},{"title":"Stop a discount code","openapi":"POST /gateway/discount-codes/{id}/archive","href":"/api-reference/discount-codes/archive"}]},{"group":"Customers","expanded":false,"pages":[{"title":"List customers","openapi":"GET /gateway/customers","href":"/api-reference/customers/list"}]},{"group":"Invoices","expanded":false,"pages":[{"title":"List invoices","openapi":"GET /gateway/invoices","href":"/api-reference/invoices/list"},{"title":"Retrieve an invoice","openapi":"GET /gateway/invoices/{invoiceId}","href":"/api-reference/invoices/retrieve"},{"title":"Void an invoice","openapi":"POST /gateway/invoices/{invoiceId}/void","href":"/api-reference/invoices/void"},{"title":"Download the invoice PDF","openapi":"GET /gateway/invoices/{invoiceId}/pdf","href":"/api-reference/invoices/pdf"},{"title":"Download the receipt PDF","openapi":"GET /gateway/invoices/{invoiceId}/receipt","href":"/api-reference/invoices/receipt"},{"title":"Re-send the receipt email","openapi":"POST /gateway/invoices/{invoiceId}/send-receipt","href":"/api-reference/invoices/send-receipt"},{"title":"Download a statement","openapi":"GET /gateway/invoices/statement","href":"/api-reference/invoices/statement"},{"title":"Export invoices as CSV","openapi":"GET /gateway/invoices/export","href":"/api-reference/invoices/export"}]},{"group":"Transactions","expanded":false,"pages":[{"title":"List transactions","openapi":"GET /gateway/all-transactions","href":"/api-reference/transactions/list"},{"title":"Ask for a refund","openapi":"POST /gateway/transactions/{id}/refund-request","href":"/api-reference/transactions/refund-request"}]},{"group":"Businesses","expanded":false,"pages":[{"title":"List businesses","openapi":"GET /gateway/businesses","href":"/api-reference/businesses/list"},{"title":"Create a business","openapi":"POST /gateway/businesses","href":"/api-reference/businesses/create"},{"title":"Retrieve a business","openapi":"GET /gateway/businesses/{id}","href":"/api-reference/businesses/retrieve"},{"title":"Resend the invitation","openapi":"POST /gateway/businesses/{id}/invitation","href":"/api-reference/businesses/resend-invitation"},{"title":"Revoke the invitation","openapi":"DELETE /gateway/businesses/{id}/invitation","href":"/api-reference/businesses/revoke-invitation"},{"title":"Create a verification link","openapi":"POST /gateway/businesses/{id}/verification-link","href":"/api-reference/businesses/verification-link"}]},{"group":"Bank Accounts","expanded":false,"pages":[{"title":"Get the fields a currency needs","openapi":"GET /gateway/bank-accounts/requirements","href":"/api-reference/bank-accounts/requirements"},{"title":"Refresh the fields after an answer","openapi":"POST /gateway/bank-accounts/requirements/refresh","href":"/api-reference/bank-accounts/refresh-requirements"},{"title":"Add a bank account","openapi":"POST /gateway/bank-accounts","href":"/api-reference/bank-accounts/create"},{"title":"List bank accounts","openapi":"GET /gateway/bank-accounts","href":"/api-reference/bank-accounts/list"},{"title":"Retire a bank account","openapi":"DELETE /gateway/bank-accounts/{id}","href":"/api-reference/bank-accounts/deactivate"}]},{"group":"Approved sites","pages":[{"title":"Set the approved sites","openapi":"PATCH /orgs/{id}/embed-domains","href":"/api-reference/approved-sites/update"}]},{"group":"Payouts","pages":[{"title":"List payouts","openapi":"GET /gateway/mor-settlements","href":"/api-reference/payouts/list"},{"title":"Download the payout statement","openapi":"GET /gateway/mor-settlements/{id}/payout-statement.pdf","href":"/api-reference/payouts/statement"},{"title":"Download the self-billed invoice","openapi":"GET /gateway/mor-settlements/{id}/self-billed-invoice.pdf","href":"/api-reference/payouts/self-billed-invoice"}]},{"title":"Webhooks","icon":"bell","href":"/api-reference/webhooks"}]}]},{"tab":"Changelog","icon":"clock-rotate-left","pages":[{"title":"Changelog","href":"/changelog/overview"}]}]},"basePath":"","title":"Paywall for logged-in users - AgentaOS","buildId":"dpl_8hoxaqFTU7hTr6A2fUraxAyjuiZo","deploymentId":"dpl_8hoxaqFTU7hTr6A2fUraxAyjuiZo","dynamics":["10e4515597","07c022d89b","a74be98ba7"],"chunks":["BannerMarkdown-D7Q3g8OM.js","dist-BvrGG8gU.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-B35qUV0p.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","Frame-Dmj010Ph.js","DynamicMarkdown-GHvayGOn.js","zoom-image-lightbox-8gCTkA22.js","lightbox-handle-r17bVUz3.js"]}