subscription

package
v1.0.49 Latest Latest
Warning

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

Go to latest
Published: Jan 5, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BillingCyclePreview added in v1.0.25

type BillingCyclePreview struct {
	// NewPeriodStart when the new billing period starts
	NewPeriodStart time.Time `json:"new_period_start"`

	// NewPeriodEnd when the new billing period ends
	NewPeriodEnd time.Time `json:"new_period_end"`

	// NewBillingAnchor for future billing cycles
	NewBillingAnchor time.Time `json:"new_billing_anchor"`

	// BillingCadence of the new plan
	BillingCadence types.BillingCadence `json:"billing_cadence"`

	// BillingPeriod of the new plan
	BillingPeriod types.BillingPeriod `json:"billing_period"`

	// BillingPeriodCount of the new plan
	BillingPeriodCount int `json:"billing_period_count" default:"1"`
}

BillingCyclePreview contains new billing cycle information

type InvoiceAmountPreview added in v1.0.25

type InvoiceAmountPreview struct {
	// Subtotal before taxes
	Subtotal string `json:"subtotal"`

	// TaxAmount total tax
	TaxAmount string `json:"tax_amount"`

	// Total including taxes
	Total string `json:"total"`

	// Currency for all amounts
	Currency string `json:"currency"`

	// LineItems preview
	LineItems []LineItemPreview `json:"line_items,omitempty"`
}

InvoiceAmountPreview contains invoice amount preview information

type LineItemPreview added in v1.0.25

type LineItemPreview struct {
	// Description of the line item
	Description string `json:"description"`

	// Amount for the line item
	Amount string `json:"amount"`

	// Quantity for the line item
	Quantity string `json:"quantity"`

	// IsProration indicates if this is a proration line item
	IsProration bool `json:"is_proration"`

	// PeriodStart for the line item
	PeriodStart *time.Time `json:"period_start,omitempty"`

	// PeriodEnd for the line item
	PeriodEnd *time.Time `json:"period_end,omitempty"`
}

LineItemPreview contains line item preview information

type LineItemRepository

type LineItemRepository interface {
	// Create creates a new subscription line item
	Create(ctx context.Context, lineItem *SubscriptionLineItem) error

	// CreateBulk creates multiple subscription line items in bulk
	CreateBulk(ctx context.Context, lineItems []*SubscriptionLineItem) error

	// Get retrieves a subscription line item by ID
	Get(ctx context.Context, id string) (*SubscriptionLineItem, error)

	// Update updates an existing subscription line item
	Update(ctx context.Context, lineItem *SubscriptionLineItem) error

	// Delete deletes a subscription line item by ID
	Delete(ctx context.Context, id string) error

	// ListBySubscription retrieves all line items for a subscription
	ListBySubscription(ctx context.Context, sub *Subscription) ([]*SubscriptionLineItem, error)

	// List retrieves subscription line items based on filter
	List(ctx context.Context, filter *types.SubscriptionLineItemFilter) ([]*SubscriptionLineItem, error)
}

LineItemRepository defines the interface for subscription line item operations

type Repository

type Repository interface {
	Create(ctx context.Context, subscription *Subscription) error
	Get(ctx context.Context, id string) (*Subscription, error)
	Update(ctx context.Context, subscription *Subscription) error
	Delete(ctx context.Context, id string) error
	List(ctx context.Context, filter *types.SubscriptionFilter) ([]*Subscription, error)
	Count(ctx context.Context, filter *types.SubscriptionFilter) (int, error)
	ListAll(ctx context.Context, filter *types.SubscriptionFilter) ([]*Subscription, error)
	ListAllTenant(ctx context.Context, filter *types.SubscriptionFilter) ([]*Subscription, error)
	CreateWithLineItems(ctx context.Context, subscription *Subscription, items []*SubscriptionLineItem) error
	GetWithLineItems(ctx context.Context, id string) (*Subscription, []*SubscriptionLineItem, error)
	ListByCustomerID(ctx context.Context, customerID string) ([]*Subscription, error)

	// Pause-related methods
	CreatePause(ctx context.Context, pause *SubscriptionPause) error
	GetPause(ctx context.Context, id string) (*SubscriptionPause, error)
	UpdatePause(ctx context.Context, pause *SubscriptionPause) error
	ListPauses(ctx context.Context, subscriptionID string) ([]*SubscriptionPause, error)
	GetWithPauses(ctx context.Context, id string) (*Subscription, []*SubscriptionPause, error)

	// Renewal due alert methods
	ListSubscriptionsDueForRenewal(ctx context.Context) ([]*Subscription, error)
}

