core

package
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2025 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package core defines the core domain types for the subscription plugin.

Package core defines the core domain types for the subscription plugin. These types have no external dependencies and define the business domain model.

Index

Constants

View Source
const (
	CurrencyUSD = "USD"
	CurrencyEUR = "EUR"
	CurrencyGBP = "GBP"
	CurrencyJPY = "JPY"
	CurrencyCAD = "CAD"
	CurrencyAUD = "AUD"
	CurrencyCHF = "CHF"
	CurrencyCNY = "CNY"
	CurrencyINR = "INR"
	CurrencyBRL = "BRL"
)

Common currency codes

View Source
const (
	FeatureKeyMaxMembers        = "max_members"
	FeatureKeyMaxTeams          = "max_teams"
	FeatureKeyMaxProjects       = "max_projects"
	FeatureKeyMaxStorage        = "max_storage_gb"
	FeatureKeyMaxAPICallsMonth  = "max_api_calls_month"
	FeatureKeyCustomDomain      = "custom_domain"
	FeatureKeyPrioritySupport   = "priority_support"
	FeatureKeySSO               = "sso"
	FeatureKeyAuditLogs         = "audit_logs"
	FeatureKeyAdvancedAnalytics = "advanced_analytics"
)

Feature keys for common plan features

View Source
const (
	UsageMetricAPICalls    = "api_calls"
	UsageMetricStorageGB   = "storage_gb"
	UsageMetricBandwidthGB = "bandwidth_gb"
	UsageMetricActiveUsers = "active_users"
	UsageMetricMessages    = "messages"
	UsageMetricCompute     = "compute_hours"
)

Common usage metric keys

View Source
const DefaultCurrency = "USD"

DefaultCurrency is the default currency if not specified

Variables

View Source
var (
	ErrCouponNotFound       = &CouponError{Code: "COUPON_NOT_FOUND", Message: "coupon not found"}
	ErrCouponExpired        = &CouponError{Code: "COUPON_EXPIRED", Message: "coupon has expired"}
	ErrCouponNotYetValid    = &CouponError{Code: "COUPON_NOT_YET_VALID", Message: "coupon is not yet valid"}
	ErrCouponMaxRedemptions = &CouponError{Code: "COUPON_MAX_REDEMPTIONS", Message: "coupon has reached maximum redemptions"}
	ErrCouponNotApplicable  = &CouponError{Code: "COUPON_NOT_APPLICABLE", Message: "coupon is not applicable to this plan"}
	ErrCouponMinPurchase    = &CouponError{Code: "COUPON_MIN_PURCHASE", Message: "purchase amount does not meet minimum"}
	ErrCouponAlreadyUsed    = &CouponError{Code: "COUPON_ALREADY_USED", Message: "coupon has already been used by this organization"}
	ErrCouponFirstPurchase  = &CouponError{Code: "COUPON_FIRST_PURCHASE", Message: "coupon is only valid for first purchase"}
	ErrCouponCodeExists     = &CouponError{Code: "COUPON_CODE_EXISTS", Message: "coupon code already exists"}
)

Common coupon errors

Functions

func CalculateARPU

func CalculateARPU(totalMRR int64, totalCustomers int) int64

CalculateARPU calculates Average Revenue Per User

func CalculateARR

func CalculateARR(mrr int64) int64

CalculateARR calculates ARR from MRR

func CalculateChurnRate

func CalculateChurnRate(customersChurned, customersAtStart int) float64

CalculateChurnRate calculates the churn rate

func CalculateLTV

func CalculateLTV(arpu int64, churnRate float64) int64

CalculateLTV calculates Customer Lifetime Value

func CalculateMRR

func CalculateMRR(subscription *Subscription, plan *Plan) int64

CalculateMRR calculates MRR from a subscription

func CalculateNetRevenueRetention

func CalculateNetRevenueRetention(mrrAtStart, newMRR, expansionMRR, contractionMRR, churnedMRR int64) float64

CalculateNetRevenueRetention calculates NRR

func FormatAmount

func FormatAmount(amount int64, currency string) string

FormatAmount formats an amount for display

Types

type AcknowledgeAlertRequest

type AcknowledgeAlertRequest struct {
	AlertID        xid.ID `json:"alertId" validate:"required"`
	AcknowledgedBy string `json:"acknowledgedBy"`
}

AcknowledgeAlertRequest is used to acknowledge an alert

type AddOn

type AddOn struct {
	ID              xid.ID          `json:"id"`
	AppID           xid.ID          `json:"appId"`           // Scoped to app
	Name            string          `json:"name"`            // Display name
	Slug            string          `json:"slug"`            // URL-safe identifier
	Description     string          `json:"description"`     // Marketing description
	BillingPattern  BillingPattern  `json:"billingPattern"`  // How the add-on is billed
	BillingInterval BillingInterval `json:"billingInterval"` // Billing frequency
	Price           int64           `json:"price"`           // Price in cents
	Currency        string          `json:"currency"`        // ISO 4217 currency code
	Features        []PlanFeature   `json:"features"`        // Features provided by this add-on
	PriceTiers      []PriceTier     `json:"priceTiers"`      // For usage-based add-ons
	TierMode        TierMode        `json:"tierMode"`        // How tiers are applied
	Metadata        map[string]any  `json:"metadata"`        // Custom metadata
	IsActive        bool            `json:"isActive"`        // Available for purchase
	IsPublic        bool            `json:"isPublic"`        // Visible in public listing
	DisplayOrder    int             `json:"displayOrder"`    // Display order
	ProviderPriceID string          `json:"providerPriceId"` // Stripe Price ID
	CreatedAt       time.Time       `json:"createdAt"`
	UpdatedAt       time.Time       `json:"updatedAt"`

	// Constraints
	RequiresPlanIDs []xid.ID `json:"requiresPlanIds"` // Only available with these plans
	ExcludesPlanIDs []xid.ID `json:"excludesPlanIds"` // Not available with these plans
	MaxQuantity     int      `json:"maxQuantity"`     // Maximum quantity per subscription (0 = unlimited)
}

AddOn represents an optional add-on that can be attached to subscriptions

func NewAddOn

func NewAddOn(appID xid.ID, name, slug string) *AddOn

NewAddOn creates a new AddOn with default values

func (*AddOn) CalculatePrice

func (a *AddOn) CalculatePrice(quantity int) int64

CalculatePrice calculates the price for a given quantity

func (*AddOn) GetFeature

func (a *AddOn) GetFeature(key string) *PlanFeature

GetFeature returns a feature by key, or nil if not found

func (*AddOn) IsAvailableForPlan

func (a *AddOn) IsAvailableForPlan(planID xid.ID) bool

IsAvailableForPlan checks if this add-on is available for a specific plan

type AddPaymentMethodRequest

type AddPaymentMethodRequest struct {
	OrganizationID xid.ID            `json:"organizationId" validate:"required"`
	Type           PaymentMethodType `json:"type" validate:"required"`
	SetAsDefault   bool              `json:"setAsDefault"`
	BillingName    string            `json:"billingName"`
	BillingEmail   string            `json:"billingEmail" validate:"omitempty,email"`
	BillingPhone   string            `json:"billingPhone"`
	BillingAddress *BillingAddress   `json:"billingAddress"`
}

AddPaymentMethodRequest represents a request to add a payment method

type Alert

type Alert struct {
	ID             xid.ID  `json:"id"`
	AppID          xid.ID  `json:"appId"`
	OrganizationID xid.ID  `json:"organizationId"`
	ConfigID       *xid.ID `json:"configId"` // Reference to AlertConfig

	// Alert details
	Type     AlertType     `json:"type"`
	Severity AlertSeverity `json:"severity"`
	Status   AlertStatus   `json:"status"`
	Title    string        `json:"title"`
	Message  string        `json:"message"`

	// Context data
	MetricKey      string  `json:"metricKey"`
	CurrentValue   float64 `json:"currentValue"`
	ThresholdValue float64 `json:"thresholdValue"`
	LimitValue     float64 `json:"limitValue"`

	// Related entities
	SubscriptionID *xid.ID `json:"subscriptionId"`
	InvoiceID      *xid.ID `json:"invoiceId"`

	// Delivery tracking
	Channels       []AlertChannel    `json:"channels"`
	SentAt         *time.Time        `json:"sentAt"`
	DeliveryStatus map[string]string `json:"deliveryStatus"` // Channel -> status

	// Acknowledgment
	AcknowledgedAt *time.Time `json:"acknowledgedAt"`
	AcknowledgedBy string     `json:"acknowledgedBy"`

	// Resolution
	ResolvedAt *time.Time `json:"resolvedAt"`
	Resolution string     `json:"resolution"`

	// Metadata
	Metadata  map[string]interface{} `json:"metadata"`
	CreatedAt time.Time              `json:"createdAt"`
	UpdatedAt time.Time              `json:"updatedAt"`
}

Alert represents an individual alert instance

type AlertChannel

type AlertChannel string

AlertChannel represents how an alert is delivered

const (
	AlertChannelEmail   AlertChannel = "email"
	AlertChannelWebhook AlertChannel = "webhook"
	AlertChannelInApp   AlertChannel = "in_app"
	AlertChannelSMS     AlertChannel = "sms"
	AlertChannelSlack   AlertChannel = "slack"
)

type AlertConfig

