pricing

package
v0.0.0-...-4ba1516 Latest Latest
Warning

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

Go to latest
Published: Dec 16, 2024 License: Apache-2.0 Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const BillingWarningPeriod = 7 * 24 * time.Hour

Variables

View Source
var ProductPrices = map[backend.PlanType]map[model.PricingProductType]ProductPricing{
	backend.PlanTypeGraduated: {
		model.PricingProductTypeSessions: {
			Included: 500,
			Items: []GraduatedPriceItem{{
				Rate:  20. / 1_000,
				Count: 15_000,
			}, {
				Rate:  15. / 1_000,
				Count: 50_000,
			}, {
				Rate:  12. / 1_000,
				Count: 150_000,
			}, {
				Rate:  6.5 / 1_000,
				Count: 500_000,
			}, {
				Rate:  3.5 / 1_000,
				Count: 1_000_000,
			}, {
				Rate: 2.5 / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 1_000,
			Items: []GraduatedPriceItem{{
				Rate:  2. / 1_000,
				Count: 50_000,
			}, {
				Rate:  0.5 / 1_000,
				Count: 100_000,
			}, {
				Rate:  0.25 / 1_000,
				Count: 200_000,
			}, {
				Rate:  0.2 / 1_000,
				Count: 500_000,
			}, {
				Rate:  0.1 / 1_000,
				Count: 5_000_000,
			}, {
				Rate: 0.05 / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 1_000_000,
			Items: []GraduatedPriceItem{{
				Rate:  2.5 / 1_000_000,
				Count: 1_000_000,
			}, {
				Rate:  2. / 1_000_000,
				Count: 10_000_000,
			}, {
				Rate:  1.5 / 1_000_000,
				Count: 100_000_000,
			}, {
				Rate:  1. / 1_000_000,
				Count: 1_000_000_000,
			}, {
				Rate: 0.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 25_000_000,
			Items: []GraduatedPriceItem{{
				Rate:  2.5 / 1_000_000,
				Count: 1_000_000,
			}, {
				Rate:  2. / 1_000_000,
				Count: 10_000_000,
			}, {
				Rate:  1.5 / 1_000_000,
				Count: 100_000_000,
			}, {
				Rate:  1. / 1_000_000,
				Count: 1_000_000_000,
			}, {
				Rate: 0.5 / 1_000_000,
			}},
		},
	},
	backend.PlanTypeUsageBased: {
		model.PricingProductTypeSessions: {
			Included: 500,
			Items: []GraduatedPriceItem{{
				Rate: 20. / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 1_000,
			Items: []GraduatedPriceItem{{
				Rate: 2. / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 1_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 1_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
	},
	backend.PlanTypeLite: {
		model.PricingProductTypeSessions: {
			Included: 2_000,
			Items: []GraduatedPriceItem{{
				Rate: 5. / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 4_000,
			Items: []GraduatedPriceItem{{
				Rate: 0.2 / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 4_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 4_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
	},
	backend.PlanTypeBasic: {
		model.PricingProductTypeSessions: {
			Included: 10_000,
			Items: []GraduatedPriceItem{{
				Rate: 5. / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 20_000,
			Items: []GraduatedPriceItem{{
				Rate: 0.2 / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 20_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 20_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
	},
	backend.PlanTypeStartup: {
		model.PricingProductTypeSessions: {
			Included: 80_000,
			Items: []GraduatedPriceItem{{
				Rate: 5. / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 160_000,
			Items: []GraduatedPriceItem{{
				Rate: 0.2 / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 160_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 160_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
	},
	backend.PlanTypeEnterprise: {
		model.PricingProductTypeSessions: {
			Included: 300_000,
			Items: []GraduatedPriceItem{{
				Rate: 5. / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 600_000,
			Items: []GraduatedPriceItem{{
				Rate: 0.2 / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 600_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 600_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
	},
	backend.PlanTypeFree: {
		model.PricingProductTypeSessions: {
			Included: 500,
			Items: []GraduatedPriceItem{{
				Rate: 5. / 1_000,
			}},
		},
		model.PricingProductTypeErrors: {
			Included: 1_000,
			Items: []GraduatedPriceItem{{
				Rate: 0.2 / 1_000,
			}},
		},
		model.PricingProductTypeLogs: {
			Included: 1_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
		model.PricingProductTypeTraces: {
			Included: 25_000_000,
			Items: []GraduatedPriceItem{{
				Rate: 1.5 / 1_000_000,
			}},
		},
	},
}
View Source
var ProductTypeToQuotaConfig = map[model.PricingProductType]overageConfig{
	model.PricingProductTypeSessions: {
		func(w *model.Workspace) *int { return w.SessionsMaxCents },
		GetWorkspaceSessionsMeter,
		func(w *model.Workspace) backend.RetentionPeriod {
			if w.RetentionPeriod == nil {
				return backend.RetentionPeriodThreeMonths
			}
			return *w.RetentionPeriod
		},
		func(w *model.Workspace) int64 {
			limit := IncludedAmount(backend.PlanType(w.PlanTier), model.PricingProductTypeSessions)
			if w.MonthlySessionLimit != nil {
				limit = int64(*w.MonthlySessionLimit)
			}
			return limit
		},
		email.BillingSessionOverage,
		1000,
	},
	model.PricingProductTypeErrors: {
		func(w *model.Workspace) *int { return w.ErrorsMaxCents },
		GetWorkspaceErrorsMeter,
		func(w *model.Workspace) backend.RetentionPeriod {
			if w.ErrorsRetentionPeriod == nil {
				return backend.RetentionPeriodThreeMonths
			}
			return *w.ErrorsRetentionPeriod
		},
		func(w *model.Workspace) int64 {
			limit := IncludedAmount(backend.PlanType(w.PlanTier), model.PricingProductTypeErrors)
			if w.MonthlyErrorsLimit != nil {
				limit = int64(*w.MonthlyErrorsLimit)
			}
			return limit
		},
		email.BillingErrorsOverage,
		1000,
	},
	model.PricingProductTypeLogs: {
		func(w *model.Workspace) *int { return w.LogsMaxCents },
		GetWorkspaceLogsMeter,
		func(w *model.Workspace) backend.RetentionPeriod {
			if w.LogsRetentionPeriod == nil {
				return backend.RetentionPeriodThirtyDays
			}
			return *w.LogsRetentionPeriod
		},
		func(w *model.Workspace) int64 {
			limit := IncludedAmount(backend.PlanType(w.PlanTier), model.PricingProductTypeLogs)
			if w.MonthlyLogsLimit != nil {
				limit = int64(*w.MonthlyLogsLimit)
			}
			return limit
		},
		email.BillingLogsOverage,
		1_000_000,
	},
	model.PricingProductTypeTraces: {
		func(w *model.Workspace) *int { return w.TracesMaxCents },
		GetWorkspaceTracesMeter,
		func(w *model.Workspace) backend.RetentionPeriod {
			if w.TracesRetentionPeriod == nil {
				return backend.RetentionPeriodThirtyDays
			}
			return *w.TracesRetentionPeriod
		},
		func(w *model.Workspace) int64 {
			limit := IncludedAmount(backend.PlanType(w.PlanTier), model.PricingProductTypeTraces)
			if w.MonthlyTracesLimit != nil {
				limit = int64(*w.MonthlyTracesLimit)
			}
			return limit
		},
		email.BillingTracesOverage,
		1_000_000,
	},
}

Functions

func FillProducts

func FillProducts(pricingClient *Client, subscriptions []*stripe.Subscription)

Products are too nested in the Subscription model to be added through the API This method calls the Stripe ListProducts API and replaces each product id in the subscriptions with the full product data.

func FromPriceID

func FromPriceID(priceID string) backend.PlanType

func GetBaseLookupKey

func GetBaseLookupKey(productTier backend.PlanType, interval model.PricingSubscriptionInterval, unlimitedMembers bool, retentionPeriod backend.RetentionPeriod) (result string)

Returns a Stripe lookup key which maps to a single Stripe Price

func GetErrors7DayAverage

func GetErrors7DayAverage(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, workspace *model.Workspace) (float64, error)

func GetLimitAmount

func GetLimitAmount(limitCostCents *int, productType model.PricingProductType, planType backend.PlanType, retentionPeriod backend.RetentionPeriod) *int64

func GetLogs7DayAverage

func GetLogs7DayAverage(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, workspace *model.Workspace) (float64, error)

func GetOverageKey

func GetOverageKey(productType model.PricingProductType, retentionPeriod backend.RetentionPeriod, planType backend.PlanType) string

func GetProductMetadata

Returns the Highlight model.PricingProductType, Tier, and Interval for the Stripe Price

func GetSessions7DayAverage

func GetSessions7DayAverage(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, workspace *model.Workspace) (float64, error)

func GetStripePrices

func GetStripePrices(pricingClient *Client, workspace *model.Workspace, productTier backend.PlanType, interval model.PricingSubscriptionInterval, unlimitedMembers bool, sessionsRetention *backend.RetentionPeriod, errorsRetention *backend.RetentionPeriod) (map[model.PricingProductType]*stripe.Price, error)

Returns the Stripe Prices for the associated tier and interval

func GetTraces7DayAverage

func GetTraces7DayAverage(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, workspace *model.Workspace) (float64, error)

func GetWorkspaceErrorsMeter

func GetWorkspaceErrorsMeter(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, redisClient *redis.Client, workspace *model.Workspace) (int64, error)

func GetWorkspaceLogsMeter

func GetWorkspaceLogsMeter(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, redis *redis.Client, workspace *model.Workspace) (int64, error)

func GetWorkspaceSessionsMeter

func GetWorkspaceSessionsMeter(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, redisClient *redis.Client, workspace *model.Workspace) (int64, error)

func GetWorkspaceTracesMeter

func GetWorkspaceTracesMeter(ctx context.Context, DB *gorm.DB, ccClient *clickhouse.Client, redis *redis.Client, workspace *model.Workspace) (int64, error)

func IncludedAmount

func IncludedAmount(planType backend.PlanType, productType model.PricingProductType) int64

func MustUpgradeForClearbit

func MustUpgradeForClearbit(tier string) bool

MustUpgradeForClearbit shows when tier is insufficient for Clearbit.

func ProductToBasePriceCents

func ProductToBasePriceCents(productType model.PricingProductType, planType backend.PlanType, meter int64) float64

func RetentionMultiplier

func RetentionMultiplier(retentionPeriod backend.RetentionPeriod) float64

func TypeToMemberLimit

func TypeToMemberLimit(planType backend.PlanType, unlimitedMembers bool) *int64

Types

type AWSCustomerUsage

type AWSCustomerUsage struct {
	Customer *model.AWSMarketplaceCustomer
	Usage    WorkspaceOverages
}

type AWSCustomerUsages

type AWSCustomerUsages = map[int]AWSCustomerUsage

type AWSMPProductCode

type AWSMPProductCode = string
const AWSMPProductCodeUsageBased AWSMPProductCode = "24dmmonsy3i8lrvjcct8mq07y"

type BillingPortalSessions

type BillingPortalSessions interface {
	New(session *stripe.BillingPortalSessionParams) (*stripe.BillingPortalSession, error)
}

type CheckoutSessions

type CheckoutSessions interface {
	New(session *stripe.CheckoutSessionParams) (*stripe.CheckoutSession, error)
}

type Client

type Client struct {
	BillingPortalSessions BillingPortalSessions
	CheckoutSessions      CheckoutSessions
	Customers             Customers
	Invoices              Invoices
	InvoiceItems          InvoiceItems
	PaymentMethods        PaymentMethods
	Prices                Prices
	Products              Products
	Subscriptions         Subscriptions
	SubscriptionItems     SubscriptionItems
	UsageRecords          UsageRecords
}

func New

func New(client *client.API) *Client

func NewNoopClient

func NewNoopClient() *Client

type Customers

type Customers interface {
	New(*stripe.CustomerParams) (*stripe.Customer, error)
	Get(string, *stripe.CustomerParams) (*stripe.Customer, error)
}

type GraduatedPriceItem

type GraduatedPriceItem struct {
	Rate  float64
	Count int64
}

type InvoiceItems

type InvoiceItems interface {
	New(session *stripe.InvoiceItemParams) (*stripe.InvoiceItem, error)
	Update(string, *stripe.InvoiceItemParams) (*stripe.InvoiceItem, error)
}

type Invoices

type Invoices interface {
	Get(string, *stripe.InvoiceParams) (*stripe.Invoice, error)
	List(*stripe.InvoiceListParams) *invoice.Iter
	Upcoming(*stripe.InvoiceUpcomingParams) (*stripe.Invoice, error)
	UpcomingLines(*stripe.InvoiceUpcomingLinesParams) *invoice.LineItemIter
}

type PaymentIssueType

type PaymentIssueType = string
const PaymentIssueTypeCardCheckFail PaymentIssueType = "payment_method_check_failed"
const PaymentIssueTypeInvoiceOpenAttempted PaymentIssueType = "invoice_open_attempted"
const PaymentIssueTypeInvoiceUncollectible PaymentIssueType = "invoice_uncollectible"
const PaymentIssueTypeNoPaymentMethod PaymentIssueType = "no_payment_method"
const PaymentIssueTypeSubscriptionDue PaymentIssueType = "subscription_due"

type PaymentMethods

type PaymentMethods interface {
	List(params *stripe.PaymentMethodListParams) *paymentmethod.Iter
}

type Prices

type Prices interface {
	Get(string, *stripe.PriceParams) (*stripe.Price, error)
	List(*stripe.PriceListParams) *price.Iter
}

type ProductPricing

type ProductPricing struct {
	Included int64
	Items    []GraduatedPriceItem
}

type Products

type Products interface {
	List(params *stripe.ProductListParams) *product.Iter
}

type SubscriptionItems

type SubscriptionItems interface {
	New(*stripe.SubscriptionItemParams) (*stripe.SubscriptionItem, error)
}

type Subscriptions

type Subscriptions interface {
	Update(string, *stripe.SubscriptionParams) (*stripe.Subscription, error)
	List(params *stripe.SubscriptionListParams) *subscription.Iter
}

type UsageRecords

type UsageRecords interface {
	New(*stripe.UsageRecordParams) (*stripe.UsageRecord, error)
}

type Worker

type Worker struct {
	// contains filtered or unexported fields
}

func NewWorker

func NewWorker(db *gorm.DB, redis *redis.Client, store *store.Store, ccClient *clickhouse.Client, pricingClient *Client, awsmpClient *marketplacemetering.Client, mailClient *sendgrid.Client) *Worker

func (*Worker) AddOrUpdateOverageItem

func (w *Worker) AddOrUpdateOverageItem(newPrice *stripe.Price, invoiceLine *stripe.InvoiceLineItem, customer *stripe.Customer, subscription *stripe.Subscription, overage int64) error

func (*Worker) CalculateOverages

func (w *Worker) CalculateOverages(ctx context.Context, workspaceID int) (WorkspaceOverages, error)

func (*Worker) GetBillingIssue

func (w *Worker) GetBillingIssue(ctx context.Context, workspace *model.Workspace, customer *stripe.Customer, subscription *stripe.Subscription, invoice *stripe.Invoice) (PaymentIssueType, error)

func (*Worker) ProcessBillingIssue

func (w *Worker) ProcessBillingIssue(ctx context.Context, workspace *model.Workspace, status PaymentIssueType)

func (*Worker) ReportAWSMPUsages

func (w *Worker) ReportAWSMPUsages(ctx context.Context, usages AWSCustomerUsages)

func (*Worker) ReportAllUsage

func (w *Worker) ReportAllUsage(ctx context.Context)

func (*Worker) ReportStripeUsageForWorkspace

func (w *Worker) ReportStripeUsageForWorkspace(ctx context.Context, workspaceID int) error

type WorkspaceOverages

type WorkspaceOverages = map[model.PricingProductType]int64

Jump to

Keyboard shortcuts

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