type Subscription

type Subscription struct {
	// ID is the unique identifier for the subscription
	ID string `db:"id" json:"id"`

	// LookupKey is the key used to lookup the subscription in our system
	LookupKey string `db:"lookup_key" json:"lookup_key,omitempty"`

	// CustomerID is the identifier for the customer in our system
	CustomerID string `db:"customer_id" json:"customer_id"`

	// PlanID is the identifier for the plan in our system
	PlanID string `db:"plan_id" json:"plan_id"`

	SubscriptionStatus types.SubscriptionStatus `db:"subscription_status" json:"subscription_status"`

	// Currency is the currency of the subscription in lowercase 3 digit ISO codes
	Currency string `db:"currency" json:"currency"`

	// BillingAnchor is the reference point that aligns future billing cycle dates.
	// It sets the day of week for week intervals, the day of month for month and year intervals,
	// and the month of year for year intervals. The timestamp is in UTC format.
	BillingAnchor time.Time `db:"billing_anchor" json:"billing_anchor"`

	// BillingCycle is the cycle of the billing anchor.
	// This is used to determine the billing date for the subscription (i.e set the billing anchor)
	// If not set, the default value is anniversary. Possible values are anniversary and calendar.
	// Anniversary billing means the billing anchor will be the start date of the subscription.
	// Calendar billing means the billing anchor will be the appropriate date based on the billing period.
	// For example, if the billing period is month and the start date is 2025-04-15 then in case of
	// calendar billing the billing anchor will be 2025-05-01 vs 2025-04-15 for anniversary billing.
	BillingCycle types.BillingCycle `db:"billing_cycle" json:"billing_cycle"`

	// StartDate is the start date of the subscription
	StartDate time.Time `db:"start_date" json:"start_date"`

	// EndDate is the end date of the subscription
	EndDate *time.Time `db:"end_date" json:"end_date,omitempty"`

	// CurrentPeriodStart is the end of the current period that the subscription has been invoiced for.
	// At the end of this period, a new invoice will be created.
	CurrentPeriodStart time.Time `db:"current_period_start" json:"current_period_start"`

	// CurrentPeriodEnd is the end of the current period that the subscription has been invoiced for.
	// At the end of this period, a new invoice will be created.
	CurrentPeriodEnd time.Time `db:"current_period_end" json:"current_period_end"`

	// CanceledAt is the date the subscription was canceled
	CancelledAt *time.Time `db:"cancelled_at" json:"cancelled_at,omitempty"`

	// CancelAt is the date the subscription will be canceled
	CancelAt *time.Time `db:"cancel_at" json:"cancel_at"`

	// CancelAtPeriodEnd is whether the subscription was canceled at the end of the current period
	CancelAtPeriodEnd bool `db:"cancel_at_period_end" json:"cancel_at_period_end"`

	// TrialStart is the start date of the trial period
	TrialStart *time.Time `db:"trial_start" json:"trial_start"`

	// TrialEnd is the end date of the trial period
	TrialEnd *time.Time `db:"trial_end" json:"trial_end"`

	BillingCadence types.BillingCadence `db:"billing_cadence" json:"billing_cadence"`

	BillingPeriod types.BillingPeriod `db:"billing_period" json:"billing_period"`

	// BillingPeriodCount is the total number units of the billing period.
	BillingPeriodCount int `db:"billing_period_count" json:"billing_period_count" default:"1"`

	// Version is used for optimistic locking
	Version int `db:"version" json:"version"`

	Metadata types.Metadata `db:"metadata" json:"metadata,omitempty"`

	// EnvironmentID is the environment identifier for the subscription
	EnvironmentID string `db:"environment_id" json:"environment_id"`

	PauseStatus types.PauseStatus `db:"pause_status" json:"pause_status"`

	// ActivePauseID references the current active pause configuration
	// This will be null if no pause is active or scheduled
	ActivePauseID *string `db:"active_pause_id" json:"active_pause_id,omitempty"`

	// CommitmentAmount is the minimum amount a customer commits to paying for a billing period
	CommitmentAmount *decimal.Decimal `db:"commitment_amount" json:"commitment_amount,omitempty" swaggertype:"string"`

	// OverageFactor is a multiplier applied to usage beyond the commitment amount
	OverageFactor *decimal.Decimal `db:"overage_factor" json:"overage_factor,omitempty" swaggertype:"string"`

	// PaymentBehavior determines how subscription payments are handled
	PaymentBehavior string `db:"payment_behavior" json:"payment_behavior"`

	// CollectionMethod determines how invoices are collected
	CollectionMethod string `db:"collection_method" json:"collection_method"`

	// GatewayPaymentMethodID is the gateway payment method ID for this subscription
	GatewayPaymentMethodID *string `db:"gateway_payment_method_id" json:"gateway_payment_method_id,omitempty"`

	LineItems []*SubscriptionLineItem `json:"line_items,omitempty"`

	Pauses []*SubscriptionPause `json:"pauses,omitempty"`

	Phases []*SubscriptionPhase `json:"phases,omitempty"`

	CouponAssociations []*coupon_association.CouponAssociation `json:"coupon_associations,omitempty"`

	CustomerTimezone string `json:"customer_timezone"`

	ProrationBehavior types.ProrationBehavior `json:"proration_behavior"`

	EnableTrueUp bool `json:"enable_true_up"`
	// InvoicingCustomerID is the customer ID to use for invoicing
	// This can differ from the subscription customer (e.g., parent company invoicing for child company)
	InvoicingCustomerID *string `db:"invoicing_customer_id" json:"invoicing_customer_id,omitempty"`

	types.BaseModel
}

