Guide
This guide builds on the SDK quickstart and shows you how to model, manage, and experiment on your pricing using Hypertune.
You'll learn how to:
Create custom object types to model your pricing
Create flags that use those custom object types
Access those flags in your code
Update your pricing
Run experiments on your pricing
Prerequisites
Create custom object types to model your pricing
Go to the Schema view in the dashboard. Click the + button in the top-right of the sidebar. Select Object, enter a name, and click Create.

By default, the new object type has no fields.
Click + Add to add a new field. Enter a name, select List from the Type dropdown, then select New object type from the Item type dropdown.

Enter a name for the new type and click Create.

Repeat for each field you want to add. You can switch to the code view to make this easier. Then, click Save.

type Pricing {
stripePrices(plan: Plan!): [StripePrice!]!
planContent(plan: Plan!): PlanContent!
planFeatures: [PlanFeature!]!
planOrdering: [Plan!]!
}
enum Plan { free, pro, enterprise }
type StripePrice {
id: String!
type: StripePriceType!
}
enum StripePriceType { flatFee, perSeat }
type PlanContent {
name: String!
description: String!
features: [String!]!
}
type PlanFeature {
name: String!
value(plan: Plan!): PlanFeatureValue!
}
type PlanFeatureValue {
isIncluded: Boolean!
text: String!
}Create flags for your pricing
Go to the Flags view in the dashboard. Click the + button in the top-right of the sidebar and select Flag.

Enter a name, set its type to the one you created earlier, and click Create.

Select the nested flag for the Stripe Prices, open the options (⋯) menu on the List, and select Insert enum switch.

Set the switch Control to the Plan argument.

You'll see a nested sidebar item for each plan. Add the Stripe Prices for each plan. These will be added as line items when creating a Stripe checkout session.

Insert an enum switch on the Plan Content flag, and add content for each plan. This will be used to render the plans table that lets your users compare each plan.

Select the Plan Features list flag. This will be used to render the detailed features table under the plans table.
Add a Plan Feature, enter a name for it, then select Insert enum switch on the value field.

This lets you return different values for each plan.

Repeat for all the features you want to show in your features table.
Finally, select the Plan Ordering flag, set the order that plans should appear in the plans table and features table, and click Save.

Access flags to retrieve pricing
Regenerate the client:
npx hypertuneyarn hypertunepnpm hypertuneThen use the generated methods for your flags to get the pricing configuration when creating Stripe checkout sessions and rendering pricing components:
import { waitUntil } from '@vercel/functions'
import { NextResponse } from 'next/server'
import getHypertune from '@/lib/getHypertune'
import getStripe from '@/lib/getStripe'
import getTeamSize from '@/lib/getTeamSize'
export const runtime = 'nodejs'
export async function GET(request: Request) {
const hypertune = await getHypertune({ isRouteHandler: true })
const stripePrices = hypertune
.pricing()
.stripePrices({ args: { plan: 'pro' } })
.map((price) => price.get())
const teamSize = getTeamSize()
const lineItems = stripePrices.map((price) => ({
price: price.id,
quantity: price.type === 'perSeat' ? teamSize : 1,
}))
const stripe = getStripe()
const baseUrl = new URL(request.url).origin
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: lineItems,
success_url: `${baseUrl}/success`,
cancel_url: `${baseUrl}/cancel`,
})
waitUntil(hypertune.flushLogs())
return NextResponse.json({
sessionUrl: session.url,
sessionId: session.id,
})
}import FeaturesTable from './FeaturesTable'
import PlansTable from './PlansTable'
import getHypertune from '@/lib/getHypertune'
export default async function Pricing() {
const hypertune = await getHypertune()
const pricing = hypertune.pricing()
return (
<div className="pricing">
<h2>Pricing</h2>
<PlansTable pricing={pricing} />
<FeaturesTable pricing={pricing} />
</div>
)
}import {
type PricingNode,
type PlanContentNode,
} from '@/generated/hypertune'
export default function PlansTable({
pricing,
}: {
pricing: PricingNode
}) {
const planOrdering = pricing.planOrdering({
itemFallback: 'free',
})
return (
<div className="plans-table">
{planOrdering.map((plan) => {
const planContent = pricing.planContent({
args: { plan },
})
return (
<PlanColumn key={plan} planContent={planContent} />
)
})}
</div>
)
}
function PlanColumn({
planContent,
}: {
planContent: PlanContentNode
}) {
const content = planContent.get()
return (
<div className="plan-column">
<h3>{content.name}</h3>
<p>{content.description}</p>
<ul>
{content.features.map((feature) => (
<li key={feature}>{feature}</li>
))}
</ul>
</div>
)
}import { type PricingNode } from '@/generated/hypertune'
export default function FeaturesTable({
pricing,
}: {
pricing: PricingNode
}) {
const planOrdering = pricing.planOrdering({
itemFallback: 'free',
})
const planFeatures = pricing.planFeatures()
return (
<table className="features-table">
<thead>
<tr>
<th>Feature</th>
{planOrdering.map((plan) => (
<th key={plan}>{plan}</th>
))}
</tr>
</thead>
<tbody>
{planFeatures.map((feature) => {
const featureName = feature.name({
args: {},
fallback: '',
})
return (
<tr key={featureName}>
<td>{featureName}</td>
{planOrdering.map((plan) => {
const value = feature
.value({ args: { plan } })
.get()
return (
<td key={plan}>
{value.text ? (
<span className="text">{value.text}</span>
) : value.isIncluded ? (
<span className="tick">✓</span>
) : (
<span className="cross">✗</span>
)}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
)
}Update your pricing configuration
Go to the Flags view in the dashboard, expand the top-level flag with your pricing configuration in the left sidebar, and select the nested flag that you want to configure.

Make your changes, then open the Diff view to review them. Click Save.

Add a new plan
Go to the Schema view in the dashboard, select the Plan enum, and add a value for the new plan.

Go to the Flags view, and enter the configuration for the new plan across each of your nested flags for the Stripe Prices, Plan Content, Plan Features, and Plan Ordering.

A/B test a new plan
To measure the impact of the new plan on conversion and revenue, select the Plan Ordering flag.

Click + Experiment, select New experiment from the dropdown, enter a name for it, click Create, then click Insert.
In the Test Variant, replace the old plan enum value with the new one you created earlier.

Next steps
Build an impact analysis or funnel to view the performance of each experiment variant.
Experiment on your plan content and plan features.
Last updated