Pricing Table Fresh
An embeddable UI component that displays subscription pricing and takes customers directly to Stripe Checkout.
What it does
- Displays pricing for up to 4 products per pricing interval
- Supports flat-rate, per-seat, tiered pricing, and free trials
- Customers click through to Stripe-hosted Checkout to subscribe
- Manage products, pricing, and appearance entirely from the Dashboard — no code changes needed
Create a pricing table
- Dashboard → Product catalog → Pricing tables → Create pricing table
- Add products (up to 4 per interval). Optionally include a free trial
- Adjust look and feel in Display settings (colors, font, button design, highlight a product)
- Configure Payment settings (info to collect, confirmation page or redirect URL)
- Set up the customer portal
- Click Copy code — paste the snippet into your website
Embed the pricing table
html
<body>
<h1>Choose your plan</h1>
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
<stripe-pricing-table
pricing-table-id="prctbl_YOUR_ID"
publishable-key="pk_live_YOUR_KEY"
>
</stripe-pricing-table>
</body>Uses your publishable API key. If you revoke the key, update the embed code.
Pass an existing customer
Generate a customer session server-side and pass the client_secret to the component:
bash
curl https://api.stripe.com/v1/customer_sessions \
-u "sk_test_YOUR_KEY:" \
-d "customer=cus_123" \
-d "components[pricing_table][enabled]=true"html
<stripe-pricing-table
pricing-table-id="prctbl_YOUR_ID"
publishable-key="pk_live_YOUR_KEY"
customer-session-client-secret="{{CLIENT_SECRET}}"
>
</stripe-pricing-table>Customer sessions expire after 30 minutes. If expired before Checkout Session creation, no customer is associated.
Pass customer email
html
<stripe-pricing-table
pricing-table-id="prctbl_YOUR_ID"
publishable-key="pk_live_YOUR_KEY"
customer-email="user@example.com"
>
</stripe-pricing-table>Pre-fills the email on the Checkout page.
Track purchases with client-reference-id
html
<stripe-pricing-table
pricing-table-id="prctbl_YOUR_ID"
publishable-key="pk_live_YOUR_KEY"
client-reference-id="user_abc123"
>
</stripe-pricing-table>The client_reference_id is passed to the Checkout Session. Max 200 characters, alphanumeric + dashes + underscores. Don't include sensitive data.
Handle fulfillment
The pricing table uses Checkout — listen for checkout.session.completed:
javascript
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const event = stripe.webhooks.constructEvent(req.body, req.headers['stripe-signature'], endpointSecret);
if (event.type === 'checkout.session.completed') {
// Provision access for new subscriber
}
res.send();
});Optional customizations
Add product marketing features
bash
curl https://api.stripe.com/v1/products \
-u "sk_test_YOUR_KEY:" \
-d name=Professional \
-d "marketing_features[0][name]=Unlimited boards" \
-d "marketing_features[1][name]=Up to 20 seats"Custom call-to-action
One product can have a custom CTA that redirects to any URL (useful for enterprise/custom pricing). Supports {PRODUCT_ID} and {CUSTOMER_EMAIL} variables.
Custom fields
Collect additional info at checkout (text, numbers, dropdown). Available in the checkout.session.completed event.
Local currencies
Set customer-email with a +location_XX suffix to preview pricing in a specific country's currency.
Free trials without payment method
Select "Include a free trial" → "Only collect payment method information if required". Set up email reminders to collect payment before trial ends.
Limitations
- Does not support usage-based pricing
- Maximum 4 products, 3 prices per product, 3 unique pricing intervals
- No intermediate step before checkout (can't require account creation first)
- Rate limit: 50 read operations/second (shared across all pricing tables)
- Requires a real domain to render — use localhost HTTP server for local testing
- Not compatible with Connect platform fee collection
Content Security Policy
Add to your CSP if applicable:
frame-src:https://js.stripe.comscript-src:https://js.stripe.com