func FromEntList added in v1.0.18

func FromEntList(subs []*ent.Subscription) []*Subscription

func GetSubscriptionFromEnt

func GetSubscriptionFromEnt(sub *ent.Subscription) *Subscription

func (*Subscription) GetInvoicingCustomerID added in v1.0.42

func (s *Subscription) GetInvoicingCustomerID() string

GetInvoicingCustomerID returns the invoicing customer ID if available, otherwise falls back to the subscription customer ID. This provides backward compatibility for subscriptions that don't have an invoicing customer ID set.

type SubscriptionChange added in v1.0.25

type SubscriptionChange struct {
	// ID is the unique identifier for the subscription change
	ID string `json:"id"`

	// SubscriptionID is the ID of the subscription being changed
	SubscriptionID string `json:"subscription_id"`

	// TargetPlanID is the ID of the new plan to change to
	TargetPlanID string `json:"target_plan_id"`

	// ProrationBehavior controls how proration is handled
	ProrationBehavior types.ProrationBehavior `json:"proration_behavior"`

	// EffectiveDate is when the change takes effect
	EffectiveDate time.Time `json:"effective_date"`

	// BillingCycleAnchor controls how billing cycle is handled
	BillingCycleAnchor types.BillingCycleAnchor `json:"billing_cycle_anchor"`

	// Metadata contains additional key-value pairs
	Metadata types.Metadata `json:"metadata,omitempty"`

	// Base model fields
	types.BaseModel
}

SubscriptionChange represents a subscription plan change operation

type SubscriptionChangePreview added in v1.0.25