type AlertConfig struct {
	ID             xid.ID `json:"id"`
	AppID          xid.ID `json:"appId"`
	OrganizationID xid.ID `json:"organizationId"`

	// Alert type settings
	AlertType AlertType `json:"alertType"`
	IsEnabled bool      `json:"isEnabled"`

	// Threshold settings (for usage alerts)
	ThresholdPercent float64 `json:"thresholdPercent"` // Trigger at X% (e.g., 80, 90, 100)
	MetricKey        string  `json:"metricKey"`        // Which metric to monitor

	// Timing settings
	DaysBeforeEnd int `json:"daysBeforeEnd"` // For trial/subscription ending alerts

	// Delivery settings
	Channels     []AlertChannel `json:"channels"`
	Recipients   []string       `json:"recipients"`   // Email addresses
	WebhookURL   string         `json:"webhookUrl"`   // For webhook channel
	SlackChannel string         `json:"slackChannel"` // For Slack channel

	// Frequency settings
	MinInterval     int `json:"minInterval"`     // Minimum minutes between alerts
	MaxAlertsPerDay int `json:"maxAlertsPerDay"` // Max alerts per day (0 = unlimited)

	// Snooze settings
	SnoozedUntil *time.Time `json:"snoozedUntil"`

	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

AlertConfig represents alert configuration for an organization

func DefaultAlertConfigs

func DefaultAlertConfigs(appID, orgID xid.ID) []AlertConfig

DefaultAlertConfigs returns default alert configurations for a new organization

type AlertSeverity

type AlertSeverity string

AlertSeverity represents the severity level of an alert

const (
	AlertSeverityInfo     AlertSeverity = "info"
	AlertSeverityWarning  AlertSeverity = "warning"
	AlertSeverityCritical AlertSeverity = "critical"
)

type AlertStatus

type AlertStatus string

AlertStatus represents the status of an alert

const (
	AlertStatusPending      AlertStatus = "pending"      // Alert created, not yet sent
	AlertStatusSent         AlertStatus = "sent"         // Alert sent
	AlertStatusAcknowledged AlertStatus = "acknowledged" // Alert acknowledged by user
	AlertStatusResolved     AlertStatus = "resolved"     // Alert condition resolved
	AlertStatusSnoozed      AlertStatus = "snoozed"      // Alert snoozed
)

type AlertSummary

type AlertSummary struct {
	TotalAlerts        int                   `json:"totalAlerts"`
	PendingAlerts      int                   `json:"pendingAlerts"`
	SentAlerts         int                   `json:"sentAlerts"`
	AcknowledgedAlerts int                   `json:"acknowledgedAlerts"`
	BySeverity         map[AlertSeverity]int `json:"bySeverity"`
	ByType             map[AlertType]int     `json:"byType"`
	RecentAlerts       []Alert               `json:"recentAlerts"`
}

AlertSummary provides a summary of alerts for an organization

type AlertTemplate

type AlertTemplate struct {
	ID        xid.ID       `json:"id"`
	AppID     xid.ID       `json:"appId"`
	AlertType AlertType    `json:"alertType"`
	Channel   AlertChannel `json:"channel"`

	// Template content
	Subject       string `json:"subject"` // For email
	TitleTemplate string `json:"titleTemplate"`
	BodyTemplate  string `json:"bodyTemplate"`

	IsDefault bool      `json:"isDefault"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

AlertTemplate represents an alert message template

func DefaultAlertTemplates

func DefaultAlertTemplates(appID xid.ID) []AlertTemplate

DefaultAlertTemplates returns default alert templates

type AlertType

type AlertType string

AlertType represents the type of usage alert

const (
	AlertTypeUsageThreshold       AlertType = "usage_threshold"        // When usage reaches X%
	AlertTypeUsageLimit           AlertType = "usage_limit"            // When usage hits limit
	AlertTypePaymentFailed        AlertType = "payment_failed"         // Payment failure
	AlertTypeTrialEnding          AlertType = "trial_ending"           // Trial about to end
	AlertTypeSubscriptionExpiring AlertType = "subscription_expiring"  // Subscription expiring
	AlertTypeInvoicePastDue       AlertType = "invoice_past_due"       // Invoice past due
	AlertTypeSeatLimitApproaching AlertType = "seat_limit_approaching" // Seat limit approaching
)

type AppliedDiscount

type AppliedDiscount struct {
	CouponID       xid.ID     `json:"couponId"`
	CouponCode     string     `json:"couponCode"`
	Type           CouponType `json:"type"`
	OriginalAmount int64      `json:"originalAmount"`
	DiscountAmount int64      `json:"discountAmount"`
	FinalAmount    int64      `json:"finalAmount"`
	Description    string     `json:"description"`
}

AppliedDiscount represents a discount applied to an invoice line item

type AttachAddOnRequest

type AttachAddOnRequest struct {
	SubscriptionID xid.ID `json:"subscriptionId" validate:"required"`
	AddOnID        xid.ID `json:"addOnId" validate:"required"`
	Quantity       int    `json:"quantity" validate:"min=1"`
}

AttachAddOnRequest represents a request to attach an add-on to a subscription

type BillingAddress

type BillingAddress struct {
	Line1      string `json:"line1"`
	Line2      string `json:"line2"`
	City       string `json:"city"`
	State      string `json:"state"`
	PostalCode string `json:"postalCode"`
	Country    string `json:"country" validate:"len=2"` // ISO 3166-1 alpha-2
}

BillingAddress represents a billing address

type BillingInterval

type BillingInterval string

BillingInterval defines the billing frequency

const (
	// BillingIntervalMonthly bills every month
	BillingIntervalMonthly BillingInterval = "monthly"
	// BillingIntervalYearly bills every year
	BillingIntervalYearly BillingInterval = "yearly"
	// BillingIntervalOneTime is a one-time charge
	BillingIntervalOneTime BillingInterval = "one_time"
)

func (BillingInterval) IsValid

func (b BillingInterval) IsValid() bool

IsValid checks if the billing interval is valid

func (BillingInterval) String

func (b BillingInterval) String() string

String returns the string representation of the billing interval

type BillingMetric

type BillingMetric struct {
	ID        xid.ID       `json:"id"`
	AppID     xid.ID       `json:"appId"`
	Type      MetricType   `json:"type"`
	Period    MetricPeriod `json:"period"`
	Value     float64      `json:"value"`
	Currency  string       `json:"currency"`
	Date      time.Time    `json:"date"` // The date this metric is for
	CreatedAt time.Time    `json:"createdAt"`
}

BillingMetric represents a point-in-time billing metric

type BillingPattern

type BillingPattern string

BillingPattern defines how a plan or add-on is billed

const (
	// BillingPatternFlat is a fixed price per billing period
	BillingPatternFlat BillingPattern = "flat"
	// BillingPatternPerSeat charges per user/member
	BillingPatternPerSeat BillingPattern = "per_seat"
	// BillingPatternTiered uses volume-based pricing tiers
	BillingPatternTiered BillingPattern = "tiered"
	// BillingPatternUsage is pay-per-use metered billing
	BillingPatternUsage BillingPattern = "usage"
	// BillingPatternHybrid combines base price with usage
	BillingPatternHybrid BillingPattern = "hybrid"
)

func (BillingPattern) IsValid

func (b BillingPattern) IsValid() bool

IsValid checks if the billing pattern is valid

func (BillingPattern) String

func (b BillingPattern) String() string

String returns the string representation of the billing pattern

type CalculateTaxRequest

type CalculateTaxRequest struct {
	Amount         int64           `json:"amount" validate:"required"`
	Currency       string          `json:"currency" validate:"required,len=3"`
	BillingAddress *BillingAddress `json:"billingAddress"`
	OrganizationID *xid.ID         `json:"organizationId"`
	ProductType    string          `json:"productType"` // For product-specific tax rules
}

CalculateTaxRequest is used to calculate tax for an amount

type CancelSubscriptionRequest

type CancelSubscriptionRequest struct {
	Immediate bool   `json:"immediate"` // If true, cancel immediately; otherwise at period end
	Reason    string `json:"reason"`    // Cancellation reason
}

CancelSubscriptionRequest represents a request to cancel a subscription

type ChurnAnalysis

type ChurnAnalysis struct {
	Period    MetricPeriod `json:"period"`
	StartDate time.Time    `json:"startDate"`
	EndDate   time.Time    `json:"endDate"`

	// Customer churn
	CustomersAtStart  int     `json:"customersAtStart"`
	CustomersAtEnd    int     `json:"customersAtEnd"`
	CustomersChurned  int     `json:"customersChurned"`
	CustomerChurnRate float64 `json:"customerChurnRate"` // Percentage

	// Revenue churn
	MRRAtStart          int64   `json:"mrrAtStart"`
	MRRAtEnd            int64   `json:"mrrAtEnd"`
	MRRChurned          int64   `json:"mrrChurned"`
	RevenueChurnRate    float64 `json:"revenueChurnRate"`    // Percentage
	NetRevenueRetention float64 `json:"netRevenueRetention"` // Percentage (can be >100%)

	// Breakdown by reason
	ChurnByReason map[string]int `json:"churnByReason"` // Reason -> count
	ChurnByPlan   map[string]int `json:"churnByPlan"`   // Plan slug -> count

	Currency string `json:"currency"`
}

ChurnAnalysis provides detailed churn analysis

type CohortAnalysis

type CohortAnalysis struct {
	CohortMonth    time.Time `json:"cohortMonth"` // The month customers signed up
	TotalCustomers int       `json:"totalCustomers"`
	Retention      []float64 `json:"retention"` // Retention rate for each subsequent month
	Revenue        []int64   `json:"revenue"`   // Revenue for each subsequent month
	Currency       string    `json:"currency"`
}

CohortAnalysis represents a cohort analysis for retention

type CohortAnalysisResponse

type CohortAnalysisResponse struct {
	Cohorts  []CohortAnalysis `json:"cohorts"`
	Currency string           `json:"currency"`
}

CohortAnalysisResponse contains cohort analysis results

type Config

type Config struct {
	// General settings
	Enabled             bool `json:"enabled"`
	RequireSubscription bool `json:"requireSubscription"` // Require subscription to create org

	// Trial settings
	DefaultTrialDays  int      `json:"defaultTrialDays"`
	TrialAllowedPlans []string `json:"trialAllowedPlans"` // Plan slugs that allow trials

	// Grace period
	GracePeriodDays int `json:"gracePeriodDays"` // Days before suspending on failed payment

	// Seat management
	AutoSyncSeats bool `json:"autoSyncSeats"` // Auto-update quantity based on org members

	// Plan sync settings
	AutoSyncPlans bool `json:"autoSyncPlans"` // Auto-sync plans to payment provider on create/update

	// Provider configuration
	Provider     string       `json:"provider"` // stripe, paddle, etc.
	StripeConfig StripeConfig `json:"stripe"`

	// Webhook settings
	WebhookTolerance int `json:"webhookTolerance"` // Seconds tolerance for webhook timestamp

	// Metering settings
	UsageReportBatchSize int `json:"usageReportBatchSize"` // Batch size for usage reporting
	UsageReportInterval  int `json:"usageReportInterval"`  // Seconds between usage reports
}

Config holds the subscription plugin configuration

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default plugin configuration

func (*Config) GetWebhookSecret

func (c *Config) GetWebhookSecret() string

GetWebhookSecret returns the appropriate webhook secret based on provider

func (*Config) IsStripeConfigured

func (c *Config) IsStripeConfigured() bool

IsStripeConfigured returns true if Stripe is properly configured

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration

type ConsumeFeatureRequest

type ConsumeFeatureRequest struct {
	OrganizationID xid.ID         `json:"organizationId" validate:"required"`
	FeatureKey     string         `json:"featureKey" validate:"required"`
	Quantity       int64          `json:"quantity" validate:"required,min=1"`
	IdempotencyKey string         `json:"idempotencyKey,omitempty"`
	Reason         string         `json:"reason,omitempty"`
	Metadata       map[string]any `json:"metadata,omitempty"`
}

ConsumeFeatureRequest represents a request to consume feature quota

type ConvertCurrencyRequest

type ConvertCurrencyRequest struct {
	Amount       int64  `json:"amount" validate:"required"`
	FromCurrency string `json:"fromCurrency" validate:"required,len=3"`
	ToCurrency   string `json:"toCurrency" validate:"required,len=3"`
}

ConvertCurrencyRequest is used to convert between currencies

type ConvertCurrencyResponse

type ConvertCurrencyResponse struct {
	OriginalAmount    int64     `json:"originalAmount"`
	OriginalCurrency  string    `json:"originalCurrency"`
	ConvertedAmount   int64     `json:"convertedAmount"`
	ConvertedCurrency string    `json:"convertedCurrency"`
	ExchangeRate      float64   `json:"exchangeRate"`
	ConvertedAt       time.Time `json:"convertedAt"`
}

ConvertCurrencyResponse contains the conversion result

type Coupon

type Coupon struct {
	ID          xid.ID         `json:"id"`
	AppID       xid.ID         `json:"appId"`
	Code        string         `json:"code"`        // Unique coupon code (e.g., "SUMMER2024")
	Name        string         `json:"name"`        // Display name
	Description string         `json:"description"` // Optional description
	Type        CouponType     `json:"type"`        // Type of discount
	Duration    CouponDuration `json:"duration"`    // How long it applies
	Status      CouponStatus   `json:"status"`

	// Discount values (depending on type)
	PercentOff float64 `json:"percentOff"` // Percentage off (0-100)
	AmountOff  int64   `json:"amountOff"`  // Fixed amount off (in smallest currency unit)
	Currency   string  `json:"currency"`   // Currency for fixed amount
	TrialDays  int     `json:"trialDays"`  // Additional trial days
	FreeMonths int     `json:"freeMonths"` // Number of free months

	// Duration settings
	DurationMonths int `json:"durationMonths"` // For repeating duration

	// Restrictions
	MaxRedemptions       int      `json:"maxRedemptions"`       // Max total redemptions (0 = unlimited)
	MaxRedemptionsPerOrg int      `json:"maxRedemptionsPerOrg"` // Max per organization
	MinPurchaseAmount    int64    `json:"minPurchaseAmount"`    // Minimum purchase amount
	ApplicablePlans      []string `json:"applicablePlans"`      // Plan slugs this applies to (empty = all)
	ApplicableAddOns     []string `json:"applicableAddOns"`     // Add-on slugs this applies to
	FirstPurchaseOnly    bool     `json:"firstPurchaseOnly"`    // Only for first purchase

	// Validity
	ValidFrom  time.Time  `json:"validFrom"`
	ValidUntil *time.Time `json:"validUntil"`

	// Usage tracking
	TimesRedeemed int `json:"timesRedeemed"` // Number of times redeemed

	// Provider integration
	ProviderCouponID string `json:"providerCouponId"` // Coupon ID in payment provider

	// Metadata
	Metadata  map[string]interface{} `json:"metadata"`
	CreatedAt time.Time              `json:"createdAt"`
	UpdatedAt time.Time              `json:"updatedAt"`
}

Coupon represents a discount coupon

func (*Coupon) CalculateDiscount

func (c *Coupon) CalculateDiscount(originalAmount int64) int64

CalculateDiscount calculates the discount amount for a given price

func (*Coupon) CanRedeem

func (c *Coupon) CanRedeem() bool

CanRedeem checks if a coupon can be redeemed (considering usage limits)

func (*Coupon) IsValid

func (c *Coupon) IsValid() bool

IsValid checks if a coupon is currently valid (not considering usage limits)

type CouponDuration

type CouponDuration string

CouponDuration defines how long a coupon applies

const (
	CouponDurationOnce      CouponDuration = "once"      // Apply once
	CouponDurationRepeating CouponDuration = "repeating" // Apply for X months
	CouponDurationForever   CouponDuration = "forever"   // Apply forever
)

type CouponError

type CouponError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

CouponError represents a coupon-related error

func (*CouponError) Error

func (e *CouponError) Error() string

type CouponRedemption

type CouponRedemption struct {
	ID             xid.ID `json:"id"`
	AppID          xid.ID `json:"appId"`
	CouponID       xid.ID `json:"couponId"`
	OrganizationID xid.ID `json:"organizationId"`
	SubscriptionID xid.ID `json:"subscriptionId"`

	// Applied discount
	DiscountType   CouponType `json:"discountType"`
	DiscountAmount int64      `json:"discountAmount"` // Actual amount discounted
	Currency       string     `json:"currency"`

	RedeemedAt time.Time  `json:"redeemedAt"`
	ExpiresAt  *time.Time `json:"expiresAt"` // When the discount stops applying
}

CouponRedemption tracks when a coupon is used

type CouponStatus

type CouponStatus string

CouponStatus represents the status of a coupon

const (
	CouponStatusActive   CouponStatus = "active"
	CouponStatusExpired  CouponStatus = "expired"
	CouponStatusArchived CouponStatus = "archived"
)

type CouponType

type CouponType string

CouponType represents the type of discount a coupon provides

const (
	CouponTypePercentage     CouponType = "percentage"      // Percentage off (e.g., 20% off)
	CouponTypeFixedAmount    CouponType = "fixed_amount"    // Fixed amount off (e.g., $10 off)
	CouponTypeTrialExtension CouponType = "trial_extension" // Extend trial period
	CouponTypeFreeMonths     CouponType = "free_months"     // Free months
)

type CreateAddOnRequest

type CreateAddOnRequest struct {
	Name            string          `json:"name" validate:"required,min=1,max=100"`
	Slug            string          `json:"slug" validate:"required,min=1,max=50,alphanum"`
	Description     string          `json:"description" validate:"max=1000"`
	BillingPattern  BillingPattern  `json:"billingPattern" validate:"required"`
	BillingInterval BillingInterval `json:"billingInterval" validate:"required"`
	Price           int64           `json:"price" validate:"min=0"`
	Currency        string          `json:"currency" validate:"len=3"`
	Features        []PlanFeature   `json:"features"`
	PriceTiers      []PriceTier     `json:"priceTiers"`
	TierMode        TierMode        `json:"tierMode"`
	Metadata        map[string]any  `json:"metadata"`
	IsActive        bool            `json:"isActive"`
	IsPublic        bool            `json:"isPublic"`
	DisplayOrder    int             `json:"displayOrder"`
	RequiresPlanIDs []xid.ID        `json:"requiresPlanIds"`
	ExcludesPlanIDs []xid.ID        `json:"excludesPlanIds"`
	MaxQuantity     int             `json:"maxQuantity"`
}

CreateAddOnRequest represents a request to create an add-on

type CreateAlertConfigRequest

type CreateAlertConfigRequest struct {
	OrganizationID   xid.ID         `json:"organizationId" validate:"required"`
	AlertType        AlertType      `json:"alertType" validate:"required"`
	ThresholdPercent float64        `json:"thresholdPercent"`
	MetricKey        string         `json:"metricKey"`
	DaysBeforeEnd    int            `json:"daysBeforeEnd"`
	Channels         []AlertChannel `json:"channels" validate:"required,min=1"`
	Recipients       []string       `json:"recipients"`
	WebhookURL       string         `json:"webhookUrl"`
	SlackChannel     string         `json:"slackChannel"`
	MinInterval      int            `json:"minInterval"`
	MaxAlertsPerDay  int            `json:"maxAlertsPerDay"`
}

CreateAlertConfigRequest is used to create an alert configuration

type CreateCouponRequest

type CreateCouponRequest struct {
	Code                 string                 `json:"code" validate:"required,min=3,max=50"`
	Name                 string                 `json:"name" validate:"required"`
	Description          string                 `json:"description"`
	Type                 CouponType             `json:"type" validate:"required"`
	Duration             CouponDuration         `json:"duration" validate:"required"`
	PercentOff           float64                `json:"percentOff"`
	AmountOff            int64                  `json:"amountOff"`
	Currency             string                 `json:"currency"`
	TrialDays            int                    `json:"trialDays"`
	FreeMonths           int                    `json:"freeMonths"`
	DurationMonths       int                    `json:"durationMonths"`
	MaxRedemptions       int                    `json:"maxRedemptions"`
	MaxRedemptionsPerOrg int                    `json:"maxRedemptionsPerOrg"`
	MinPurchaseAmount    int64                  `json:"minPurchaseAmount"`
	ApplicablePlans      []string               `json:"applicablePlans"`
	ApplicableAddOns     []string               `json:"applicableAddOns"`
	FirstPurchaseOnly    bool                   `json:"firstPurchaseOnly"`
	ValidFrom            time.Time              `json:"validFrom"`
	ValidUntil           *time.Time             `json:"validUntil"`
	Metadata             map[string]interface{} `json:"metadata"`
}

CreateCouponRequest is used to create a new coupon

type CreateCustomerRequest

type CreateCustomerRequest struct {
	OrganizationID xid.ID          `json:"organizationId" validate:"required"`
	Email          string          `json:"email" validate:"required,email"`
	Name           string          `json:"name" validate:"required"`
	Phone          string          `json:"phone"`
	TaxID          string          `json:"taxId"`
	TaxExempt      bool            `json:"taxExempt"`
	BillingAddress *BillingAddress `json:"billingAddress"`
	Metadata       map[string]any  `json:"metadata"`
}

CreateCustomerRequest represents a request to create a customer

type CreateExchangeRateRequest

type CreateExchangeRateRequest struct {
	FromCurrency string    `json:"fromCurrency" validate:"required,len=3"`
	ToCurrency   string    `json:"toCurrency" validate:"required,len=3"`
	Rate         float64   `json:"rate" validate:"required,gt=0"`
	ValidFrom    time.Time `json:"validFrom"`
	Source       string    `json:"source"`
}

CreateExchangeRateRequest is used to create a new exchange rate

type CreateFeatureRequest

type CreateFeatureRequest struct {
	Key          string         `json:"key" validate:"required,min=1,max=100"`
	Name         string         `json:"name" validate:"required,min=1,max=100"`
	Description  string         `json:"description" validate:"max=1000"`
	Type         FeatureType    `json:"type" validate:"required"`
	Unit         string         `json:"unit" validate:"max=50"`
	ResetPeriod  ResetPeriod    `json:"resetPeriod"`
	IsPublic     bool           `json:"isPublic"`
	DisplayOrder int            `json:"displayOrder"`
	Icon         string         `json:"icon" validate:"max=100"`
	Metadata     map[string]any `json:"metadata,omitempty"`
	Tiers        []FeatureTier  `json:"tiers,omitempty"` // For tiered features
}

CreateFeatureRequest represents a request to create a new feature

type CreatePlanRequest

type CreatePlanRequest struct {
	Name            string          `json:"name" validate:"required,min=1,max=100"`
	Slug            string          `json:"slug" validate:"required,min=1,max=50,alphanum"`
	Description     string          `json:"description" validate:"max=1000"`
	BillingPattern  BillingPattern  `json:"billingPattern" validate:"required"`
	BillingInterval BillingInterval `json:"billingInterval" validate:"required"`
	BasePrice       int64           `json:"basePrice" validate:"min=0"`
	Currency        string          `json:"currency" validate:"len=3"`
	TrialDays       int             `json:"trialDays" validate:"min=0,max=365"`
	Features        []PlanFeature   `json:"features"`
	PriceTiers      []PriceTier     `json:"priceTiers"`
	TierMode        TierMode        `json:"tierMode"`
	Metadata        map[string]any  `json:"metadata"`
	IsActive        bool            `json:"isActive"`
	IsPublic        bool            `json:"isPublic"`
	DisplayOrder    int             `json:"displayOrder"`
}

CreatePlanRequest represents a request to create a new plan

type CreatePromotionCodeRequest

type CreatePromotionCodeRequest struct {
	CouponID       xid.ID     `json:"couponId" validate:"required"`
	Code           string     `json:"code" validate:"required,min=3,max=50"`
	MaxRedemptions int        `json:"maxRedemptions"`
	ValidFrom      time.Time  `json:"validFrom"`
	ValidUntil     *time.Time `json:"validUntil"`
	RestrictToOrgs []string   `json:"restrictToOrgs"`
	FirstTimeOnly  bool       `json:"firstTimeOnly"`
}

CreatePromotionCodeRequest is used to create a promotion code

type CreateSubscriptionRequest

type CreateSubscriptionRequest struct {
	OrganizationID xid.ID         `json:"organizationId" validate:"required"`
	PlanID         xid.ID         `json:"planId" validate:"required"`
	Quantity       int            `json:"quantity" validate:"min=1"`
	StartTrial     bool           `json:"startTrial"`
	TrialDays      int            `json:"trialDays" validate:"min=0,max=365"`
	Metadata       map[string]any `json:"metadata"`
}

CreateSubscriptionRequest represents a request to create a subscription

type CreateTaxExemptionRequest

type CreateTaxExemptionRequest struct {
	OrganizationID xid.ID     `json:"organizationId" validate:"required"`
	Type           string     `json:"type" validate:"required"`
	Certificate    string     `json:"certificate" validate:"required"`
	Country        string     `json:"country" validate:"required,len=2"`
	State          string     `json:"state"`
	ExpiresAt      *time.Time `json:"expiresAt"`
}

CreateTaxExemptionRequest is used to create a tax exemption

type CreateTaxIDRequest

type CreateTaxIDRequest struct {
	OrganizationID xid.ID    `json:"organizationId" validate:"required"`
	Type           TaxIDType `json:"type" validate:"required"`
	Value          string    `json:"value" validate:"required"`
	Country        string    `json:"country" validate:"required,len=2"`
}

CreateTaxIDRequest is used to create a customer tax ID

type CreateTaxRateRequest

type CreateTaxRateRequest struct {
	Name        string      `json:"name" validate:"required"`
	Description string      `json:"description"`
	Type        TaxType     `json:"type" validate:"required"`
	Percentage  float64     `json:"percentage" validate:"required,gte=0,lte=100"`
	Country     string      `json:"country" validate:"required,len=2"`
	State       string      `json:"state"`
	City        string      `json:"city"`
	PostalCode  string      `json:"postalCode"`
	Behavior    TaxBehavior `json:"behavior" validate:"required"`
	IsDefault   bool        `json:"isDefault"`
	ValidFrom   time.Time   `json:"validFrom"`
}

CreateTaxRateRequest is used to create a new tax rate

type CurrencyAmount

type CurrencyAmount struct {
	Amount       int64  `json:"amount"`       // Amount in smallest unit (cents, pence, etc.)
	Currency     string `json:"currency"`     // Currency code
	DisplayValue string `json:"displayValue"` // Formatted display value
}

CurrencyAmount represents an amount in a specific currency

type Customer

type Customer struct {
	ID                 xid.ID          `json:"id"`
	OrganizationID     xid.ID          `json:"organizationId"`
	ProviderCustomerID string          `json:"providerCustomerId"` // Stripe Customer ID
	Email              string          `json:"email"`
	Name               string          `json:"name"`
	Phone              string          `json:"phone"`
	TaxID              string          `json:"taxId"` // VAT number, etc.
	TaxExempt          bool            `json:"taxExempt"`
	Currency           string          `json:"currency"`         // Preferred currency
	Balance            int64           `json:"balance"`          // Account balance in cents
	DefaultPaymentID   *xid.ID         `json:"defaultPaymentId"` // Default payment method
	BillingAddress     *BillingAddress `json:"billingAddress"`
	Metadata           map[string]any  `json:"metadata"`
	CreatedAt          time.Time       `json:"createdAt"`
	UpdatedAt          time.Time       `json:"updatedAt"`
}

Customer represents the billing customer for an organization

func NewCustomer

func NewCustomer(orgID xid.ID, email, name string) *Customer

NewCustomer creates a new Customer with default values

type CustomerTaxID

type CustomerTaxID struct {
	ID             xid.ID     `json:"id"`
	AppID          xid.ID     `json:"appId"`
	OrganizationID xid.ID     `json:"organizationId"`
	Type           TaxIDType  `json:"type"`
	Value          string     `json:"value"`
	Country        string     `json:"country"`
	VerifiedAt     *time.Time `json:"verifiedAt"`
	IsValid        bool       `json:"isValid"`
	CreatedAt      time.Time  `json:"createdAt"`
	UpdatedAt      time.Time  `json:"updatedAt"`
}

CustomerTaxID represents a customer's tax identification

type DashboardMetrics

type DashboardMetrics struct {
	// Current state
	TotalMRR              int64 `json:"totalMrr"`
	TotalARR              int64 `json:"totalArr"`
	ActiveSubscriptions   int   `json:"activeSubscriptions"`
	TrialingSubscriptions int   `json:"trialingSubscriptions"`

	// Changes
	MRRGrowth          float64 `json:"mrrGrowth"` // Percentage change
	SubscriptionGrowth float64 `json:"subscriptionGrowth"`

	// Health indicators
	ChurnRate           float64 `json:"churnRate"`
	TrialConversionRate float64 `json:"trialConversionRate"`
	NetRevenueRetention float64 `json:"netRevenueRetention"`

	// Revenue breakdown
	NewMRR       int64 `json:"newMrr"`
	ExpansionMRR int64 `json:"expansionMrr"`
	ChurnedMRR   int64 `json:"churnedMrr"`

	Currency string    `json:"currency"`
	AsOf     time.Time `json:"asOf"`
}

DashboardMetrics provides overview metrics for the dashboard

type EventType

type EventType string

EventType defines subscription-related event types

const (
	// EventSubscriptionCreated when a subscription is created
	EventSubscriptionCreated EventType = "subscription.created"
	// EventSubscriptionUpdated when a subscription is updated
	EventSubscriptionUpdated EventType = "subscription.updated"
	// EventSubscriptionCanceled when a subscription is canceled
	EventSubscriptionCanceled EventType = "subscription.canceled"
	// EventSubscriptionPaused when a subscription is paused
	EventSubscriptionPaused EventType = "subscription.paused"
	// EventSubscriptionResumed when a subscription is resumed
	EventSubscriptionResumed EventType = "subscription.resumed"
	// EventSubscriptionTrialEnding when trial is about to end
	EventSubscriptionTrialEnding EventType = "subscription.trial_ending"
	// EventPaymentSucceeded when payment is successful
	EventPaymentSucceeded EventType = "payment.succeeded"
	// EventPaymentFailed when payment fails
	EventPaymentFailed EventType = "payment.failed"
	// EventInvoiceCreated when invoice is created
	EventInvoiceCreated EventType = "invoice.created"
	// EventInvoicePaid when invoice is paid
	EventInvoicePaid EventType = "invoice.paid"
	// EventUsageRecorded when usage is recorded
	EventUsageRecorded EventType = "usage.recorded"
)

func (EventType) String

func (e EventType) String() string

String returns the string representation of the event type

type ExchangeRate

type ExchangeRate struct {
	ID           xid.ID     `json:"id"`
	AppID        xid.ID     `json:"appId"`
	FromCurrency string     `json:"fromCurrency"` // Source currency code
	ToCurrency   string     `json:"toCurrency"`   // Target currency code
	Rate         float64    `json:"rate"`         // Exchange rate (multiply by this to convert)
	ValidFrom    time.Time  `json:"validFrom"`    // When this rate becomes valid
	ValidUntil   *time.Time `json:"validUntil"`   // When this rate expires (nil = current)
	Source       string     `json:"source"`       // Source of the rate (manual, api, etc.)
	CreatedAt    time.Time  `json:"createdAt"`
	UpdatedAt    time.Time  `json:"updatedAt"`
}

ExchangeRate represents a currency exchange rate

type ExportMetricsRequest

type ExportMetricsRequest struct {
	MetricTypes []MetricType `json:"metricTypes"`
	Period      MetricPeriod `json:"period"`
	StartDate   time.Time    `json:"startDate"`
	EndDate     time.Time    `json:"endDate"`
	Format      string       `json:"format"` // csv, json, xlsx
}

ExportMetricsRequest is used to export metrics

type Feature

type Feature struct {
	ID           xid.ID         `json:"id"`
	AppID        xid.ID         `json:"appId"`
	Key          string         `json:"key"`          // Unique per app
	Name         string         `json:"name"`         // Display name
	Description  string         `json:"description"`  // Feature description
	Type         FeatureType    `json:"type"`         // boolean, limit, unlimited, metered, tiered
	Unit         string         `json:"unit"`         // "seats", "GB", "API calls", etc.
	ResetPeriod  ResetPeriod    `json:"resetPeriod"`  // When usage resets
	IsPublic     bool           `json:"isPublic"`     // Show in pricing pages
	DisplayOrder int            `json:"displayOrder"` // Order in UI
	Icon         string         `json:"icon"`         // Icon identifier for UI
	Metadata     map[string]any `json:"metadata"`
	Tiers        []FeatureTier  `json:"tiers,omitempty"` // For tiered features
	CreatedAt    time.Time      `json:"createdAt"`
	UpdatedAt    time.Time      `json:"updatedAt"`
}

Feature represents a standalone feature definition that can be linked to plans

func NewFeature

func NewFeature(appID xid.ID, key, name string, featureType FeatureType) *Feature

NewFeature creates a new Feature with default values

type FeatureAccess

type FeatureAccess struct {
	Feature      *Feature `json:"feature"`
	HasAccess    bool     `json:"hasAccess"`
	IsBlocked    bool     `json:"isBlocked"`
	Limit        int64    `json:"limit"` // -1 for unlimited, 0 for no access
	CurrentUsage int64    `json:"currentUsage"`
	Remaining    int64    `json:"remaining"`    // -1 for unlimited
	GrantedExtra int64    `json:"grantedExtra"` // Extra from grants
	PlanValue    string   `json:"planValue"`    // The raw value from plan
}

FeatureAccess represents the complete access state for a feature

type FeatureGrant

type FeatureGrant struct {
	ID             xid.ID           `json:"id"`
	OrganizationID xid.ID           `json:"organizationId"`
	FeatureID      xid.ID           `json:"featureId"`
	FeatureKey     string           `json:"featureKey"` // Denormalized for convenience
	GrantType      FeatureGrantType `json:"grantType"`  // addon, override, promotion, trial, manual
	Value          int64            `json:"value"`      // Additional quota
	ExpiresAt      *time.Time       `json:"expiresAt,omitempty"`
	SourceType     string           `json:"sourceType,omitempty"` // addon, coupon, promotion, etc.
	SourceID       *xid.ID          `json:"sourceId,omitempty"`   // AddOn ID, Promotion ID, etc.
	Reason         string           `json:"reason,omitempty"`
	IsActive       bool             `json:"isActive"`
	Metadata       map[string]any   `json:"metadata,omitempty"`
	CreatedAt      time.Time        `json:"createdAt"`
	UpdatedAt      time.Time        `json:"updatedAt"`
}

FeatureGrant provides additional feature access beyond the plan

type FeatureGrantType

type FeatureGrantType string

FeatureGrantType defines the type of feature grant

const (
	// FeatureGrantTypeAddon is a grant from an add-on purchase
	FeatureGrantTypeAddon FeatureGrantType = "addon"
	// FeatureGrantTypeOverride is a manual override
	FeatureGrantTypeOverride FeatureGrantType = "override"
	// FeatureGrantTypePromotion is a promotional grant
	FeatureGrantTypePromotion FeatureGrantType = "promotion"
	// FeatureGrantTypeTrial is a trial grant
	FeatureGrantTypeTrial FeatureGrantType = "trial"
	// FeatureGrantTypeManual is a manually added grant
	FeatureGrantTypeManual FeatureGrantType = "manual"
)

func (FeatureGrantType) IsValid

func (f FeatureGrantType) IsValid() bool

IsValid checks if the feature grant type is valid

func (FeatureGrantType) String

func (f FeatureGrantType) String() string

String returns the string representation of the feature grant type

type FeatureTier

type FeatureTier struct {
	ID        xid.ID `json:"id"`
	FeatureID xid.ID `json:"featureId"`
	TierOrder int    `json:"tierOrder"`
	UpTo      int64  `json:"upTo"`  // -1 for unlimited
	Value     string `json:"value"` // What's unlocked at this tier
	Label     string `json:"label"` // Display label for this tier
}

FeatureTier represents a tier within a tiered feature type

type FeatureType

type FeatureType string

FeatureType defines the type of a plan feature

const (
	// FeatureTypeBoolean is a simple on/off feature
	FeatureTypeBoolean FeatureType = "boolean"
	// FeatureTypeLimit is a numeric limit
	FeatureTypeLimit FeatureType = "limit"
	// FeatureTypeUnlimited is no limit on the feature
	FeatureTypeUnlimited FeatureType = "unlimited"
	// FeatureTypeMetered is a usage-based billing feature
	FeatureTypeMetered FeatureType = "metered"
	// FeatureTypeTiered provides different values at different usage levels
	FeatureTypeTiered FeatureType = "tiered"
)

func (FeatureType) IsConsumable

func (f FeatureType) IsConsumable() bool

IsConsumable returns true if the feature type can be consumed (has usage tracking)

func (FeatureType) IsValid

func (f FeatureType) IsValid() bool

IsValid checks if the feature type is valid

func (FeatureType) String

func (f FeatureType) String() string

String returns the string representation of the feature type

type FeatureUsageAction

type FeatureUsageAction string

FeatureUsageAction defines the type of usage action

const (
	// FeatureUsageActionConsume decrements the available quota
	FeatureUsageActionConsume FeatureUsageAction = "consume"
	// FeatureUsageActionGrant adds to the quota
	FeatureUsageActionGrant FeatureUsageAction = "grant"
	// FeatureUsageActionReset resets the usage counter
	FeatureUsageActionReset FeatureUsageAction = "reset"
	// FeatureUsageActionAdjust manually adjusts the usage
	FeatureUsageActionAdjust FeatureUsageAction = "adjust"
)

func (FeatureUsageAction) IsValid

func (f FeatureUsageAction) IsValid() bool

IsValid checks if the feature usage action is valid

func (FeatureUsageAction) String

func (f FeatureUsageAction) String() string

String returns the string representation of the feature usage action

type FeatureUsageLog

type FeatureUsageLog struct {
	ID             xid.ID         `json:"id"`
	OrganizationID xid.ID         `json:"organizationId"`
	FeatureID      xid.ID         `json:"featureId"`
	FeatureKey     string         `json:"featureKey"`
	Action         string         `json:"action"` // consume, grant, reset, adjust
	Quantity       int64          `json:"quantity"`
	PreviousUsage  int64          `json:"previousUsage"`
	NewUsage       int64          `json:"newUsage"`
	ActorID        *xid.ID        `json:"actorId,omitempty"`
	Reason         string         `json:"reason,omitempty"`
	IdempotencyKey string         `json:"idempotencyKey,omitempty"`
	Metadata       map[string]any `json:"metadata,omitempty"`
	CreatedAt      time.Time      `json:"createdAt"`
}

FeatureUsageLog represents an audit entry for feature usage changes

type FeatureUsageResponse

type FeatureUsageResponse struct {
	FeatureKey   string    `json:"featureKey"`
	FeatureName  string    `json:"featureName"`
	FeatureType  string    `json:"featureType"`
	CurrentUsage int64     `json:"currentUsage"`
	Limit        int64     `json:"limit"`     // -1 for unlimited
	Remaining    int64     `json:"remaining"` // -1 for unlimited
	PeriodStart  time.Time `json:"periodStart"`
	PeriodEnd    time.Time `json:"periodEnd"`
	GrantedExtra int64     `json:"grantedExtra"` // Extra quota from grants
}

FeatureUsageResponse represents the response for feature usage queries

type GetCohortAnalysisRequest

type GetCohortAnalysisRequest struct {
	StartMonth time.Time `json:"startMonth"`
	NumMonths  int       `json:"numMonths"`
	Currency   string    `json:"currency"`
}

GetCohortAnalysisRequest is used to request cohort analysis

type GetMetricsRequest

type GetMetricsRequest struct {
	MetricTypes []MetricType `json:"metricTypes"`
	Period      MetricPeriod `json:"period"`
	StartDate   time.Time    `json:"startDate"`
	EndDate     time.Time    `json:"endDate"`
	Currency    string       `json:"currency"`
	GroupBy     string       `json:"groupBy"` // plan, segment, etc.
}

GetMetricsRequest is used to request billing metrics

type GetUsageSummaryRequest

type GetUsageSummaryRequest struct {
	SubscriptionID xid.ID    `json:"subscriptionId" validate:"required"`
	MetricKey      string    `json:"metricKey" validate:"required"`
	PeriodStart    time.Time `json:"periodStart" validate:"required"`
	PeriodEnd      time.Time `json:"periodEnd" validate:"required"`
}

GetUsageSummaryRequest represents a request to get usage summary

type GrantFeatureRequest

type GrantFeatureRequest struct {
	OrganizationID xid.ID           `json:"organizationId" validate:"required"`
	FeatureKey     string           `json:"featureKey" validate:"required"`
	GrantType      FeatureGrantType `json:"grantType" validate:"required"`
	Value          int64            `json:"value" validate:"required,min=1"`
	ExpiresAt      *time.Time       `json:"expiresAt,omitempty"`
	SourceType     string           `json:"sourceType,omitempty"`
	SourceID       *xid.ID          `json:"sourceId,omitempty"`
	Reason         string           `json:"reason,omitempty"`
	Metadata       map[string]any   `json:"metadata,omitempty"`
}

GrantFeatureRequest represents a request to grant additional feature quota

type Invoice

type Invoice struct {
	ID                xid.ID         `json:"id"`
	SubscriptionID    xid.ID         `json:"subscriptionId"`    // Related subscription
	OrganizationID    xid.ID         `json:"organizationId"`    // Organization billed
	Number            string         `json:"number"`            // Invoice number (e.g., INV-2024-0001)
	Status            InvoiceStatus  `json:"status"`            // Current status
	Currency          string         `json:"currency"`          // ISO 4217 currency code
	Subtotal          int64          `json:"subtotal"`          // Amount before tax in cents
	Tax               int64          `json:"tax"`               // Tax amount in cents
	Total             int64          `json:"total"`             // Total amount in cents
	AmountPaid        int64          `json:"amountPaid"`        // Amount already paid in cents
	AmountDue         int64          `json:"amountDue"`         // Remaining amount due in cents
	Description       string         `json:"description"`       // Invoice description
	PeriodStart       time.Time      `json:"periodStart"`       // Billing period start
	PeriodEnd         time.Time      `json:"periodEnd"`         // Billing period end
	DueDate           time.Time      `json:"dueDate"`           // Payment due date
	PaidAt            *time.Time     `json:"paidAt"`            // When paid
	VoidedAt          *time.Time     `json:"voidedAt"`          // When voided
	ProviderInvoiceID string         `json:"providerInvoiceId"` // Stripe Invoice ID
	ProviderPDFURL    string         `json:"providerPdfUrl"`    // Stripe hosted PDF URL
	HostedInvoiceURL  string         `json:"hostedInvoiceUrl"`  // Stripe hosted invoice page
	Metadata          map[string]any `json:"metadata"`          // Custom metadata
	CreatedAt         time.Time      `json:"createdAt"`
	UpdatedAt         time.Time      `json:"updatedAt"`

	// Relations
	Items []InvoiceItem `json:"items,omitempty"`
}

Invoice represents a billing invoice

func NewInvoice

func NewInvoice(subID, orgID xid.ID) *Invoice

NewInvoice creates a new Invoice with default values

func (*Invoice) AddItem

func (i *Invoice) AddItem(description string, quantity, unitAmount int64) *InvoiceItem

AddItem adds a line item to the invoice

func (*Invoice) Finalize

func (i *Invoice) Finalize()

Finalize moves the invoice from draft to open

func (*Invoice) IsDraft

func (i *Invoice) IsDraft() bool

IsDraft returns true if the invoice is still a draft

func (*Invoice) IsOpen

func (i *Invoice) IsOpen() bool

IsOpen returns true if the invoice is awaiting payment

func (*Invoice) IsOverdue

func (i *Invoice) IsOverdue() bool

IsOverdue returns true if the invoice is past due date and not paid

func (*Invoice) IsPaid

func (i *Invoice) IsPaid() bool

IsPaid returns true if the invoice has been paid

func (*Invoice) MarkPaid

func (i *Invoice) MarkPaid()

MarkPaid marks the invoice as paid

func (*Invoice) Void

func (i *Invoice) Void()

Void voids the invoice

type InvoiceItem

type InvoiceItem struct {
	ID             xid.ID         `json:"id"`
	InvoiceID      xid.ID         `json:"invoiceId"`
	Description    string         `json:"description"`    // Line item description
	Quantity       int64          `json:"quantity"`       // Quantity
	UnitAmount     int64          `json:"unitAmount"`     // Unit price in cents
	Amount         int64          `json:"amount"`         // Total amount in cents
	PlanID         *xid.ID        `json:"planId"`         // Related plan if applicable
	AddOnID        *xid.ID        `json:"addOnId"`        // Related add-on if applicable
	PeriodStart    time.Time      `json:"periodStart"`    // Item period start
	PeriodEnd      time.Time      `json:"periodEnd"`      // Item period end
	Proration      bool           `json:"proration"`      // Is this a proration adjustment
	Metadata       map[string]any `json:"metadata"`       // Custom metadata
	ProviderItemID string         `json:"providerItemId"` // Stripe Invoice Item ID
	CreatedAt      time.Time      `json:"createdAt"`
}

InvoiceItem represents a line item on an invoice

type InvoiceMetrics

type InvoiceMetrics struct {
	Period               MetricPeriod `json:"period"`
	TotalInvoiced        int64        `json:"totalInvoiced"`
	TotalCollected       int64        `json:"totalCollected"`
	TotalOutstanding     int64        `json:"totalOutstanding"`
	TotalOverdue         int64        `json:"totalOverdue"`
	CollectionRate       float64      `json:"collectionRate"`       // Percentage
	AverageTimeToPayment float64      `json:"averageTimeToPayment"` // In days
	Currency             string       `json:"currency"`
}

InvoiceMetrics provides invoice and payment metrics

type InvoiceStatus

type InvoiceStatus string

InvoiceStatus defines the state of an invoice

const (
	// InvoiceStatusDraft is not yet finalized
	InvoiceStatusDraft InvoiceStatus = "draft"
	// InvoiceStatusOpen is awaiting payment
	InvoiceStatusOpen InvoiceStatus = "open"
	// InvoiceStatusPaid has been paid
	InvoiceStatusPaid InvoiceStatus = "paid"
	// InvoiceStatusVoid has been voided
	InvoiceStatusVoid InvoiceStatus = "void"
	// InvoiceStatusUncollectible cannot be collected
	InvoiceStatusUncollectible InvoiceStatus = "uncollectible"
)

func (InvoiceStatus) IsValid

func (i InvoiceStatus) IsValid() bool

IsValid checks if the invoice status is valid

func (InvoiceStatus) String

func (i InvoiceStatus) String() string

String returns the string representation of the invoice status

type LinkFeatureRequest

type LinkFeatureRequest struct {
	FeatureID        xid.ID         `json:"featureId" validate:"required"`
	Value            string         `json:"value"`         // The limit/value for this plan
	IsBlocked        bool           `json:"isBlocked"`     // Explicitly block this feature
	IsHighlighted    bool           `json:"isHighlighted"` // Highlight in pricing UI
	OverrideSettings map[string]any `json:"overrideSettings,omitempty"`
}

LinkFeatureRequest represents a request to link a feature to a plan

type ListInvoicesFilter

type ListInvoicesFilter struct {
	OrganizationID *xid.ID       `json:"organizationId"`
	SubscriptionID *xid.ID       `json:"subscriptionId"`
	Status         InvoiceStatus `json:"status"`
	FromDate       *time.Time    `json:"fromDate"`
	ToDate         *time.Time    `json:"toDate"`
	Page           int           `json:"page"`
	PageSize       int           `json:"pageSize"`
}

ListInvoicesFilter defines filters for listing invoices

type ListUsageRecordsFilter

type ListUsageRecordsFilter struct {
	SubscriptionID *xid.ID    `json:"subscriptionId"`
	OrganizationID *xid.ID    `json:"organizationId"`
	MetricKey      string     `json:"metricKey"`
	FromDate       *time.Time `json:"fromDate"`
	ToDate         *time.Time `json:"toDate"`
	Reported       *bool      `json:"reported"`
	Page           int        `json:"page"`
	PageSize       int        `json:"pageSize"`
}

ListUsageRecordsFilter defines filters for listing usage records

type MRRBreakdown

type MRRBreakdown struct {
	Date            time.Time `json:"date"`
	Currency        string    `json:"currency"`
	TotalMRR        int64     `json:"totalMrr"`
	NewMRR          int64     `json:"newMrr"`          // From new customers
	ExpansionMRR    int64     `json:"expansionMrr"`    // From upgrades
	ContractionMRR  int64     `json:"contractionMrr"`  // From downgrades (negative)
	ChurnedMRR      int64     `json:"churnedMrr"`      // Lost from cancellations (negative)
	ReactivationMRR int64     `json:"reactivationMrr"` // From reactivated customers
	NetNewMRR       int64     `json:"netNewMrr"`       // Total change
}

MRRBreakdown provides a detailed breakdown of MRR

type MetricPeriod

type MetricPeriod string

MetricPeriod represents the time period for metrics

const (
	MetricPeriodDaily   MetricPeriod = "daily"
	MetricPeriodWeekly  MetricPeriod = "weekly"
	MetricPeriodMonthly MetricPeriod = "monthly"
	MetricPeriodYearly  MetricPeriod = "yearly"
)

type MetricType

type MetricType string

MetricType represents the type of billing metric

const (
	MetricTypeMRR             MetricType = "mrr"              // Monthly Recurring Revenue
	MetricTypeARR             MetricType = "arr"              // Annual Recurring Revenue
	MetricTypeChurnRate       MetricType = "churn_rate"       // Customer churn rate
	MetricTypeRevenueChurn    MetricType = "revenue_churn"    // Revenue churn rate
	MetricTypeExpansionMRR    MetricType = "expansion_mrr"    // Expansion MRR (upgrades)
	MetricTypeContractionMRR  MetricType = "contraction_mrr"  // Contraction MRR (downgrades)
	MetricTypeNewMRR          MetricType = "new_mrr"          // New customer MRR
	MetricTypeLTV             MetricType = "ltv"              // Customer Lifetime Value
	MetricTypeCAC             MetricType = "cac"              // Customer Acquisition Cost
	MetricTypeARPU            MetricType = "arpu"             // Average Revenue Per User
	MetricTypeTrialConversion MetricType = "trial_conversion" // Trial to paid conversion rate
	MetricTypeNetRevenue      MetricType = "net_revenue"      // Net revenue retention
)

type MetricsResponse

type MetricsResponse struct {
	Metrics    []BillingMetric   `json:"metrics"`
	MRRHistory []MRRBreakdown    `json:"mrrHistory,omitempty"`
	Churn      *ChurnAnalysis    `json:"churn,omitempty"`
	Dashboard  *DashboardMetrics `json:"dashboard,omitempty"`
	StartDate  time.Time         `json:"startDate"`
	EndDate    time.Time         `json:"endDate"`
	Currency   string            `json:"currency"`
}

MetricsResponse contains the metrics response

type MultiCurrencyPrice

type MultiCurrencyPrice struct {
	BaseCurrency string                    `json:"baseCurrency"`
	BaseAmount   int64                     `json:"baseAmount"`
	Prices       map[string]CurrencyAmount `json:"prices"` // Currency code -> amount
}

MultiCurrencyPrice represents a price in multiple currencies

type OrganizationFeatureUsage

type OrganizationFeatureUsage struct {
	ID             xid.ID         `json:"id"`
	OrganizationID xid.ID         `json:"organizationId"`
	FeatureID      xid.ID         `json:"featureId"`
	FeatureKey     string         `json:"featureKey"` // Denormalized for convenience
	CurrentUsage   int64          `json:"currentUsage"`
	PeriodStart    time.Time      `json:"periodStart"`
	PeriodEnd      time.Time      `json:"periodEnd"`
	LastReset      time.Time      `json:"lastReset"`
	Metadata       map[string]any `json:"metadata,omitempty"`
}

OrganizationFeatureUsage tracks feature usage per organization

type PauseSubscriptionRequest

type PauseSubscriptionRequest struct {
	ResumeAt *time.Time `json:"resumeAt"` // Optional date to auto-resume
	Reason   string     `json:"reason"`   // Pause reason
}

PauseSubscriptionRequest represents a request to pause a subscription

type PaymentMethod

type PaymentMethod struct {
	ID                 xid.ID            `json:"id"`
	OrganizationID     xid.ID            `json:"organizationId"`
	Type               PaymentMethodType `json:"type"`               // card, bank_account, etc.
	IsDefault          bool              `json:"isDefault"`          // Is this the default payment method
	ProviderMethodID   string            `json:"providerMethodId"`   // Stripe PaymentMethod ID
	ProviderCustomerID string            `json:"providerCustomerId"` // Stripe Customer ID

	// Card-specific fields (when Type == PaymentMethodCard)
	CardBrand    string `json:"cardBrand"`    // visa, mastercard, etc.
	CardLast4    string `json:"cardLast4"`    // Last 4 digits
	CardExpMonth int    `json:"cardExpMonth"` // Expiration month
	CardExpYear  int    `json:"cardExpYear"`  // Expiration year
	CardFunding  string `json:"cardFunding"`  // credit, debit, prepaid

	// Bank account specific fields (when Type == PaymentMethodBankAccount)
	BankName          string `json:"bankName"`
	BankLast4         string `json:"bankLast4"`
	BankRoutingNumber string `json:"bankRoutingNumber"` // Masked
	BankAccountType   string `json:"bankAccountType"`   // checking, savings

	// Billing details
	BillingName         string `json:"billingName"`
	BillingEmail        string `json:"billingEmail"`
	BillingPhone        string `json:"billingPhone"`
	BillingAddressLine1 string `json:"billingAddressLine1"`
	BillingAddressLine2 string `json:"billingAddressLine2"`
	BillingCity         string `json:"billingCity"`
	BillingState        string `json:"billingState"`
	BillingPostalCode   string `json:"billingPostalCode"`
	BillingCountry      string `json:"billingCountry"`

	Metadata  map[string]any `json:"metadata"`
	CreatedAt time.Time      `json:"createdAt"`
	UpdatedAt time.Time      `json:"updatedAt"`
}

PaymentMethod represents a stored payment method

func NewPaymentMethod

func NewPaymentMethod(orgID xid.ID, methodType PaymentMethodType) *PaymentMethod

NewPaymentMethod creates a new PaymentMethod with default values

func (*PaymentMethod) DisplayName

func (pm *PaymentMethod) DisplayName() string

DisplayName returns a user-friendly display name for the payment method

func (*PaymentMethod) IsBankAccount

func (pm *PaymentMethod) IsBankAccount() bool

IsBankAccount returns true if this is a bank account

func (*PaymentMethod) IsCard

func (pm *PaymentMethod) IsCard() bool

IsCard returns true if this is a card payment method

func (*PaymentMethod) IsExpired

func (pm *PaymentMethod) IsExpired() bool

IsExpired returns true if the card is expired

func (*PaymentMethod) WillExpireSoon

func (pm *PaymentMethod) WillExpireSoon(days int) bool

WillExpireSoon returns true if the card will expire within the given days

type PaymentMethodType

type PaymentMethodType string

PaymentMethodType defines the type of payment method

const (
	// PaymentMethodCard is a credit/debit card
	PaymentMethodCard PaymentMethodType = "card"
	// PaymentMethodBankAccount is a bank account
	PaymentMethodBankAccount PaymentMethodType = "bank_account"
	// PaymentMethodSepaDebit is SEPA direct debit
	PaymentMethodSepaDebit PaymentMethodType = "sepa_debit"
)

func (PaymentMethodType) IsValid

func (p PaymentMethodType) IsValid() bool

IsValid checks if the payment method type is valid

func (PaymentMethodType) String

func (p PaymentMethodType) String() string

String returns the string representation of the payment method type

type Plan

type Plan struct {
	ID              xid.ID          `json:"id"`
	AppID           xid.ID          `json:"appId"`           // Scoped to app
	Name            string          `json:"name"`            // Display name
	Slug            string          `json:"slug"`            // URL-safe identifier
	Description     string          `json:"description"`     // Marketing description
	Archived        bool            `json:"archived"`        // Whether the plan is archived
	BillingPattern  BillingPattern  `json:"billingPattern"`  // How the plan is billed
	BillingInterval BillingInterval `json:"billingInterval"` // Billing frequency
	BasePrice       int64           `json:"basePrice"`       // Price in cents
	Currency        string          `json:"currency"`        // ISO 4217 currency code
	TrialDays       int             `json:"trialDays"`       // Number of trial days (0 for no trial)
	Features        []PlanFeature   `json:"features"`        // Feature flags and limits
	PriceTiers      []PriceTier     `json:"priceTiers"`      // For tiered/usage pricing
	TierMode        TierMode        `json:"tierMode"`        // How tiers are applied
	Metadata        map[string]any  `json:"metadata"`        // Custom metadata
	IsActive        bool            `json:"isActive"`        // Can be subscribed to
	IsPublic        bool            `json:"isPublic"`        // Visible in public pricing
	DisplayOrder    int             `json:"displayOrder"`    // Order in pricing pages
	ProviderPlanID  string          `json:"providerPlanId"`  // Stripe Product ID
	ProviderPriceID string          `json:"providerPriceId"` // Stripe Price ID
	CreatedAt       time.Time       `json:"createdAt"`
	UpdatedAt       time.Time       `json:"updatedAt"`
}

Plan represents a subscription plan that organizations can subscribe to

func NewPlan

func NewPlan(appID xid.ID, name, slug string) *Plan

NewPlan creates a new Plan with default values

func (*Plan) AddPriceTier

func (p *Plan) AddPriceTier(upTo, unitAmount, flatAmount int64)

AddPriceTier adds a pricing tier to the plan

func (*Plan) CalculateTieredPrice

func (p *Plan) CalculateTieredPrice(quantity int64) int64

CalculateTieredPrice calculates the price for a given quantity using tiered pricing

func (*Plan) GetFeature

func (p *Plan) GetFeature(key string) *PlanFeature

GetFeature returns a feature by key, or nil if not found

func (*Plan) GetFeatureLimit

func (p *Plan) GetFeatureLimit(key string) int64

GetFeatureLimit returns the numeric limit for a feature, or -1 if unlimited

func (*Plan) HasFeature

func (p *Plan) HasFeature(key string) bool

HasFeature checks if a plan has a specific feature enabled

func (*Plan) SetFeature

func (p *Plan) SetFeature(key, name string, featureType FeatureType, value any)

SetFeature adds or updates a feature on the plan

type PlanFeature

type PlanFeature struct {
	Key           string      `json:"key"`                     // Feature identifier (e.g., "max_members")
	Name          string      `json:"name"`                    // Display name
	Description   string      `json:"description"`             // Feature description
	Type          FeatureType `json:"type"`                    // boolean, limit, or unlimited
	Value         any         `json:"value"`                   // The feature value (true, 100, -1 for unlimited)
	Unit          string      `json:"unit,omitempty"`          // Unit of measurement (e.g., "seats", "GB", "API calls")
	IsHighlighted bool        `json:"isHighlighted,omitempty"` // Highlight in pricing comparison
}

PlanFeature represents a feature or limit included in a plan

type PlanFeatureLink struct {
	ID               xid.ID         `json:"id"`
	PlanID           xid.ID         `json:"planId"`
	FeatureID        xid.ID         `json:"featureId"`
	Value            string         `json:"value"`         // JSON: limit value, tier, boolean, etc.
	IsBlocked        bool           `json:"isBlocked"`     // Explicitly blocked for this plan
	IsHighlighted    bool           `json:"isHighlighted"` // Highlight in pricing comparison
	OverrideSettings map[string]any `json:"overrideSettings,omitempty"`
	Feature          *Feature       `json:"feature,omitempty"` // Loaded feature
}

PlanFeatureLink connects features to plans with plan-specific configuration

type PriceTier

type PriceTier struct {
	UpTo       int64 `json:"upTo"`       // Upper bound (-1 for infinite)
	UnitAmount int64 `json:"unitAmount"` // Price per unit in cents
	FlatAmount int64 `json:"flatAmount"` // Flat fee for this tier in cents
}

PriceTier represents a pricing tier for tiered or usage-based billing

type PromotionCode

type PromotionCode struct {
	ID       xid.ID  `json:"id"`
	AppID    xid.ID  `json:"appId"`
	CouponID xid.ID  `json:"couponId"`
	Coupon   *Coupon `json:"coupon,omitempty"`
	Code     string  `json:"code"` // Unique promotion code
	IsActive bool    `json:"isActive"`

	// Restrictions (override coupon settings)
	MaxRedemptions int        `json:"maxRedemptions"` // Max for this specific code
	ValidFrom      time.Time  `json:"validFrom"`
	ValidUntil     *time.Time `json:"validUntil"`

	// Customer restrictions
	RestrictToOrgs []string `json:"restrictToOrgs"` // Org IDs that can use this
	FirstTimeOnly  bool     `json:"firstTimeOnly"`

	// Usage tracking
	TimesRedeemed int `json:"timesRedeemed"`

	// Provider integration
	ProviderPromoID string `json:"providerPromoId"`

	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

PromotionCode represents a promotion code that references a coupon This allows multiple codes to reference the same underlying coupon

type PublicFeature

type PublicFeature struct {
	Key          string `json:"key"`
	Name         string `json:"name"`
	Description  string `json:"description"`
	Type         string `json:"type"`
	Unit         string `json:"unit,omitempty"`
	Icon         string `json:"icon,omitempty"`
	DisplayOrder int    `json:"displayOrder"`
}

PublicFeature represents a feature for public API (pricing pages)

type PublicPlanFeature

type PublicPlanFeature struct {
	Key           string `json:"key"`
	Name          string `json:"name"`
	Description   string `json:"description"`
	Type          string `json:"type"`
	Unit          string `json:"unit,omitempty"`
	Value         any    `json:"value"` // Parsed value (boolean, number, or tier info)
	IsHighlighted bool   `json:"isHighlighted"`
	IsBlocked     bool   `json:"isBlocked"`
	DisplayOrder  int    `json:"displayOrder"`
}

PublicPlanFeature represents a feature within a plan for public API

type RecordUsageRequest

type RecordUsageRequest struct {
	SubscriptionID xid.ID         `json:"subscriptionId" validate:"required"`
	MetricKey      string         `json:"metricKey" validate:"required,min=1,max=50"`
	Quantity       int64          `json:"quantity" validate:"required,min=0"`
	Action         UsageAction    `json:"action" validate:"required"`
	Timestamp      *time.Time     `json:"timestamp"` // Optional, defaults to now
	IdempotencyKey string         `json:"idempotencyKey" validate:"max=100"`
	Metadata       map[string]any `json:"metadata"`
}

RecordUsageRequest represents a request to record usage

type RedeemCouponRequest

type RedeemCouponRequest struct {
	Code           string `json:"code" validate:"required"`
	OrganizationID xid.ID `json:"organizationId" validate:"required"`
	SubscriptionID xid.ID `json:"subscriptionId" validate:"required"`
}

RedeemCouponRequest is used to redeem a coupon

type ResetPeriod

type ResetPeriod string

ResetPeriod defines when feature usage should be reset

const (
	// ResetPeriodNone means usage never resets (cumulative)
	ResetPeriodNone ResetPeriod = "none"
	// ResetPeriodDaily resets usage every day
	ResetPeriodDaily ResetPeriod = "daily"
	// ResetPeriodWeekly resets usage every week
	ResetPeriodWeekly ResetPeriod = "weekly"
	// ResetPeriodMonthly resets usage every month
	ResetPeriodMonthly ResetPeriod = "monthly"
	// ResetPeriodYearly resets usage every year
	ResetPeriodYearly ResetPeriod = "yearly"
	// ResetPeriodBillingCycle resets usage at each billing cycle
	ResetPeriodBillingCycle ResetPeriod = "billing_period"
)

func (ResetPeriod) IsValid

func (r ResetPeriod) IsValid() bool

IsValid checks if the reset period is valid

func (ResetPeriod) String

func (r ResetPeriod) String() string

String returns the string representation of the reset period

type ResolveAlertRequest

type ResolveAlertRequest struct {
	AlertID    xid.ID `json:"alertId" validate:"required"`
	Resolution string `json:"resolution"`
}

ResolveAlertRequest is used to resolve an alert

type RevenueByPlan

type RevenueByPlan struct {
	PlanID            xid.ID  `json:"planId"`
	PlanName          string  `json:"planName"`
	PlanSlug          string  `json:"planSlug"`
	ActiveSubscribers int     `json:"activeSubscribers"`
	MRR               int64   `json:"mrr"`
	ARR               int64   `json:"arr"`
	PercentOfTotal    float64 `json:"percentOfTotal"`
	Currency          string  `json:"currency"`
}

RevenueByPlan shows revenue breakdown by plan

type RevenueBySegment

type RevenueBySegment struct {
	Segment     string  `json:"segment"`
	Subscribers int     `json:"subscribers"`
	MRR         int64   `json:"mrr"`
	ARPU        int64   `json:"arpu"`
	ChurnRate   float64 `json:"churnRate"`
	LTV         int64   `json:"ltv"`
	Currency    string  `json:"currency"`
}

RevenueBySegment shows revenue by customer segment

type SetupIntentResult

type SetupIntentResult struct {
	ClientSecret   string `json:"clientSecret"`   // For client-side confirmation
	SetupIntentID  string `json:"setupIntentId"`  // Stripe SetupIntent ID
	PublishableKey string `json:"publishableKey"` // Stripe publishable key
}

SetupIntentResult represents the result of creating a setup intent

type SnoozeAlertRequest

type SnoozeAlertRequest struct {
	AlertID     xid.ID    `json:"alertId" validate:"required"`
	SnoozeUntil time.Time `json:"snoozeUntil" validate:"required"`
}

SnoozeAlertRequest is used to snooze an alert

type StripeConfig

type StripeConfig struct {
	SecretKey      string `json:"secretKey"`
	WebhookSecret  string `json:"webhookSecret"`
	PublishableKey string `json:"publishableKey"`
	APIVersion     string `json:"apiVersion"`     // Optional: specific API version
	ConnectAccount string `json:"connectAccount"` // Optional: for Stripe Connect
}

StripeConfig holds Stripe-specific configuration

type Subscription

type Subscription struct {
	ID                 xid.ID             `json:"id"`
	OrganizationID     xid.ID             `json:"organizationId"`     // Links to Organization
	PlanID             xid.ID             `json:"planId"`             // Current plan
	Status             SubscriptionStatus `json:"status"`             // Current status
	Quantity           int                `json:"quantity"`           // For per-seat billing
	CurrentPeriodStart time.Time          `json:"currentPeriodStart"` // Start of current billing period
	CurrentPeriodEnd   time.Time          `json:"currentPeriodEnd"`   // End of current billing period
	TrialStart         *time.Time         `json:"trialStart"`         // Start of trial
	TrialEnd           *time.Time         `json:"trialEnd"`           // End of trial
	CancelAt           *time.Time         `json:"cancelAt"`           // Scheduled cancellation date
	CanceledAt         *time.Time         `json:"canceledAt"`         // When cancellation was requested
	EndedAt            *time.Time         `json:"endedAt"`            // When subscription actually ended
	PausedAt           *time.Time         `json:"pausedAt"`           // When subscription was paused
	ResumeAt           *time.Time         `json:"resumeAt"`           // Scheduled resume date
	ProviderSubID      string             `json:"providerSubId"`      // Stripe Subscription ID
	ProviderCustomerID string             `json:"providerCustomerId"` // Stripe Customer ID
	Metadata           map[string]any     `json:"metadata"`           // Custom metadata
	CreatedAt          time.Time          `json:"createdAt"`
	UpdatedAt          time.Time          `json:"updatedAt"`

	// Relations (populated when loaded)
	Plan   *Plan               `json:"plan,omitempty"`
	AddOns []SubscriptionAddOn `json:"addOns,omitempty"`
}

Subscription represents an organization's subscription to a plan

func NewSubscription

func NewSubscription(orgID, planID xid.ID) *Subscription

NewSubscription creates a new Subscription with default values

func (*Subscription) ActivateFromTrial

func (s *Subscription) ActivateFromTrial()

ActivateFromTrial converts trial to active subscription

func (*Subscription) Cancel

func (s *Subscription) Cancel(immediate bool)

Cancel marks the subscription for cancellation

func (*Subscription) DaysUntilRenewal

func (s *Subscription) DaysUntilRenewal() int

DaysUntilRenewal returns the number of days until the next billing date

func (*Subscription) DaysUntilTrialEnd

func (s *Subscription) DaysUntilTrialEnd() int

DaysUntilTrialEnd returns the number of days until trial ends, or -1 if not trialing

func (*Subscription) IsActive

func (s *Subscription) IsActive() bool

IsActive returns true if the subscription is currently usable

func (*Subscription) IsCanceled

func (s *Subscription) IsCanceled() bool

IsCanceled returns true if the subscription has been canceled

func (*Subscription) IsPastDue

func (s *Subscription) IsPastDue() bool

IsPastDue returns true if payment has failed

func (*Subscription) IsPaused

func (s *Subscription) IsPaused() bool

IsPaused returns true if the subscription is paused

func (*Subscription) IsTrialing

func (s *Subscription) IsTrialing() bool

IsTrialing returns true if the subscription is in trial

func (*Subscription) Pause

func (s *Subscription) Pause(resumeAt *time.Time)

Pause pauses the subscription

func (*Subscription) Resume

func (s *Subscription) Resume()

Resume resumes a paused subscription

func (*Subscription) StartTrial

func (s *Subscription) StartTrial(days int)

StartTrial starts a trial period

func (*Subscription) WillCancel

func (s *Subscription) WillCancel() bool

WillCancel returns true if the subscription is scheduled to cancel

type SubscriptionAddOn

type SubscriptionAddOn struct {
	ID                xid.ID    `json:"id"`
	SubscriptionID    xid.ID    `json:"subscriptionId"`
	AddOnID           xid.ID    `json:"addOnId"`
	Quantity          int       `json:"quantity"`
	ProviderSubItemID string    `json:"providerSubItemId"` // Stripe Subscription Item ID
	CreatedAt         time.Time `json:"createdAt"`

	// Relations
	AddOn *AddOn `json:"addOn,omitempty"`
}

SubscriptionAddOn represents an add-on attached to a subscription

type SubscriptionMovement

type SubscriptionMovement struct {
	ID             xid.ID `json:"id"`
	AppID          xid.ID `json:"appId"`
	SubscriptionID xid.ID `json:"subscriptionId"`
	OrganizationID xid.ID `json:"organizationId"`
	MovementType   string `json:"movementType"` // new, upgrade, downgrade, churn, reactivation

	// Revenue impact
	PreviousMRR int64  `json:"previousMrr"`
	NewMRR      int64  `json:"newMrr"`
	MRRChange   int64  `json:"mrrChange"`
	Currency    string `json:"currency"`

	// Plan details
	PreviousPlanID *xid.ID `json:"previousPlanId"`
	NewPlanID      *xid.ID `json:"newPlanId"`

	// Metadata
	Reason     string    `json:"reason"`
	Notes      string    `json:"notes"`
	OccurredAt time.Time `json:"occurredAt"`
	CreatedAt  time.Time `json:"createdAt"`
}

SubscriptionMovement tracks subscription changes

type SubscriptionStatus

type SubscriptionStatus string

SubscriptionStatus defines the current state of a subscription

const (
	// StatusTrialing is an active trial period
	StatusTrialing SubscriptionStatus = "trialing"
	// StatusActive is a paid, active subscription
	StatusActive SubscriptionStatus = "active"
	// StatusPastDue has failed payment but still active
	StatusPastDue SubscriptionStatus = "past_due"
	// StatusCanceled has been cancelled
	StatusCanceled SubscriptionStatus = "canceled"
	// StatusUnpaid has exhausted retry attempts
	StatusUnpaid SubscriptionStatus = "unpaid"
	// StatusPaused is temporarily paused
	StatusPaused SubscriptionStatus = "paused"
	// StatusIncomplete requires payment action to activate
	StatusIncomplete SubscriptionStatus = "incomplete"
)

func (SubscriptionStatus) IsActiveOrTrialing

func (s SubscriptionStatus) IsActiveOrTrialing() bool

IsActiveOrTrialing returns true if the subscription is usable

func (SubscriptionStatus) IsValid

func (s SubscriptionStatus) IsValid() bool

IsValid checks if the subscription status is valid

func (SubscriptionStatus) String

func (s SubscriptionStatus) String() string

String returns the string representation of the subscription status

type SupportedCurrency

type SupportedCurrency struct {
	ID            xid.ID    `json:"id"`
	Code          string    `json:"code"`          // ISO 4217 code (USD, EUR, GBP, etc.)
	Name          string    `json:"name"`          // Display name
	Symbol        string    `json:"symbol"`        // Currency symbol ($, €, £)
	DecimalPlaces int       `json:"decimalPlaces"` // Number of decimal places (2 for most, 0 for JPY)
	IsDefault     bool      `json:"isDefault"`     // Is this the default currency
	IsActive      bool      `json:"isActive"`      // Is this currency currently active
	CreatedAt     time.Time `json:"createdAt"`
	UpdatedAt     time.Time `json:"updatedAt"`
}

SupportedCurrency represents a currency supported by the system

func DefaultCurrencies

func DefaultCurrencies() []SupportedCurrency

DefaultCurrencies returns the default supported currencies

type TaxBehavior

type TaxBehavior string

TaxBehavior defines how tax is applied to prices

const (
	TaxBehaviorExclusive TaxBehavior = "exclusive" // Tax added on top of price
	TaxBehaviorInclusive TaxBehavior = "inclusive" // Tax included in price
)

type TaxBillingAddress

type TaxBillingAddress = BillingAddress

TaxBillingAddress represents a customer's billing address for tax purposes Note: Uses BillingAddress from payment.go for actual address storage This alias is for documentation purposes

type TaxCalculation

type TaxCalculation struct {
	TaxRateID     xid.ID  `json:"taxRateId"`
	TaxRateName   string  `json:"taxRateName"`
	TaxType       TaxType `json:"taxType"`
	Percentage    float64 `json:"percentage"`
	TaxableAmount int64   `json:"taxableAmount"` // Amount before tax
	TaxAmount     int64   `json:"taxAmount"`     // Calculated tax amount
	TotalAmount   int64   `json:"totalAmount"`   // Amount after tax
	Currency      string  `json:"currency"`
	IsExempt      bool    `json:"isExempt"`
	ExemptionID   *xid.ID `json:"exemptionId"`
}

TaxCalculation represents a calculated tax amount

type TaxExemption

type TaxExemption struct {
	ID             xid.ID     `json:"id"`
	AppID          xid.ID     `json:"appId"`
	OrganizationID xid.ID     `json:"organizationId"`
	Type           string     `json:"type"`        // Exemption type (nonprofit, government, resale)
	Certificate    string     `json:"certificate"` // Exemption certificate number
	Country        string     `json:"country"`     // Country where exemption applies
	State          string     `json:"state"`       // State where exemption applies
	VerifiedAt     *time.Time `json:"verifiedAt"`  // When exemption was verified
	ExpiresAt      *time.Time `json:"expiresAt"`   // When exemption expires
	IsActive       bool       `json:"isActive"`
	CreatedAt      time.Time  `json:"createdAt"`
	UpdatedAt      time.Time  `json:"updatedAt"`
}

TaxExemption represents a tax exemption for an organization

type TaxIDType

type TaxIDType string

TaxIDType represents the type of tax ID

const (
	TaxIDTypeVAT    TaxIDType = "eu_vat"
	TaxIDTypeGSTIN  TaxIDType = "in_gst"
	TaxIDTypeABN    TaxIDType = "au_abn"
	TaxIDTypeGST_NZ TaxIDType = "nz_gst"
	TaxIDTypeEIN    TaxIDType = "us_ein"
	TaxIDTypeGST_CA TaxIDType = "ca_gst"
	TaxIDTypeBN     TaxIDType = "ca_bn"
	TaxIDTypeCNPJ   TaxIDType = "br_cnpj"
	TaxIDTypeCPF    TaxIDType = "br_cpf"
	TaxIDTypeCustom TaxIDType = "custom"
)

type TaxRate

type TaxRate struct {
	ID          xid.ID      `json:"id"`
	AppID       xid.ID      `json:"appId"`
	Name        string      `json:"name"`        // Display name (e.g., "US Sales Tax", "UK VAT")
	Description string      `json:"description"` // Optional description
	Type        TaxType     `json:"type"`        // Type of tax
	Percentage  float64     `json:"percentage"`  // Tax rate as percentage (e.g., 20.0 for 20%)
	Country     string      `json:"country"`     // ISO 3166-1 alpha-2 country code
	State       string      `json:"state"`       // State/province code (for US, CA)
	City        string      `json:"city"`        // City (for local taxes)
	PostalCode  string      `json:"postalCode"`  // Postal/ZIP code pattern
	Behavior    TaxBehavior `json:"behavior"`    // Exclusive or inclusive
	IsDefault   bool        `json:"isDefault"`   // Default rate for the region
	IsActive    bool        `json:"isActive"`    // Is this rate active

	// Provider integration
	ProviderTaxRateID string `json:"providerTaxRateId"` // Tax rate ID in payment provider

	// Timestamps
	ValidFrom  time.Time  `json:"validFrom"`  // When rate becomes valid
	ValidUntil *time.Time `json:"validUntil"` // When rate expires
	CreatedAt  time.Time  `json:"createdAt"`
	UpdatedAt  time.Time  `json:"updatedAt"`
}

TaxRate represents a tax rate configuration

type TaxSummary

type TaxSummary struct {
	Calculations []TaxCalculation `json:"calculations"`
	TotalTax     int64            `json:"totalTax"`
	Currency     string           `json:"currency"`
}

TaxSummary represents a summary of taxes on an invoice

type TaxType

type TaxType string

TaxType represents the type of tax

const (
	TaxTypeVAT         TaxType = "vat"         // Value Added Tax (EU, UK)
	TaxTypeGST         TaxType = "gst"         // Goods and Services Tax (AU, NZ, IN)
	TaxTypeSalesTax    TaxType = "sales_tax"   // Sales Tax (US)
	TaxTypeHST         TaxType = "hst"         // Harmonized Sales Tax (Canada)
	TaxTypePST         TaxType = "pst"         // Provincial Sales Tax (Canada)
	TaxTypeConsumption TaxType = "consumption" // Consumption Tax (JP)
	TaxTypeCustom      TaxType = "custom"      // Custom tax type
)

type TierMode

type TierMode string

TierMode defines how tiered pricing is applied

const (
	// TierModeGraduated applies each tier's price to units in that tier
	TierModeGraduated TierMode = "graduated"
	// TierModeVolume applies the final tier's price to all units
	TierModeVolume TierMode = "volume"
)

func (TierMode) IsValid

func (t TierMode) IsValid() bool

IsValid checks if the tier mode is valid

func (TierMode) String

func (t TierMode) String() string

String returns the string representation of the tier mode

type TrialMetrics

type TrialMetrics struct {
	Period             MetricPeriod `json:"period"`
	TrialsStarted      int          `json:"trialsStarted"`
	TrialsConverted    int          `json:"trialsConverted"`
	TrialsExpired      int          `json:"trialsExpired"`
	TrialsActive       int          `json:"trialsActive"`
	ConversionRate     float64      `json:"conversionRate"`
	AverageTrialLength float64      `json:"averageTrialLength"` // In days

	// Conversion by plan
	ConversionByPlan map[string]float64 `json:"conversionByPlan"` // Plan slug -> rate
}

TrialMetrics provides trial conversion metrics

type TriggerAlertRequest

type TriggerAlertRequest struct {
	OrganizationID xid.ID                 `json:"organizationId" validate:"required"`
	Type           AlertType              `json:"type" validate:"required"`
	Severity       AlertSeverity          `json:"severity"`
	Title          string                 `json:"title" validate:"required"`
	Message        string                 `json:"message" validate:"required"`
	Metadata       map[string]interface{} `json:"metadata"`
}

TriggerAlertRequest is used to manually trigger an alert

type UpdateAddOnRequest

type UpdateAddOnRequest struct {
	Name            *string        `json:"name,omitempty" validate:"omitempty,min=1,max=100"`
	Description     *string        `json:"description,omitempty" validate:"omitempty,max=1000"`
	Price           *int64         `json:"price,omitempty" validate:"omitempty,min=0"`
	Features        []PlanFeature  `json:"features,omitempty"`
	PriceTiers      []PriceTier    `json:"priceTiers,omitempty"`
	TierMode        *TierMode      `json:"tierMode,omitempty"`
	Metadata        map[string]any `json:"metadata,omitempty"`
	IsActive        *bool          `json:"isActive,omitempty"`
	IsPublic        *bool          `json:"isPublic,omitempty"`
	DisplayOrder    *int           `json:"displayOrder,omitempty"`
	RequiresPlanIDs []xid.ID       `json:"requiresPlanIds,omitempty"`
	ExcludesPlanIDs []xid.ID       `json:"excludesPlanIds,omitempty"`
	MaxQuantity     *int           `json:"maxQuantity,omitempty"`
}

UpdateAddOnRequest represents a request to update an add-on

type UpdateAlertConfigRequest

type UpdateAlertConfigRequest struct {
	IsEnabled        *bool          `json:"isEnabled"`
	ThresholdPercent *float64       `json:"thresholdPercent"`
	DaysBeforeEnd    *int           `json:"daysBeforeEnd"`
	Channels         []AlertChannel `json:"channels"`
	Recipients       []string       `json:"recipients"`
	WebhookURL       *string        `json:"webhookUrl"`
	SlackChannel     *string        `json:"slackChannel"`
	MinInterval      *int           `json:"minInterval"`
	MaxAlertsPerDay  *int           `json:"maxAlertsPerDay"`
}

UpdateAlertConfigRequest is used to update an alert configuration

type UpdateCouponRequest

type UpdateCouponRequest struct {
	Name                 *string                `json:"name"`
	Description          *string                `json:"description"`
	MaxRedemptions       *int                   `json:"maxRedemptions"`
	MaxRedemptionsPerOrg *int                   `json:"maxRedemptionsPerOrg"`
	ApplicablePlans      []string               `json:"applicablePlans"`
	ApplicableAddOns     []string               `json:"applicableAddOns"`
	ValidUntil           *time.Time             `json:"validUntil"`
	Status               *CouponStatus          `json:"status"`
	Metadata             map[string]interface{} `json:"metadata"`
}

UpdateCouponRequest is used to update a coupon

type UpdateCustomerRequest

type UpdateCustomerRequest struct {
	Email          *string         `json:"email,omitempty" validate:"omitempty,email"`
	Name           *string         `json:"name,omitempty"`
	Phone          *string         `json:"phone,omitempty"`
	TaxID          *string         `json:"taxId,omitempty"`
	TaxExempt      *bool           `json:"taxExempt,omitempty"`
	BillingAddress *BillingAddress `json:"billingAddress,omitempty"`
	Metadata       map[string]any  `json:"metadata,omitempty"`
}

UpdateCustomerRequest represents a request to update a customer

type UpdateExchangeRateRequest

type UpdateExchangeRateRequest struct {
	Rate       *float64   `json:"rate"`
	ValidUntil *time.Time `json:"validUntil"`
}

UpdateExchangeRateRequest is used to update an exchange rate

type UpdateFeatureRequest

type UpdateFeatureRequest struct {
	Name         *string        `json:"name,omitempty" validate:"omitempty,min=1,max=100"`
	Description  *string        `json:"description,omitempty" validate:"omitempty,max=1000"`
	Unit         *string        `json:"unit,omitempty" validate:"omitempty,max=50"`
	ResetPeriod  *ResetPeriod   `json:"resetPeriod,omitempty"`
	IsPublic     *bool          `json:"isPublic,omitempty"`
	DisplayOrder *int           `json:"displayOrder,omitempty"`
	Icon         *string        `json:"icon,omitempty" validate:"omitempty,max=100"`
	Metadata     map[string]any `json:"metadata,omitempty"`
	Tiers        []FeatureTier  `json:"tiers,omitempty"`
}

UpdateFeatureRequest represents a request to update an existing feature

type UpdateLinkRequest

type UpdateLinkRequest struct {
	Value            *string        `json:"value,omitempty"`
	IsBlocked        *bool          `json:"isBlocked,omitempty"`
	IsHighlighted    *bool          `json:"isHighlighted,omitempty"`
	OverrideSettings map[string]any `json:"overrideSettings,omitempty"`
}

UpdateLinkRequest represents a request to update a feature-plan link

type UpdatePlanRequest

type UpdatePlanRequest struct {
	Name         *string        `json:"name,omitempty" validate:"omitempty,min=1,max=100"`
	Description  *string        `json:"description,omitempty" validate:"omitempty,max=1000"`
	BasePrice    *int64         `json:"basePrice,omitempty" validate:"omitempty,min=0"`
	TrialDays    *int           `json:"trialDays,omitempty" validate:"omitempty,min=0,max=365"`
	Features     []PlanFeature  `json:"features,omitempty"`
	PriceTiers   []PriceTier    `json:"priceTiers,omitempty"`
	TierMode     *TierMode      `json:"tierMode,omitempty"`
	Metadata     map[string]any `json:"metadata,omitempty"`
	IsActive     *bool          `json:"isActive,omitempty"`
	IsPublic     *bool          `json:"isPublic,omitempty"`
	DisplayOrder *int           `json:"displayOrder,omitempty"`
}

UpdatePlanRequest represents a request to update an existing plan

type UpdateSubscriptionRequest

type UpdateSubscriptionRequest struct {
	PlanID   *xid.ID        `json:"planId,omitempty"`
	Quantity *int           `json:"quantity,omitempty" validate:"omitempty,min=1"`
	Metadata map[string]any `json:"metadata,omitempty"`
}

UpdateSubscriptionRequest represents a request to update a subscription

type UpdateTaxRateRequest

type UpdateTaxRateRequest struct {
	Name        *string      `json:"name"`
	Description *string      `json:"description"`
	Percentage  *float64     `json:"percentage"`
	Behavior    *TaxBehavior `json:"behavior"`
	IsDefault   *bool        `json:"isDefault"`
	IsActive    *bool        `json:"isActive"`
	ValidUntil  *time.Time   `json:"validUntil"`
}

UpdateTaxRateRequest is used to update a tax rate

type UsageAction

type UsageAction string

UsageAction defines the type of usage update

const (
	// UsageActionSet sets the usage to an absolute value
	UsageActionSet UsageAction = "set"
	// UsageActionIncrement adds to the current usage
	UsageActionIncrement UsageAction = "increment"
	// UsageActionDecrement subtracts from the current usage
	UsageActionDecrement UsageAction = "decrement"
)

func (UsageAction) IsValid

func (u UsageAction) IsValid() bool

IsValid checks if the usage action is valid

func (UsageAction) String

func (u UsageAction) String() string

String returns the string representation of usage action

type UsageLimit

type UsageLimit struct {
	MetricKey      string  `json:"metricKey"`
	CurrentUsage   int64   `json:"currentUsage"`
	Limit          int64   `json:"limit"`          // -1 for unlimited
	RemainingUsage int64   `json:"remainingUsage"` // -1 for unlimited
	IsExceeded     bool    `json:"isExceeded"`
	PercentUsed    float64 `json:"percentUsed"`
}

UsageLimit tracks current usage against limits

func NewUsageLimit

func NewUsageLimit(metricKey string, current, limit int64) *UsageLimit

NewUsageLimit creates a UsageLimit with calculated values

type UsageMetric

type UsageMetric struct {
	Key           string `json:"key"`           // Metric identifier
	Name          string `json:"name"`          // Display name
	Description   string `json:"description"`   // Description
	Unit          string `json:"unit"`          // Unit of measurement (e.g., "calls", "GB")
	AggregateType string `json:"aggregateType"` // "sum", "max", "last_during_period"
}

UsageMetric defines a usage metric for metered billing

type UsageRecord

type UsageRecord struct {
	ID               xid.ID         `json:"id"`
	SubscriptionID   xid.ID         `json:"subscriptionId"`   // Related subscription
	OrganizationID   xid.ID         `json:"organizationId"`   // Organization for quick queries
	MetricKey        string         `json:"metricKey"`        // Usage metric identifier (e.g., "api_calls", "storage_gb")
	Quantity         int64          `json:"quantity"`         // Usage amount
	Action           UsageAction    `json:"action"`           // set, increment, decrement
	Timestamp        time.Time      `json:"timestamp"`        // When the usage occurred
	IdempotencyKey   string         `json:"idempotencyKey"`   // For deduplication
	Metadata         map[string]any `json:"metadata"`         // Additional context
	ProviderRecordID string         `json:"providerRecordId"` // Stripe Usage Record ID
	Reported         bool           `json:"reported"`         // Has been reported to provider
	ReportedAt       *time.Time     `json:"reportedAt"`       // When reported to provider
	CreatedAt        time.Time      `json:"createdAt"`
}

UsageRecord represents a metered usage record

func NewUsageRecord

func NewUsageRecord(subID, orgID xid.ID, metricKey string, quantity int64, action UsageAction) *UsageRecord

NewUsageRecord creates a new UsageRecord

type UsageSnapshot

type UsageSnapshot struct {
	MetricKey    string    `json:"metricKey"`
	CurrentValue int64     `json:"currentValue"`
	Limit        int64     `json:"limit"`
	PercentUsed  float64   `json:"percentUsed"`
	Timestamp    time.Time `json:"timestamp"`
}

UsageSnapshot represents a point-in-time usage snapshot

type UsageSummary

type UsageSummary struct {
	MetricKey     string    `json:"metricKey"`
	TotalQuantity int64     `json:"totalQuantity"`
	PeriodStart   time.Time `json:"periodStart"`
	PeriodEnd     time.Time `json:"periodEnd"`
	RecordCount   int64     `json:"recordCount"`
	FirstRecordAt time.Time `json:"firstRecordAt"`
	LastRecordAt  time.Time `json:"lastRecordAt"`
}

UsageSummary provides aggregated usage data for a metric

type VATValidationResult

type VATValidationResult struct {
	Valid       bool   `json:"valid"`
	CountryCode string `json:"countryCode"`
	VATNumber   string `json:"vatNumber"`
	Name        string `json:"name"`
	Address     string `json:"address"`
	Message     string `json:"message"`
}

VATValidationResult represents the result of VAT validation

type ValidateCouponRequest

type ValidateCouponRequest struct {
	Code           string `json:"code" validate:"required"`
	OrganizationID xid.ID `json:"organizationId" validate:"required"`
	PlanSlug       string `json:"planSlug"`
	AddOnSlug      string `json:"addOnSlug"`
	PurchaseAmount int64  `json:"purchaseAmount"`
}

ValidateCouponRequest is used to validate a coupon code

type ValidateCouponResponse

type ValidateCouponResponse struct {
	Valid           bool     `json:"valid"`
	Coupon          *Coupon  `json:"coupon,omitempty"`
	DiscountAmount  int64    `json:"discountAmount"`
	DiscountPercent float64  `json:"discountPercent"`
	Message         string   `json:"message"`
	Errors          []string `json:"errors,omitempty"`
}

ValidateCouponResponse contains coupon validation result

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL