"Like Stripe but simpler" is not a scope; here is what is
title: '"Like Stripe but simpler" is not a scope; here is what is' slug: product-thinking-scope-vs-features pillar: Product Thinking angle: myth audience: Founders, product owners, MVP buyers status: draft
"Like Stripe but simpler" is not a scope; here is what is
Why feature analogies fail as specifications — and the one-sentence test that turns them into something a developer can actually build from.
Every product specification eventually produces one of these sentences: "It is like Stripe but simpler." "Think of it as a simpler version of Notion." "Basically Calendly, but for our specific use case." The analogy arrives as clarification, but it contains no scope. It names the ambition, not the work.
Stripe has fifty-plus products. "Simpler" is not a product. "Simpler" is an opinion about complexity that two people can hold simultaneously and mean completely different things. A developer who hears "like Stripe but simpler" has no idea whether you want one-time payments or subscriptions, whether you need webhook retries, whether idempotency matters, or whether you need coupon codes. Those are not implementation details. They are architectural decisions that affect every part of the system.
The myth as the audience hears it
The myth has a specific structure: product X but [modifier]. The modifier is usually "simpler," "lighter," "for our industry," or "without the parts we don't need." It feels like it communicates scope because it names a reference point. Stripe is a known entity — the listener fills in the details from their experience of Stripe, which may be completely different from what you actually want.
The myth works in meetings because both parties leave with the feeling of alignment. The developer thinks: one-time payments, payment intent flow, webhooks. The founder thinks: subscriptions, coupon codes, a billing portal, maybe usage-based metering for the enterprise tier. Neither person is wrong given their interpretation. They are just aligned on a label rather than a specification.
When the developer starts building and asks "do you need subscriptions or one-time payments?", the founder says "both, eventually." The developer asks "what is the v1 scope?" and the founder says "let us start with subscriptions, actually, because that is our main revenue model." That decision alone changes the shape of the backend:
# One-time payments
modules/payment/
# Subscriptions
modules/payment/
modules/tenant_subscription/
modules/tenant_usage/
modules/coupon/
Four modules instead of one. Each with its own service, DTO, entities, and integration with the payment provider. Not a different size of the same thing — a different category of problem. The analogy did not communicate that distinction.
Where the myth comes from
The analogy pattern is not careless. It comes from a real constraint: early-stage founders often cannot fully specify what they want because they have not yet validated it. "Like Stripe but simpler" is their attempt to communicate direction without over-specifying a product they have not finished thinking through.
The problem is that this communication style, which is appropriate for a napkin conversation between co-founders, gets carried into a technical engagement without being translated into a buildable specification. The analogy is useful for communicating vision; it is not useful for communicating scope.
A secondary driver: founders who have experienced Stripe as customers have strong opinions about the user-facing features (checkout UX, the billing portal, invoice PDFs) but much less visibility into the backend infrastructure requirements (idempotency, webhook retry queues, multi-currency handling). The features they want to simplify are often the user-visible ones; the infrastructure requirements come with the territory regardless of how simple the UX is.
The reality
Every payment system, regardless of how simple the UI looks, requires the same backend infrastructure at the reliability boundary. Idempotency protection is not optional if you want to avoid double-charging. Webhook retry queues are not optional if your integration partners need to be notified of payment events. Async processing is not optional if payment webhooks arrive faster than your API can process them synchronously.
A production TypeScript API boilerplate that handles payments responsibly has this infrastructure in place:
// modules/redis_idempotency/redis_idempotency.service.ts
const TTL_SECONDS = 86400; // 24 hours
export class IdempotencyKey {
static async setPending(idempotencyKey: string): Promise<void> {
const record: IdempotencyRecord = { status: 'pending' };
await redis.set(
IdempotencyKey.key(idempotencyKey),
JSON.stringify(record),
'EX',
TTL_SECONDS
);
}
static async setCompleted(
idempotencyKey: string,
response: { body: unknown; statusCode: number },
): Promise<void> {
const record: IdempotencyRecord = { status: 'completed', response };
await redis.set(
IdempotencyKey.key(idempotencyKey),
JSON.stringify(record),
'EX',
TTL_SECONDS
);
}
}
This is not optional complexity. A mobile client that retries a timed-out payment request without idempotency will charge the user twice. "Simpler Stripe" does not mean "no idempotency." It means the same idempotency infrastructure, potentially with fewer UI features on top.
Background job processing is the other unavoidable requirement. Payment confirmation emails, webhook dispatches, and export generation cannot block the HTTP response cycle in a production application. BullMQ and its Redis dependency are already in scope the moment you decide to send an email after a payment:
// modules/redis/redis.bullmq.ts
export function createQueue<T = unknown>(name: string): Queue<T> {
return new Queue<T>(name, { connection: getBullMQConnection() });
}
Two lines. But behind them: Redis is a dependency, BullMQ worker processes are in scope, the deployment configuration needs to run them, and your infrastructure now has an additional stateful service. "Simpler Stripe" just added Redis and BullMQ.
A concrete example pulled from the target repo
The payment module in this boilerplate — which represents the minimum viable payment implementation — sits alongside:
modules/payment/ # payment records, provider config
modules/coupon/ # discount codes, redemption limits, expiry
modules/tenant_subscription/ # plan management, upgrade/downgrade flows
modules/tenant_usage/ # usage tracking for metered billing
If "like Stripe but simpler" means "subscription billing with coupon support," that is four modules in scope before you write a single application-specific line. Each of those modules interacts with:
modules/notification_mail/ # payment confirmation emails
modules/audit_log/ # compliance — who changed what plan when
modules/tenant_setting/ # per-tenant payment configuration
modules/setting/ # global payment provider config
That is eight modules for a "simple" payment system. None of them is optional if you are building for production. The coupon module alone requires a data model (code, discount type, percent vs. fixed, expiry, usage limit, redemption count), a validation service (is this code valid for this user at this time?), and an application to the payment total before the charge.
The analogy "like Stripe but simpler" contained none of this information. A scope document that lists these eight modules contains all of it.
The better rule
A scope is a list of workflows, not a list of features.
A workflow has: an actor, a trigger, a sequence of steps, and a terminal state. "Subscriptions" is a feature. "A new user selects a monthly plan, enters payment details, receives a confirmation email, and can view their active subscription from their account" is a workflow. The second version names the actor (new user), the trigger (selects a plan), the steps (payment, email, view), and the terminal state (active subscription visible).
When you write scope as workflows, the scope gaps become visible. Does the workflow include plan upgrades? Cancellation? Failed payment retry notifications? Coupon application before checkout? Each of these is a separate workflow, and its presence or absence in the scope document determines whether it is in or out of the estimate.
One sentence for your next scope document: "We need [actor] to be able to [action], starting from [trigger], ending with [terminal state]." Write one sentence per workflow. Count the sentences. That count, more than any analogy, is the real size of your project.
CTA
The next time you find yourself writing "like X but simpler" in a brief, stop and ask: which parts of X, specifically? Write out the workflows you actually want — even rough, one-sentence descriptions — before the developer call. Send them ahead. The estimate will be more accurate, the first sprint will have a real backlog, and you will not be surprised in week four when "simpler" turns out to have a subscription module.
Trade-off
Writing scope as workflows instead of analogies requires more up-front thinking. A founder who is still figuring out the product cannot always write complete workflow descriptions. The risk of spending time on a specification for a product that pivots after the first user test is real. The counter-consideration: a rough workflow list written in forty minutes is still a better specification than an analogy, even if three of the seven workflows change after user testing. The act of writing them surfaces assumptions about what the product actually does that the analogy leaves hidden.
Business impact
The cost of "like Stripe but simpler" as a specification is not the developer's estimate padding, though that is a symptom. The cost is the decision the founder cannot make because the scope is unclear. When you do not know whether subscriptions are in v1 or not, you cannot make a confident infrastructure decision. When you do not know whether multi-tenancy is required, you cannot make a confident data model decision. Both of those decisions are load-bearing — changing them mid-project costs significantly more than making them at the start.
A workflow-based scope document lets a technical founder or CTO read the specification and identify the architectural implications before a line of code is written. That is the point. The specification is not documentation of what was built; it is the input that determines what gets built and how.
What to do next
Write the three most important workflows for your current project in the "[actor] + [action] + [trigger] + [terminal state]" format. Send them to your developer and ask: "Does this change the estimate?" In most cases the answer will be yes — and that change is information you want before the project starts, not after.
If you find it hard to write the workflows, that is the most useful output of the exercise: it means you are not ready to specify yet, which means you are not ready to estimate yet, which means any number you receive right now will be wrong. The specification gap is where budget overruns are born.
Related Articles
Same CategoryComments (0)
Newsletter
Stay updated! Get all the latest and greatest posts delivered straight to your inbox