type SubscriptionChangePreview struct {
	// SubscriptionID is the ID of the subscription being changed
	SubscriptionID string `json:"subscription_id"`

	// CurrentPlanID is the current plan ID
	CurrentPlanID string `json:"current_plan_id"`

	// TargetPlanID is the target plan ID
	TargetPlanID string `json:"target_plan_id"`

	// ChangeType indicates upgrade, downgrade, or lateral
	ChangeType types.SubscriptionChangeType `json:"change_type"`

	// ProrationDetails contains proration calculations
	ProrationDetails *SubscriptionProrationPreview `json:"proration_details,omitempty"`

	// EffectiveDate when the change would take effect
	EffectiveDate time.Time `json:"effective_date"`

	// NewBillingCycle information
	NewBillingCycle *BillingCyclePreview `json:"new_billing_cycle,omitempty"`

	// ImmediateInvoiceAmount is the amount that would be invoiced immediately
	ImmediateInvoiceAmount *InvoiceAmountPreview `json:"immediate_invoice_amount,omitempty"`

	// NextInvoiceAmount is how the next invoice would be affected
	NextInvoiceAmount *InvoiceAmountPreview `json:"next_invoice_amount,omitempty"`

	// Warnings about the change
	Warnings []string `json:"warnings,omitempty"`
}

SubscriptionChangePreview represents the preview of a subscription change

type SubscriptionChangeResult added in v1.0.25

type SubscriptionChangeResult struct {
	// OldSubscriptionID is the ID of the archived subscription
	OldSubscriptionID string `json:"old_subscription_id"`

	// NewSubscriptionID is the ID of the new subscription
	NewSubscriptionID string `json:"new_subscription_id"`

	// ChangeType that was executed
	ChangeType types.SubscriptionChangeType `json:"change_type"`

	// InvoiceID of the immediate invoice (if generated)
	InvoiceID *string `json:"invoice_id,omitempty"`

	// ProrationApplied details
	ProrationApplied *SubscriptionProrationPreview `json:"proration_applied,omitempty"`

	// EffectiveDate when the change took effect
	EffectiveDate time.Time `json:"effective_date"`
}

SubscriptionChangeResult represents the result of executing a subscription change

type SubscriptionLineItem

type SubscriptionLineItem struct {
	ID                  string                               `db:"id" json:"id"`
	SubscriptionID      string                               `db:"subscription_id" json:"subscription_id"`
	CustomerID          string                               `db:"customer_id" json:"customer_id"`
	EntityID            string                               `db:"entity_id" json:"entity_id,omitempty"`
	EntityType          types.SubscriptionLineItemEntityType `db:"entity_type" json:"entity_type,omitempty"`
	PlanDisplayName     string                               `db:"plan_display_name" json:"plan_display_name,omitempty"`
	PriceID             string                               `db:"price_id" json:"price_id"`
	PriceType           types.PriceType                      `db:"price_type" json:"price_type,omitempty"`
	MeterID             string                               `db:"meter_id" json:"meter_id,omitempty"`
	MeterDisplayName    string                               `db:"meter_display_name" json:"meter_display_name,omitempty"`
	PriceUnitID         *string                              `db:"price_unit_id" json:"price_unit_id"`
	PriceUnit           *string                              `db:"price_unit" json:"price_unit"`
	DisplayName         string                               `db:"display_name" json:"display_name,omitempty"`
	Quantity            decimal.Decimal                      `db:"quantity" json:"quantity" swaggertype:"string"`
	Currency            string                               `db:"currency" json:"currency"`
	BillingPeriod       types.BillingPeriod                  `db:"billing_period" json:"billing_period"`
	InvoiceCadence      types.InvoiceCadence                 `db:"invoice_cadence" json:"invoice_cadence"`
	TrialPeriod         int                                  `db:"trial_period" json:"trial_period"`
	StartDate           time.Time                            `db:"start_date" json:"start_date,omitempty"`
	EndDate             time.Time                            `db:"end_date" json:"end_date,omitempty"`
	SubscriptionPhaseID *string                              `db:"subscription_phase_id" json:"subscription_phase_id,omitempty"`
	Metadata            map[string]string                    `db:"metadata" json:"metadata,omitempty"`
	EnvironmentID       string                               `db:"environment_id" json:"environment_id"`

	// Commitment fields
	CommitmentAmount        *decimal.Decimal     `db:"commitment_amount" json:"commitment_amount,omitempty"`
	CommitmentQuantity      *decimal.Decimal     `db:"commitment_quantity" json:"commitment_quantity,omitempty"`
	CommitmentType          types.CommitmentType `db:"commitment_type" json:"commitment_type,omitempty"`
	CommitmentOverageFactor *decimal.Decimal     `db:"commitment_overage_factor" json:"commitment_overage_factor,omitempty"`
	CommitmentTrueUpEnabled bool                 `db:"commitment_true_up_enabled" json:"commitment_true_up_enabled"`
	CommitmentWindowed      bool                 `db:"commitment_windowed" json:"commitment_windowed"`

	Price *price.Price `json:"price,omitempty"`

	types.BaseModel
}

