package billing import ( "context" "errors" "time" "aigw/internal/domain" ) var ( ErrInsufficientBalance = errors.New("insufficient balance") ErrStripeDisabled = errors.New("Stripe top-ups are disabled") ErrInvalidAmount = errors.New("invalid amount") ErrQuotaExceeded = errors.New("monthly spend quota exceeded") ) type Meter interface { Authorize(context.Context, Authorization) error Settle(context.Context, domain.UsageEvent) error } type Authorization struct { RequestID string Principal domain.Principal Model domain.Model Body []byte Policy domain.LimitPolicy } type Options struct { DatabaseURL string Currency string DefaultMaxOutputTokens int64 MinTopUpMinor int64 MaxTopUpMinor int64 StripeEnabled bool StripeAPIKey string StripeWebhookSecret string StripeSuccessURL string StripeCancelURL string } type Account struct { TenantID string `json:"tenant_id"` TenantName string `json:"tenant_name"` Currency string `json:"currency"` BalanceMicros int64 `json:"balance_micros"` ReservedMicros int64 `json:"reserved_micros"` AvailableMicros int64 `json:"available_micros"` UpdatedAt time.Time `json:"updated_at"` } type LedgerEntry struct { ID string `json:"id"` TenantID string `json:"tenant_id"` ProjectID string `json:"project_id,omitempty"` Currency string `json:"currency"` AmountMicros int64 `json:"amount_micros"` BalanceAfterMicros int64 `json:"balance_after_micros"` Kind string `json:"kind"` SourceType string `json:"source_type"` SourceID string `json:"source_id"` Description string `json:"description"` CreatedAt time.Time `json:"created_at"` } type AdjustmentInput struct { TenantID string `json:"tenant_id"` AmountMicros int64 `json:"amount_micros"` Description string `json:"description"` } type CheckoutInput struct { TenantID string `json:"tenant_id"` AmountMinor int64 `json:"amount_minor"` } type CheckoutResult struct { OrderID string `json:"order_id"` SessionID string `json:"session_id"` URL string `json:"url"` }