SaaS signup pages on Next.js
A product team sells a paid plan from a pricing route and passes the signed-in user's JWT so checkout knows the account. HubSpot gets the contact, and sales sees the plan as a property.

Checkout embed
A Next.js client component opens the Plandalf checkout, and a paid order reaches HubSpot as a contact through a webhook step.
No credit card required. No coding required.
Next.js
HubSpotPlandalf has no native HubSpot steps, and the Next.js SDK does not write to HubSpot. Your app opens the checkout; after payment a Plandalf sequence uses Send Webhook to post the buyer to HubSpot's contacts API or to a route handler you own. HubSpot workflows can also post to a Plandalf catch URL.
| Event | From and to | Through | What happens |
|---|---|---|---|
| Checkout opened | Next.js → Plandalf | A client component renders a button with data-plandalf-present, or calls present() from the SDK once the provider reports it is ready. | |
| Checkout completed | Plandalf → HubSpot | Webhook | Send Webhook posts JSON to HubSpot's contacts API with a private app token as a Bearer header, or to a Next.js route handler that holds the token. |
| Invoice paid | Plandalf → Next.js | Webhook | A Send Webhook step can also call a route handler in your app, which is where durable access is granted after you verify the paid invoice on the server. |
| Workflow webhook | HubSpot → Plandalf | Webhook | A HubSpot workflow action that sends a webhook can call a Plandalf Webhook Trigger URL, which then runs Enroll in Promo for that contact. |
| Countdown in a marketing email | Plandalf → HubSpot | By hand | An image tag in an HTML module uses HubSpot's contact email token in the ref value, so each contact has their own deadline. |
This assumes the App Router, a client provider that loads the Plandalf script, and a HubSpot private app.
Create a client component with 'use client' that renders next/script with the afterInteractive strategy and wraps your layout's children. Next.js only allows onReady and onError handlers inside client components.
Show a button with data-plandalf-present only once plandalf('ready', ...) has handed your provider the SDK. Give the button a React key that includes the offer slug, so a changed offer replaces the bound element.
In HubSpot create a private app, choose the contact write scope and copy the access token. HubSpot uses it as a Bearer token. Store it as a server environment variable, never a public one.
Create app/api/plandalf-paid/route.js that checks a shared secret header, reads the email and invoice number from the body, and upserts the contact in HubSpot. Skip repeated invoice numbers so a retry does not run twice.
In Automation, My Sequences start on Checkout Completed for your offer, then add Send Webhook with your route URL, the secret in Headers and a JSON payload using {{trigger.customer_email}} and {{trigger.invoice_number}}. Test it with your own email.
A product team sells a paid plan from a pricing route and passes the signed-in user's JWT so checkout knows the account. HubSpot gets the contact, and sales sees the plan as a property.
A creator app grants the dashboard from the route handler after verifying the invoice, and the same handler writes the buyer to HubSpot for follow-up.
purchase and complete events are for UI updates, not authorisation. Grant access from your server after verifying the paid purchase.Checked October 26, 2026 against Plandalf's own setup guides and the vendor documentation: HubSpot CRM API: contacts, HubSpot private apps overview, HubSpot: use webhooks with workflows, Next.js: load and optimize scripts.