SubscriptionLineItem represents a line item in a subscription

func GetLineItemFromEntList

func GetLineItemFromEntList(list []*ent.SubscriptionLineItem) []*SubscriptionLineItem

FromEntList converts a list of Ent SubscriptionLineItems to domain SubscriptionLineItems

func SubscriptionLineItemFromEnt

func SubscriptionLineItemFromEnt(e *ent.SubscriptionLineItem) *SubscriptionLineItem

SubscriptionLineItemFromEnt converts an ent.SubscriptionLineItem to domain SubscriptionLineItem

func (*SubscriptionLineItem) GetCommitmentType added in v1.0.47

func (li *SubscriptionLineItem) GetCommitmentType() types.CommitmentType

GetCommitmentType returns the commitment type for the line item

func (*SubscriptionLineItem) GetPeriod added in v1.0.23

func (li *SubscriptionLineItem) GetPeriod(defaultPeriodStart, defaultPeriodEnd time.Time) (time.Time, time.Time)

GetPeriod returns period start and end dates based on line item dates

func (*SubscriptionLineItem) GetPeriodEnd added in v1.0.23

func (li *SubscriptionLineItem) GetPeriodEnd(defaultPeriodEnd time.Time) time.Time

GetPeriodEnd returns the period end date based on line item dates

func (*SubscriptionLineItem) GetPeriodStart added in v1.0.23

func (li *SubscriptionLineItem) GetPeriodStart(defaultPeriodStart time.Time) time.Time

GetPeriodStart returns the period start date based on line item dates

func (*SubscriptionLineItem) HasCommitment added in v1.0.47

func (li *SubscriptionLineItem) HasCommitment() bool

HasCommitment returns true if the line item has commitment configured

func (*SubscriptionLineItem) IsActive added in v1.0.0

func (li *SubscriptionLineItem) IsActive(t time.Time) bool

IsActive returns true if the line item is active to check if the line item is active and is mostly used with time.Now() and in case of event post processing, we pass the event timestamp

func (*SubscriptionLineItem) IsUsage added in v1.0.17

func (li *SubscriptionLineItem) IsUsage() bool

type SubscriptionPause

type SubscriptionPause struct {
	// ID is the unique identifier for the subscription pause
	ID string `db:"id" json:"id"`

	// SubscriptionID is the identifier for the subscription
	SubscriptionID string `db:"subscription_id" json:"subscription_id"`

	PauseStatus types.PauseStatus `db:"pause_status" json:"pause_status"`
	PauseMode   types.PauseMode   `db:"pause_mode" json:"pause_mode"`
	ResumeMode  types.ResumeMode  `db:"resume_mode" json:"resume_mode,omitempty"`

	// PauseStart is when the pause actually started
	PauseStart time.Time `db:"pause_start" json:"pause_start"`

	// PauseEnd is when the pause will end (null for indefinite)
	PauseEnd *time.Time `db:"pause_end" json:"pause_end,omitempty"`

	// ResumedAt is when the pause was actually ended (if manually resumed)
	ResumedAt *time.Time `db:"resumed_at" json:"resumed_at,omitempty"`

	// OriginalPeriodStart is the start of the billing period when the pause was created
	OriginalPeriodStart time.Time `db:"original_period_start" json:"original_period_start"`

	// OriginalPeriodEnd is the end of the billing period when the pause was created
	OriginalPeriodEnd time.Time `db:"original_period_end" json:"original_period_end"`

	// Reason is the reason for pausing
	Reason string `db:"reason" json:"reason,omitempty"`

	Metadata types.Metadata `db:"metadata" json:"metadata,omitempty"`

	// EnvironmentID is the environment identifier for the pause
	EnvironmentID string `db:"environment_id" json:"environment_id"`

	types.BaseModel
}

