Never spend another second building and maintaining pricing in your code
What you thought is going to be a one-off sprint became your day job
Solve complex pricing with entitlements
Entitlements set limits and govern how much value an account gets. They are the building blocks for a truly flexible, lightning-fast pricing & packaging infrastructure.
customerId: user.orgId,
featureId: "feature-active-boards",
options: { requestedUsage: 1 }
});
if (entitlement.hasAccess) {
// allow user to open another board...
// finally, track that a new board was opened
await stigg.reportUsage({ customerId: user.organizationId, featureId:
"feature-active-boards", value: 1 });
}
{
name: "Free",
stripePriceId: "price_...",
maxActiveBoards: 1,
monthlyAutomationsLimit: 0,
},
{
name: "Basic",
stripePriceId: "price_...",
maxActiveBoards: 5,
monthlyAutomationsLimit: 10 // TODO: reset every month, we don't have a way to do this yet
},
{
name: "Premium (New)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 50
},
{
name: "Premium (Legacy)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 25
}
// ...
];
const subscriptions = await stripe.subscriptions.list({ customer: user.stripeCustomerId, status: "active" });
const activeSubscription = subscriptions.data[0];
if (!activeSubscription) {
// todo: customer has no active subscription, should we treat this as free?
}
const planStripePriceId = activeSubscription.items.data[0].price.id;
const plan = PRICING_PLANS.find(plan => plan.stripePriceId === planStripePriceId || plan.stripeYearlyPriceId === planStripePriceId);
if(!plan) {
// todo: customer has an active subscription but we don't know what plan it is ??? maybe some older legacy plan?
}
const org = await Organization.findOne({ id: user.orgId });
const boardsCount = await Board.count({ organizationId: org.id, status: "ACTIVE" });
if (boardsCount < plan.boardsLimit || boardsCount < org.legacyEnterpriseBoardsLimit || org.isVIP) {
// finally allow user to open another board
}
customerId: user.orgId,
featureId: "feature-active-boards",
options: { requestedUsage: 1 }
});
if (entitlement.hasAccess) {
// allow user to open another board...
// finally, track that a new board was opened
await stigg.reportUsage({ customerId: user.organizationId, featureId: "feature-active-boards", value: 1 });
}
{
name: "Free",
stripePriceId: "price_...",
maxActiveBoards: 1,
monthlyAutomationsLimit: 0,
},
{
name: "Basic",
stripePriceId: "price_...",
maxActiveBoards: 5,
monthlyAutomationsLimit: 10 // TODO: reset every month, we don't have a way to do this yet
},
{
name: "Premium (New)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 50
},
{
name: "Premium (Legacy)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 25
}
// ...
];
const subscriptions = await stripe.subscriptions.list({ customer: user.stripeCustomerId, status: "active" });
const activeSubscription = subscriptions.data[0];
if (!activeSubscription) {
// todo: customer has no active subscription, should we treat this as free?
}
const planStripePriceId = activeSubscription.items.data[0].price.id;
const plan = PRICING_PLANS.find(plan => plan.stripePriceId === planStripePriceId || plan.stripeYearlyPriceId === planStripePriceId);
if(!plan) {
// todo: customer has an active subscription but we don't know what plan it is ??? maybe some older legacy plan?
}
const org = await Organization.findOne({ id: user.orgId });
const boardsCount = await Board.count({ organizationId: org.id, status: "ACTIVE" });
if (boardsCount < plan.boardsLimit || boardsCount < org.legacyEnterpriseBoardsLimit || org.isVIP) {
// finally allow user to open another board
}
customer_id=user["orgId"],
feature_id="feature-active-boards",
options={"requested_usage": 1}
)
if entitlement["has_access"]:
# allow user to open another board...
# finally, track that a new board was opened
stigg.report_usage(customer_id=user["organizationId"],
feature_id="feature active-boards", value=1)
{
"name": "Free",
"stripePriceId": "price_...",
"maxActiveBoards": 1,
"monthlyAutomationsLimit": 0,
},
{
"name": "Basic",
"stripePriceId": "price_...",
"maxActiveBoards": 5,
"monthlyAutomationsLimit": 10 # TODO: reset every month, we don't have a way to do this yet
},
{
"name": "Premium (New)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 50
},
{
"name": "Premium (Legacy)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 25
}
# ...
]
subscriptions = stripe.subscriptions.list(customer=user["stripeCustomerId"], status="active")
active_subscription = subscriptions["data"][0]
if not active_subscription:
# todo: customer has no active subscription, should we treat this as free?
pass
plan_stripe_price_id = active_subscription["items"]["data"][0]["price"]["id"]
plan = next((plan for plan in PRICING_PLANS if plan["stripePriceId"] == plan_stripe_price_id or plan["stripeYearlyPriceId"] == plan_stripe_price_id), None)
if not plan:
# todo: customer has an active subscription but we don't know what plan it is ??? maybe some older legacy plan?
pass
org = Organization.find_one(id=user["orgId"])
boards_count = Board.count(organizationId=org["id"], status="ACTIVE")
if boards_count < plan["boardsLimit"] or boards_count < org["legacyEnterpriseBoardsLimit"] or org["isVIP"]:
# finally allow user to open another board
pass
customer_id=user["orgId"],
feature_id="feature-active-boards",
options={"requested_usage": 1}
)
if entitlement["has_access"]:
# allow user to open another board...
# finally, track that a new board was opened
stigg.report_usage(customer_id=user["organizationId"], feature_id="feature active-boards", value=1)
{
"name": "Free",
"stripePriceId": "price_...",
"maxActiveBoards": 1,
"monthlyAutomationsLimit": 0,
},
{
"name": "Basic",
"stripePriceId": "price_...",
"maxActiveBoards": 5,
"monthlyAutomationsLimit": 10 # TODO: reset every month, we don't have a way to do this yet
},
{
"name": "Premium (New)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 50
},
{
"name": "Premium (Legacy)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 25
}
# ...
]
subscriptions = stripe.subscriptions.list(customer=user["stripeCustomerId"], status="active")
active_subscription = subscriptions["data"][0]
if not active_subscription:
# todo: customer has no active subscription, should we treat this as free?
pass
plan_stripe_price_id = active_subscription["items"]["data"][0]["price"]["id"]
plan = next((plan for plan in PRICING_PLANS if plan["stripePriceId"] == plan_stripe_price_id or plan["stripeYearlyPriceId"] == plan_stripe_price_id), None)
if not plan:
# todo: customer has an active subscription but we don't know what plan it is ??? maybe some older legacy plan?
pass
org = Organization.find_one(id=user["orgId"])
boards_count = Board.count(organizationId=org["id"], status="ACTIVE")
if boards_count < plan["boardsLimit"] or boards_count < org["legacyEnterpriseBoardsLimit"] or org["isVIP"]:
# finally allow user to open another board
pass
customer_id: user[:org_id],
feature_id: "feature-active-boards",
options: {requested_usage: 1}
)
if entitlement[:has_access]
# allow user to open another board...
# finally, track that a new board was opened
Stigg.report_usage(
customer_id: user[:organization_id],
feature_id: "feature-active-boards",
value: 1
)
end
{
name: "Free",
stripePriceId: "price_...",
maxActiveBoards: 1,
monthlyAutomationsLimit: 0
},
{
name: "Basic",
stripePriceId: "price_...",
maxActiveBoards: 5,
monthlyAutomationsLimit: 10 # TODO: reset every month, we don't have a way to do this yet
},
{
name: "Premium (New)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 50
},
{
name: "Premium (Legacy)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 25
}
# ...
]
subscriptions = Stripe::Subscription.list(customer: user[:stripe_customer_id], status: "active")
active_subscription = subscriptions.data[0]
if !active_subscription
# todo: customer has no active subscription, should we treat this as free?
end
plan_stripe_price_id = active_subscription.items.data[0].price.id
plan = PRICING_PLANS.find {|plan| plan[:stripePriceId] == plan_stripe_price_id || plan[:stripeYearlyPriceId] == plan_stripe_price_id}if !plan
# todo: customer has an active subscription but we don't know what plan it is ??? maybe some older legacy plan?
end
org = Organization.find_by(id: user[:org_id])
boards_count = Board.where(organization_id: org.id, status: "ACTIVE").count
if boards_count < plan[:boardsLimit] || boards_count < org[:legacyEnterpriseBoardsLimit] || org[:isVIP]
# finally allow user to open another board
end
customer_id: user[:org_id],
feature_id: "feature-active-boards",
options: {requested_usage: 1}
)
if entitlement[:has_access]
# allow user to open another board...
# finally, track that a new board was opened
Stigg.report_usage(
customer_id: user[:organization_id],
feature_id: "feature-active-boards",
value: 1
)
end
{
name: "Free",
stripePriceId: "price_...",
maxActiveBoards: 1,
monthlyAutomationsLimit: 0
},
{
name: "Basic",
stripePriceId: "price_...",
maxActiveBoards: 5,
monthlyAutomationsLimit: 10 # TODO: reset every month, we don't have a way to do this yet
},
{
name: "Premium (New)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 50
},
{
name: "Premium (Legacy)",
stripePriceId: "price_...",
stripeYearlyPriceId: "price_...",
maxActiveBoards: 25
}
# ...
]
subscriptions = Stripe::Subscription.list(customer: user[:stripe_customer_id], status: "active")
active_subscription = subscriptions.data[0]
if !active_subscription
# todo: customer has no active subscription, should we treat this as free?
end
plan_stripe_price_id = active_subscription.items.data[0].price.id
plan = PRICING_PLANS.find {|plan| plan[:stripePriceId] == plan_stripe_price_id || plan[:stripeYearlyPriceId] == plan_stripe_price_id}if !plan
# todo: customer has an active subscription but we don't know what plan it is ??? maybe some older legacy plan?
end
org = Organization.find_by(id: user[:org_id])
boards_count = Board.where(organization_id: org.id, status: "ACTIVE").count
if boards_count < plan[:boardsLimit] || boards_count < org[:legacyEnterpriseBoardsLimit] || org[:isVIP]
# finally allow user to open another board
end
"customerId": user["org_id"],
"featureId": "feature-active-boards",
"options": map[string]interface{}{
"requestedUsage": 1
}
})
if entitlement["hasAccess"] {
// allow user to open another board...
// finally, track that a new board was opened
stigg.ReportUsage(map[string]interface{}{
"customerId": user["organizationId"],
"featureId": "feature-active-boards",
"value": 1
})
}
import (
"fmt"
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/subscription"
)
var PRICING_PLANS = []map[string]interface{}{
{
"name": "Free",
"stripePriceId": "price_...",
"maxActiveBoards": 1,
"monthlyAutomationsLimit": 0,
},
{
"name": "Basic",
"stripePriceId": "price_...",
"maxActiveBoards": 5,
"monthlyAutomationsLimit": 10, //TODO: reset every month, we don't have a way to do this yet
},
{
"name": "Premium (New)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 50,
},
{
"name": "Premium (Legacy)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 25,
},
//...
}
params := &stripe.SubscriptionListParams{
Customer: user["stripe_customer_id"],
Status: "active",
}
subscriptions, _ := subscription.List(params)
active_subscription := subscriptions.Data[0]
if active_subscription == nil {
//todo: customer has no active subscription, should we treat this as free?
}
plan_stripe_price_id := active_subscription.Items.Data[0].Price.ID
plan := getPlan(plan_stripe_price_id)if plan == nil {
//todo: customer has an active subscription but we don't know what plan it is??? maybe some older legacy plan?
}
org, _ := Organization.FindOne(map[string]interface{}{"id": user["org_id"]})
boards_count, _ := Board.Count(map[string]interface{}{"organizationId": org.ID, "status": "ACTIVE"})
if boards_count < plan["boardsLimit"] || boards_count < org["legacyEnterpriseBoardsLimit"] || org["isVIP"] {
//finally allow user to open another board
}
func getPlan(planStripePriceId string) map[string]interface{} {
for _, plan := range PRICING_PLANS {
if plan["stripePriceId"] == planStripePriceId || plan["stripeYearlyPriceId"] == planStripePriceId {
return plan
}
}
return nil
}
"customerId": user["org_id"],
"featureId": "feature-active-boards",
"options": map[string]interface{}{
"requestedUsage": 1
}
})
if entitlement["hasAccess"] {
// allow user to open another board...
// finally, track that a new board was opened
stigg.ReportUsage(map[string]interface{}{
"customerId": user["organizationId"],
"featureId": "feature-active-boards",
"value": 1
})
}
"fmt"
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/subscription"
)
var PRICING_PLANS = []map[string]interface{}{
{
"name": "Free",
"stripePriceId": "price_...",
"maxActiveBoards": 1,
"monthlyAutomationsLimit": 0,
},
{
"name": "Basic",
"stripePriceId": "price_...",
"maxActiveBoards": 5,
"monthlyAutomationsLimit": 10, //TODO: reset every month, we don't have a way to do this yet
},
{
"name": "Premium (New)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 50,
},
{
"name": "Premium (Legacy)",
"stripePriceId": "price_...",
"stripeYearlyPriceId": "price_...",
"maxActiveBoards": 25,
},
//...
}
params := &stripe.SubscriptionListParams{
Customer: user["stripe_customer_id"],
Status: "active",
}
subscriptions, _ := subscription.List(params)
active_subscription := subscriptions.Data[0]
if active_subscription == nil {
//todo: customer has no active subscription, should we treat this as free?
}
plan_stripe_price_id := active_subscription.Items.Data[0].Price.ID
plan := getPlan(plan_stripe_price_id)if plan == nil {
//todo: customer has an active subscription but we don't know what plan it is??? maybe some older legacy plan?
}
org, _ := Organization.FindOne(map[string]interface{}{"id": user["org_id"]})
boards_count, _ := Board.Count(map[string]interface{}{"organizationId": org.ID, "status": "ACTIVE"})
if boards_count < plan["boardsLimit"] || boards_count < org["legacyEnterpriseBoardsLimit"] || org["isVIP"] {
//finally allow user to open another board
}
func getPlan(planStripePriceId string) map[string]interface{} {
for _, plan := range PRICING_PLANS {
if plan["stripePriceId"] == planStripePriceId || plan["stripeYearlyPriceId"] == planStripePriceId {
return plan
}
}
return nil
}
Entitlements give engineers full control over pricing & packaging
Authentication
“Can the user prove who they claim be?”
Authorization
“Can the user access that feature based on his role?”
Feature flagging
“Did we release that feature to that segment of users under that environment?”
Entitlements
“Is that account subscribed to access that feature?”
“What becomes increasingly clear to me is that companies need a monetization platform. If you build it as a platform instead of single entities, you’ll be in a much better place going forward.” Check out Snyk’s story
What’s holding you back?
Plan versioning
Safely roll out changes any way you want: Grandfather plans or segment by attributes, meta data, location, & more.
Multi-environment support
Create as many environments as you want, like development, staging, production. Each one is fully segregated.
Native billing integration
Integrate with Stripe in one click, switch billing providers just as easily. Oh, and we take care of the maintenance, too.
Webhook automation
Send webhook events from Stigg to trigger actions in any application, like user notifications at the end of a trial.
Plug-and-play widgets
Easily introduce self-service components, like a paywall or a customer portal, out of the box.
Secure & scalable
Stigg is SOC2 complaint, built for reliability & availability, and runs on first-class monitoring systems.
Stigg vs alternatives
“We had a first cut of the platform in about 3 weeks.
I thought “Oh yeah, we’re almost done!”. And I’d say I’m quite seasoned.
However, it took 3–4 more months of full-time efforts by several engineers to get to what we have today.” Check out Reclaim’s story