Pricing Type Definitions
Complete type definitions for PricingModel, BillingPeriod, PricingSpecification, and pricing calculations
This document provides complete TypeScript type definitions for all pricing-related types in the services-as-software platform.
Core Pricing Types
PricingSpecification
The main pricing specification type that defines how a service is priced.
// @errors: 7006
interface PricingSpecification {
model: PricingModel
// ^^^^^^^^^^^^
amount: number
currency: Currency
period?: BillingPeriod
discount?: DiscountSpecification
tiers?: PricingTier[]
// ^^^^^^^^^^^^^
usage?: UsageBasedPricing
trial?: TrialSpecification
setup?: SetupFee
overage?: OveragePricing
}
const pricing: PricingSpecification = {
// ^?
model: 'per-unit',
amount: 50,
currency: 'USD',
}PricingModel
Pricing model types supported by the platform.
type PricingModel =
| 'fixed' // One-time fixed price
| 'per-unit' // Price per unit/item
| 'per-lead' // Price per lead (sales context)
| 'per-user' // Price per user/seat
| 'subscription' // Recurring subscription
| 'usage-based' // Based on usage metrics
| 'tiered' // Volume-based tiers
| 'dynamic' // Dynamic pricing based on factors
| 'freemium' // Free with paid upgrades
| 'custom' // Custom negotiated pricingUsage Examples:
// @errors: 7006
// Fixed price
const fixedPricing: PricingSpecification = {
// ^?
model: 'fixed',
// ^^^^^^^
amount: 500,
currency: 'USD',
}
// Per-unit pricing
const perUnitPricing: PricingSpecification = {
model: 'per-unit',
// ^^^^^^^^^^
amount: 50,
currency: 'USD',
}
// Per-lead pricing
const perLeadPricing: PricingSpecification = {
model: 'per-lead',
amount: 5,
currency: 'USD',
}
// Subscription pricing
const subscriptionPricing: PricingSpecification = {
model: 'subscription',
amount: 299,
currency: 'USD',
period: 'monthly',
// ^^^^^^^^^
}
// Usage-based pricing
const usagePricing: PricingSpecification = {
model: 'usage-based',
amount: 0.01,
currency: 'USD',
usage: {
metric: 'api-calls',
// ^^^^^^^^^^^
unit: 'per-call',
included: 10000,
},
}
// Tiered pricing
const tieredPricing: PricingSpecification = {
model: 'tiered',
amount: 0,
currency: 'USD',
tiers: [
{ min: 0, max: 100, price: 10 },
{ min: 101, max: 500, price: 8 },
{ min: 501, max: null, price: 5 },
],
}Currency
ISO 4217 currency codes.
type Currency =
| 'USD' // US Dollar
| 'EUR' // Euro
| 'GBP' // British Pound
| 'CAD' // Canadian Dollar
| 'AUD' // Australian Dollar
| 'JPY' // Japanese Yen
| 'CNY' // Chinese Yuan
| 'INR' // Indian Rupee
| 'BRL' // Brazilian Real
| 'MXN' // Mexican Peso
| 'CHF' // Swiss Franc
| 'SEK' // Swedish Krona
| 'NOK' // Norwegian Krone
| 'DKK' // Danish Krone
| 'SGD' // Singapore Dollar
| 'HKD' // Hong Kong Dollar
| 'NZD' // New Zealand Dollar
| 'KRW' // South Korean Won
| 'TRY' // Turkish Lira
| 'RUB' // Russian Ruble
| 'ZAR' // South African Rand
// ... other ISO 4217 codesBillingPeriod
Billing period for subscription pricing.
type BillingPeriod = 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'semi-annually' | 'annually' | 'biennial'Usage Example:
// Annual subscription with discount
const annualPricing: PricingSpecification = {
model: 'subscription',
amount: 2990,
currency: 'USD',
period: 'annually',
discount: {
type: 'percentage',
value: 20,
description: 'Save 20% with annual billing',
},
}Discount Types
DiscountSpecification
Discount configuration for pricing.
// @errors: 7006
interface DiscountSpecification {
type: DiscountType
// ^^^^^^^^^^^^
value: number
code?: string
description?: string
validFrom?: string
validUntil?: string
maxUses?: number
conditions?: DiscountCondition[]
}
type DiscountType =
| 'percentage' // Percentage discount
// ^^^^^^^^^^^^
| 'fixed' // Fixed amount discount
| 'volume' // Volume-based discount
| 'promotional' // Promotional discount
| 'seasonal' // Seasonal discount
| 'loyalty' // Loyalty/repeat customer discount
interface DiscountCondition {
field: string
operator: 'eq' | 'gt' | 'gte' | 'lt' | 'lte'
// ^^^^
value: any
}
const discount: DiscountSpecification = {
// ^?
type: 'percentage',
value: 15,
code: 'WELCOME15',
}Usage Examples:
// Percentage discount
const percentageDiscount: DiscountSpecification = {
type: 'percentage',
value: 15,
description: '15% off for new customers',
code: 'WELCOME15',
validUntil: '2025-12-31T23:59:59Z',
maxUses: 100,
}
// Fixed amount discount
const fixedDiscount: DiscountSpecification = {
type: 'fixed',
value: 50,
description: '$50 off your first order',
code: 'FIRST50',
}
// Volume discount
const volumeDiscount: DiscountSpecification = {
type: 'volume',
value: 20,
description: '20% off for orders over 100 units',
conditions: [
{
field: 'quantity',
operator: 'gte',
value: 100,
},
],
}
// Seasonal discount
const seasonalDiscount: DiscountSpecification = {
type: 'seasonal',
value: 25,
description: 'Black Friday sale',
validFrom: '2025-11-25T00:00:00Z',
validUntil: '2025-11-30T23:59:59Z',
}Tiered Pricing
PricingTier
Tier definition for volume-based pricing.
// @errors: 7006
interface PricingTier {
min: number
//^^^
max: number | null
// ^^^^
price: number
description?: string
}
const tier: PricingTier = {
// ^?
min: 0,
max: 100,
price: 10,
description: '0-100 units: $10 per unit',
}Usage Example:
// Volume-based tiered pricing
const tieredPricing: PricingSpecification = {
model: 'tiered',
amount: 0,
currency: 'USD',
tiers: [
{
min: 0,
max: 100,
price: 10,
description: '0-100 units: $10 per unit',
},
{
min: 101,
max: 500,
price: 8,
description: '101-500 units: $8 per unit',
},
{
min: 501,
max: 1000,
price: 6,
description: '501-1000 units: $6 per unit',
},
{
min: 1001,
max: null,
price: 5,
description: '1000+ units: $5 per unit',
},
],
}
// Calculate price for 750 units
function calculateTieredPrice(quantity: number, tiers: PricingTier[]): number {
let total = 0
let remaining = quantity
for (const tier of tiers) {
if (remaining <= 0) break
const tierSize = tier.max ? Math.min(tier.max - tier.min + 1, remaining) : remaining
total += tierSize * tier.price
remaining -= tierSize
}
return total
}
const totalPrice = calculateTieredPrice(750, tieredPricing.tiers)
// = 100 * $10 + 400 * $8 + 250 * $6 = $5700Usage-Based Pricing
UsageBasedPricing
Configuration for usage-based pricing models.
interface UsageBasedPricing {
metric: UsageMetric
unit: string
included?: number
overage?: number
aggregation?: UsageAggregation
resetPeriod?: BillingPeriod
}
type UsageMetric =
| 'api-calls'
| 'compute-hours'
| 'storage-gb'
| 'bandwidth-gb'
| 'requests'
| 'transactions'
| 'users'
| 'seats'
| 'tokens'
| 'messages'
| 'emails'
| 'sms'
| 'custom'
type UsageAggregation =
| 'sum' // Total usage
| 'max' // Peak usage
| 'average' // Average usage
| 'percentile' // 95th percentile, etc.Usage Examples:
// API call pricing
const apiCallPricing: PricingSpecification = {
model: 'usage-based',
amount: 0.001,
currency: 'USD',
usage: {
metric: 'api-calls',
unit: 'per-call',
included: 10000,
overage: 0.001,
aggregation: 'sum',
resetPeriod: 'monthly',
},
}
// Compute hour pricing
const computePricing: PricingSpecification = {
model: 'usage-based',
amount: 0.5,
currency: 'USD',
usage: {
metric: 'compute-hours',
unit: 'per-hour',
aggregation: 'sum',
resetPeriod: 'monthly',
},
}
// Storage pricing with tiers
const storagePricing: PricingSpecification = {
model: 'usage-based',
amount: 0.1,
currency: 'USD',
usage: {
metric: 'storage-gb',
unit: 'per-gb-month',
aggregation: 'average',
resetPeriod: 'monthly',
},
tiers: [
{ min: 0, max: 100, price: 0.1 },
{ min: 101, max: 1000, price: 0.08 },
{ min: 1001, max: null, price: 0.05 },
],
}Trial and Setup
TrialSpecification
Free trial configuration.
interface TrialSpecification {
duration: number
durationUnit: 'days' | 'weeks' | 'months'
creditCard: boolean
autoConvert: boolean
limits?: TrialLimits
}
interface TrialLimits {
[metric: string]: number
}Usage Example:
// 14-day free trial
const trialPricing: PricingSpecification = {
model: 'subscription',
amount: 299,
currency: 'USD',
period: 'monthly',
trial: {
duration: 14,
durationUnit: 'days',
creditCard: true,
autoConvert: true,
limits: {
'api-calls': 1000,
users: 5,
},
},
}SetupFee
One-time setup fee configuration.
interface SetupFee {
amount: number
currency: Currency
description?: string
waived?: boolean
conditions?: SetupFeeCondition[]
}
interface SetupFeeCondition {
type: 'annual-billing' | 'enterprise-tier' | 'promotional'
description: string
}Usage Example:
// Setup fee with conditional waiver
const pricingWithSetup: PricingSpecification = {
model: 'subscription',
amount: 499,
currency: 'USD',
period: 'monthly',
setup: {
amount: 1000,
currency: 'USD',
description: 'One-time implementation and onboarding fee',
waived: false,
conditions: [
{
type: 'annual-billing',
description: 'Setup fee waived for annual billing',
},
],
},
}OveragePricing
Overage pricing for usage beyond included limits.
interface OveragePricing {
rate: number
currency: Currency
unit: string
cap?: number
notification?: OverageNotification
}
interface OverageNotification {
threshold: number
email: boolean
webhook?: boolean
}Usage Example:
// Usage with overage limits
const pricingWithOverage: PricingSpecification = {
model: 'usage-based',
amount: 0.01,
currency: 'USD',
usage: {
metric: 'api-calls',
unit: 'per-call',
included: 10000,
},
overage: {
rate: 0.015,
currency: 'USD',
unit: 'per-call',
cap: 50000,
notification: {
threshold: 0.8,
email: true,
webhook: true,
},
},
}Dynamic Pricing
DynamicPricingFactor
Factors that influence dynamic pricing.
interface DynamicPricingFactor {
type: DynamicFactorType
weight: number
min?: number
max?: number
}
type DynamicFactorType =
| 'demand' // Current demand level
| 'time-of-day' // Time-based pricing
| 'capacity' // Available capacity
| 'location' // Geographic location
| 'customer' // Customer tier/history
| 'market' // Market conditions
| 'competition' // Competitive pricingUsage Example:
// Dynamic pricing based on demand
const dynamicPricing: PricingSpecification = {
model: 'dynamic',
amount: 100,
currency: 'USD',
// Dynamic factors would be evaluated at pricing time
}Price Calculation Types
PriceCalculation
Result of price calculation.
interface PriceCalculation {
basePrice: number
discount: number
tax: number
total: number
currency: Currency
breakdown: PriceBreakdown[]
savings?: number
}
interface PriceBreakdown {
description: string
amount: number
type: 'base' | 'discount' | 'tax' | 'fee' | 'overage'
}Usage Example:
// Calculate price with discount and tax
function calculatePrice(pricing: PricingSpecification, quantity: number, taxRate: number = 0.0): PriceCalculation {
let basePrice = 0
// Calculate base price based on model
switch (pricing.model) {
case 'fixed':
basePrice = pricing.amount
break
case 'per-unit':
case 'per-lead':
basePrice = pricing.amount * quantity
break
case 'tiered':
basePrice = calculateTieredPrice(quantity, pricing.tiers)
break
}
// Apply discount
let discount = 0
if (pricing.discount) {
if (pricing.discount.type === 'percentage') {
discount = basePrice * (pricing.discount.value / 100)
} else if (pricing.discount.type === 'fixed') {
discount = pricing.discount.value
}
}
// Calculate tax
const subtotal = basePrice - discount
const tax = subtotal * taxRate
// Calculate total
const total = subtotal + tax
return {
basePrice,
discount,
tax,
total,
currency: pricing.currency,
breakdown: [
{ description: 'Base price', amount: basePrice, type: 'base' },
{ description: 'Discount', amount: -discount, type: 'discount' },
{ description: 'Tax', amount: tax, type: 'tax' },
],
savings: discount,
}
}
// Example usage
const pricing: PricingSpecification = {
model: 'per-lead',
amount: 5,
currency: 'USD',
discount: {
type: 'percentage',
value: 10,
},
}
const calculation = calculatePrice(pricing, 100, 0.08)
// {
// basePrice: 500,
// discount: 50,
// tax: 36,
// total: 486,
// currency: 'USD',
// breakdown: [...],
// savings: 50
// }Quote
Price quote for a service.
interface Quote {
service: string
pricing: PricingSpecification
quantity: number
calculation: PriceCalculation
validUntil: string
terms?: string[]
}Usage Example:
// Generate quote
async function generateQuote(service: Service, quantity: number): Promise<Quote> {
const calculation = calculatePrice(service.pricing, quantity, 0.08)
return {
service: service.$id,
pricing: service.pricing,
quantity,
calculation,
validUntil: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
terms: ['Price valid for 7 days', 'Subject to availability', 'Payment due on acceptance'],
}
}Complete Pricing Examples
Example 1: SaaS Subscription with Tiers
const saasSubscription: PricingSpecification = {
model: 'subscription',
amount: 49,
currency: 'USD',
period: 'monthly',
tiers: [
{
min: 1,
max: 5,
price: 49,
description: 'Starter: 1-5 users',
},
{
min: 6,
max: 20,
price: 39,
description: 'Professional: 6-20 users ($39/user)',
},
{
min: 21,
max: null,
price: 29,
description: 'Enterprise: 21+ users ($29/user)',
},
],
trial: {
duration: 14,
durationUnit: 'days',
creditCard: true,
autoConvert: true,
},
discount: {
type: 'percentage',
value: 20,
description: 'Save 20% with annual billing',
conditions: [
{
field: 'period',
operator: 'eq',
value: 'annually',
},
],
},
}Example 2: AI Service Usage-Based Pricing
const aiServicePricing: PricingSpecification = {
model: 'usage-based',
amount: 0.01,
currency: 'USD',
usage: {
metric: 'tokens',
unit: 'per-1k-tokens',
included: 100000,
aggregation: 'sum',
resetPeriod: 'monthly',
},
tiers: [
{
min: 0,
max: 100000,
price: 0,
description: '100K tokens included',
},
{
min: 100001,
max: 1000000,
price: 0.01,
description: 'Next 900K tokens: $0.01/1K',
},
{
min: 1000001,
max: null,
price: 0.008,
description: 'Over 1M tokens: $0.008/1K',
},
],
overage: {
rate: 0.015,
currency: 'USD',
unit: 'per-1k-tokens',
notification: {
threshold: 0.9,
email: true,
webhook: true,
},
},
}Example 3: Enterprise Custom Pricing
const enterprisePricing: PricingSpecification = {
model: 'custom',
amount: 0,
currency: 'USD',
setup: {
amount: 5000,
currency: 'USD',
description: 'Custom implementation and integration',
},
// Actual pricing negotiated with sales team
}Utility Functions
Currency Conversion
// Exchange rates (would come from live API)
const exchangeRates: Record<Currency, number> = {
USD: 1.0,
EUR: 0.85,
GBP: 0.73,
CAD: 1.25,
// ... other rates
}
function convertCurrency(amount: number, from: Currency, to: Currency): number {
const usdAmount = amount / exchangeRates[from]
return usdAmount * exchangeRates[to]
}
// Example
const usdPrice = 100
const eurPrice = convertCurrency(usdPrice, 'USD', 'EUR')
// = 85 EURPrice Formatting
function formatPrice(amount: number, currency: Currency): string {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
}).format(amount)
}
// Example
formatPrice(1234.56, 'USD') // "$1,234.56"
formatPrice(1234.56, 'EUR') // "€1,234.56"Type Guards
function isSubscriptionPricing(pricing: PricingSpecification): boolean {
return pricing.model === 'subscription' && !!pricing.period
}
function isUsageBasedPricing(pricing: PricingSpecification): boolean {
return pricing.model === 'usage-based' && !!pricing.usage
}
function hasTieredPricing(pricing: PricingSpecification): boolean {
return !!pricing.tiers && pricing.tiers.length > 0
}
function hasDiscount(pricing: PricingSpecification): boolean {
return !!pricing.discount
}See Also
- Service Types - Service type definitions
- ServiceOrder API - Order API with pricing
- ServiceOffering API - Marketplace pricing