SubscriptionPause represents a pause configuration for a subscription

func SubscriptionPauseFromEnt

func SubscriptionPauseFromEnt(p *ent.SubscriptionPause) *SubscriptionPause

SubscriptionPauseFromEnt converts an ent.SubscriptionPause to a domain SubscriptionPause

func SubscriptionPauseListFromEnt

func SubscriptionPauseListFromEnt(pauses []*ent.SubscriptionPause) []*SubscriptionPause

SubscriptionPauseListFromEnt converts a list of ent.SubscriptionPause to a list of domain SubscriptionPause

type SubscriptionPhase added in v1.0.38

type SubscriptionPhase struct {
	// ID is the unique identifier for the subscription phase
	ID string `db:"id" json:"id"`

	// SubscriptionID is the identifier for the subscription
	SubscriptionID string `db:"subscription_id" json:"subscription_id"`

	// StartDate is when the phase starts
	StartDate time.Time `db:"start_date" json:"start_date"`

	// EndDate is when the phase ends (nil if phase is still active or indefinite)
	EndDate *time.Time `db:"end_date" json:"end_date,omitempty"`

	// Metadata contains additional key-value pairs
	Metadata types.Metadata `db:"metadata" json:"metadata,omitempty"`

	// EnvironmentID is the environment identifier for the phase
	EnvironmentID string `db:"environment_id" json:"environment_id"`

	types.BaseModel
}

SubscriptionPhase represents a phase in a subscription lifecycle

func SubscriptionPhaseFromEnt added in v1.0.38

func SubscriptionPhaseFromEnt(e *ent.SubscriptionPhase) *SubscriptionPhase

SubscriptionPhaseFromEnt converts an ent.SubscriptionPhase to domain SubscriptionPhase

func SubscriptionPhaseListFromEnt added in v1.0.38

func SubscriptionPhaseListFromEnt(phases []*ent.SubscriptionPhase) []*SubscriptionPhase

SubscriptionPhaseListFromEnt converts a list of ent.SubscriptionPhase to a list of domain SubscriptionPhase

func (*SubscriptionPhase) IsActive added in v1.0.38

func (sp *SubscriptionPhase) IsActive(t time.Time) bool

IsActive returns true if the phase is currently active at the given time A phase is active if: - Status is Published - StartDate has passed - EndDate is nil or has not yet passed

type SubscriptionPhaseRepository added in v1.0.38

type SubscriptionPhaseRepository interface {
	// Create creates a new subscription phase
	Create(ctx context.Context, phase *SubscriptionPhase) error

	// CreateBulk creates multiple subscription phases in bulk
	CreateBulk(ctx context.Context, phases []*SubscriptionPhase) error

	// Get retrieves a subscription phase by ID
	Get(ctx context.Context, id string) (*SubscriptionPhase, error)

	// Update updates an existing subscription phase
	Update(ctx context.Context, phase *SubscriptionPhase) error

	// Delete deletes a subscription phase by ID
	Delete(ctx context.Context, id string) error

	// List retrieves subscription phases based on filter
	List(ctx context.Context, filter *types.SubscriptionPhaseFilter) ([]*SubscriptionPhase, error)

	// Count returns the count of subscription phases matching the filter
	Count(ctx context.Context, filter *types.SubscriptionPhaseFilter) (int, error)
}

SubscriprionPhaseRepository defines the interface for subscription phase operations

type SubscriptionProrationPreview added in v1.0.25

type SubscriptionProrationPreview struct {
	// CreditAmount from the current subscription
	CreditAmount string `json:"credit_amount"`

	// ChargeAmount for the new subscription
	ChargeAmount string `json:"charge_amount"`

	// NetAmount is the net change
	NetAmount string `json:"net_amount"`

	// Currency for all amounts
	Currency string `json:"currency"`

	// ProrationDate used for calculations
	ProrationDate time.Time `json:"proration_date"`

	// DaysUsed in current period
	DaysUsed int `json:"days_used"`

	// DaysRemaining in current period
	DaysRemaining int `json:"days_remaining"`
}

SubscriptionProrationPreview contains proration calculation details

Jump to

Keyboard shortcuts

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