Add Aforo pricing cards, subscribe buttons, invoice lists, and embedded checkout to any page in under 10 minutes. Three integration tiers: script tag, npm, iframe.
The plugin tier sits between Aforo's headless API (full integration flexibility, you render everything) and the managed storefront (zero integration, we render the whole storefront for you). It gives you Aforo-rendered widgets that drop into your own pages — you keep your design system, your routing, your auth, and we handle the billing surface.
Anonymous pricing
Drop a PricingCard on your marketing page. No signup required.
Authenticated customer flows
Subscribe, view invoices, checkout — all using your customer identity.
Real-time updates
SSE push for invoice paid, subscription state, payment failures.
You need two things before you can render your first widget:
An Aforo account with at least one published offering. Sign up at app.aforo.ai (free sandbox tier available).
An embed key minted from Embed Studio. Open the operator UI, navigate to Customize Storefront → Embed Studio → Keys, click Mint a new embed key, and add the host domain where you'll embed widgets (e.g. https://shop.example.com).
INFO
Embed keys are public identifiers — their security comes from the server-side domain allowlist. A key only works when served from a registered origin. Add staging and production hosts separately to keep them isolated.
The fastest path. No build toolchain required. Works in Webflow, WordPress, Squarespace, and plain HTML pages. The loader is ~2.5 KB gzipped and lazy-fetches per-widget bundles only when their placeholders appear on the page.
pricing.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Pricing — Acme Corp</title>
</head>
<body>
<h1>Choose your plan</h1>
<!-- 1. Drop the loader once per page -->
<script
src="https://embed.aforo.ai/v1/loader.js"
integrity="sha384-…"
crossorigin="anonymous"
async
></script>
<!-- 2. Drop a placeholder wherever you want the widget -->
<div
data-aforo-widget="pricing-card"
data-tenant-slug="acme"
data-embed-key="embk_live_…"
data-layout="horizontal"
></div>
</body>
</html>
That's it. The loader script discovers the placeholder, lazy-fetches widgets/pricing-card.js, calls the headless config endpoint to load your offerings, and renders the card with your tenant's brand colors.
PRO TIP
Get the current SRI hash from embed.aforo.ai/v1/sri.json and paste it into the integrity= attribute. See the for SRI pinning details.
For widgets that need to know which customer the page belongs to (Subscribe, Invoice List, Checkout Flow), mint a bridge token on your backend and pass it as a prop.
app/subscribe/page.tsx
import { AforoSubscribeButton } from '@aforoai/storefront-widgets';
export default async function SubscribePage() {
// mintBridgeToken() lives in your own backend — it returns a short-lived
// signed token identifying the current customer.
const bridgeToken = await mintBridgeToken();
return (
<AforoSubscribeButton
tenantSlug="acme"
embedKey="embk_live_…"
bridgeToken={bridgeToken}
offeringId="off_pro"
mode="redirect"
returnUrl="https://shop.example.com/welcome"
/>
);
}
See the for bridge-token signing code in Node.js, Python, and Go.
Svelte, Solid, Lit and other framework consumers can use the vanilla-JS API via @aforoai/storefront-widgets/vanilla. It exposes the same mount/unmount API the loader uses internally.