Skip to main content
← All notes
Building

Twenty packages, two pricing modes, one catalog file

software

Every service I offer — sound engineering, music production, session musician work, software engineering, accessibility consulting — is defined in a single TypeScript array called products. Twenty entries. Each one carries an id, a name, a description, a price in pence or null, a human-readable price label, a list of features, a service key, a delivery estimate, and a consultation duration in minutes. The key field is type — either fixed or contact. Fixed means the price is set and you can buy it right now. Contact means you need a quote. The isPurchasable function checks for fixed type and a non-null pricePence greater than zero. That one function decides everything downstream. If isPurchasable returns true, the service page renders a checkout wizard with Stripe Elements embedded in the page. If it returns false, the page shows the package details with an intake form that sends an enquiry email. Two completely different user journeys, one boolean. Sound engineering has four packages — single track mix and master at two hundred and fifty pounds, EP mix and master priced per track, album mix and master as a quote, and podcast or voiceover edit at a hundred pounds. Music production has five — composition at five hundred, full track at a thousand, TV and film as a quote, advertising as a quote, custom sample packs as a quote. Musician has four — remote track at a hundred, half day at four hundred, full day at eight hundred, multi-day as a quote. Software has four — landing page at fifteen hundred, brochure site at thirty-five hundred, web app as a quote, MVP from five thousand as a quote. Accessibility has four — quick audit at five hundred, full site audit at two thousand, remediation as a quote, training from a thousand as a quote. The getProductsByService function filters the array by service key. Each service page calls it once and maps the result into product cards. Adding a new package means adding one object to the array. No database migration, no dashboard update, no deploy config. Push to main and it is live.

Comments coming soon

Sign in with TikTok to leave a comment. Coming soon.