billing

package
v1.0.0-beta.185 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2024 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EntityCustomerOverride = "BillingCustomerOverride"
	EntityCustomer         = "Customer"
	EntityDefaultProfile   = "DefaultBillingProfile"
)

Variables

View Source
var (
	ErrDefaultProfileAlreadyExists  = goblvalidation.NewError("default_profile_exists", "default profile already exists")
	ErrDefaultProfileNotFound       = goblvalidation.NewError("default_profile_not_found", "default profile not found")
	ErrProfileNotFound              = goblvalidation.NewError("profile_not_found", "profile not found")
	ErrProfileAlreadyDeleted        = goblvalidation.NewError("profile_already_deleted", "profile already deleted")
	ErrProfileConflict              = goblvalidation.NewError("profile_update_conflict", "profile has been already updated")
	ErrProfileReferencedByOverrides = goblvalidation.NewError("profile_referenced", "profile is referenced by customer overrides")
	ErrProfileTaxTypeChange         = goblvalidation.NewError("profile_tax_provider_change_forbidden", "profile tax type change is not allowed")
	ErrProfileInvoicingTypeChange   = goblvalidation.NewError("profile_invoicing_provider_change_forbidden", "profile invoicing type change is not allowed")
	ErrProfilePaymentTypeChange     = goblvalidation.NewError("profile_payment_provider_change_forbidden", "profile payment type change is not allowed")

	ErrCustomerOverrideNotFound       = goblvalidation.NewError("customer_override_not_found", "customer override not found")
	ErrCustomerOverrideConflict       = goblvalidation.NewError("customer_override_conflict", "customer override has been already updated conflict")
	ErrCustomerOverrideAlreadyDeleted = goblvalidation.NewError("customer_override_deleted", "customer override already deleted")
	ErrCustomerNotFound               = goblvalidation.NewError("customer_not_found", "customer not found")
)
View Source
var InvoiceImmutableStatuses = []InvoiceStatus{
	InvoiceStatusIssued,
	InvoiceStatusDeleted,
}

InvoiceImmutableStatuses are the statuses that forbid any changes to the invoice.

Functions

func WithTx

func WithTx[T any](ctx context.Context, repo Adapter, fn func(ctx context.Context, repo TxAdapter) (T, error)) (resp T, err error)

func WithTxNoValue

func WithTxNoValue(ctx context.Context, repo Adapter, fn func(ctx context.Context, repo TxAdapter) error) error

Types

type AlignmentKind

type AlignmentKind string

AlignmentKind specifies what governs when an invoice is issued

const (
	// AlignmentKindSubscription specifies that the invoice is issued based on the subscription period (
	// e.g. whenever a due line item is added, it will trigger an invoice generation after the collection period)
	AlignmentKindSubscription AlignmentKind = "subscription"
)

func (AlignmentKind) Values

func (k AlignmentKind) Values() []string

type CollectionConfig

type CollectionConfig struct {
	Alignment            AlignmentKind `json:"alignment"`
	ItemCollectionPeriod time.Duration `json:"itemCollectionPeriod,omitempty"`
}

CollectionConfig groups fields related to item collection.

func (*CollectionConfig) Validate

func (c *CollectionConfig) Validate() error

type CollectionMethod

type CollectionMethod string
const (
	// CollectionMethodChargeAutomatically charges the customer automatically based on previously saved card data
	CollectionMethodChargeAutomatically CollectionMethod = "charge_automatically"
	// CollectionMethodSendInvoice sends an invoice to the customer along with the payment instructions/links
	CollectionMethodSendInvoice CollectionMethod = "send_invoice"
)

func (CollectionMethod) Values

func (c CollectionMethod) Values() []string

type CollectionOverrideConfig

type CollectionOverrideConfig struct {
	Alignment            *AlignmentKind `json:"alignment,omitempty"`
	ItemCollectionPeriod *time.Duration `json:"itemCollectionPeriod,omitempty"`
}

func (*CollectionOverrideConfig) Validate

func (c *CollectionOverrideConfig) Validate() error

type CreateCustomerOverrideInput

type CreateCustomerOverrideInput struct {
	Namespace string `json:"namespace"`

	CustomerID string `json:"customerID"`
	ProfileID  string `json:"billingProfile,omitempty"`

	Collection CollectionOverrideConfig `json:"collection"`
	Invoicing  InvoicingOverrideConfig  `json:"invoicing"`
	Payment    PaymentOverrideConfig    `json:"payment"`
}

func (CreateCustomerOverrideInput) Validate

func (c CreateCustomerOverrideInput) Validate() error

type CreateInvoiceItemsInput

type CreateInvoiceItemsInput struct {
	InvoiceID *string
	Namespace string
	Items     []InvoiceItem
}

func (CreateInvoiceItemsInput) Validate

func (c CreateInvoiceItemsInput) Validate() error

type CreateProfileInput

type CreateProfileInput Profile

func (CreateProfileInput) Validate

func (i CreateProfileInput) Validate() error

func (CreateProfileInput) WithDefaults

func (i CreateProfileInput) WithDefaults() CreateProfileInput

WithDefaults sets the default values for the profile input if not provided, this is useful as the object is pretty big and we don't want to set all the fields

type CustomerMetadata

type CustomerMetadata struct {
	Name string `json:"name"`
}

type CustomerOverride

type CustomerOverride struct {
	Namespace string `json:"namespace"`
	ID        string `json:"id"`

	CreatedAt time.Time  `json:"createdAt"`
	UpdatedAt time.Time  `json:"updatedAt"`
	DeletedAt *time.Time `json:"deletedAt,omitempty"`

	CustomerID string   `json:"customerID"`
	Profile    *Profile `json:"billingProfile,omitempty"`

	Collection CollectionOverrideConfig `json:"collection"`
	Invoicing  InvoicingOverrideConfig  `json:"invoicing"`
	Payment    PaymentOverrideConfig    `json:"payment"`
}

func (CustomerOverride) Validate

func (c CustomerOverride) Validate() error

type CustomerOverrideAdapter

type CustomerOverrideAdapter interface {
	CreateCustomerOverride(ctx context.Context, input CreateCustomerOverrideInput) (*CustomerOverride, error)
	GetCustomerOverride(ctx context.Context, input GetCustomerOverrideAdapterInput) (*CustomerOverride, error)
	UpdateCustomerOverride(ctx context.Context, input UpdateCustomerOverrideAdapterInput) (*CustomerOverride, error)
	DeleteCustomerOverride(ctx context.Context, input DeleteCustomerOverrideInput) error

	GetCustomerOverrideReferencingProfile(ctx context.Context, input HasCustomerOverrideReferencingProfileAdapterInput) ([]customer.CustomerID, error)
}

type CustomerOverrideService

type CustomerOverrideService interface {
	CreateCustomerOverride(ctx context.Context, input CreateCustomerOverrideInput) (*CustomerOverride, error)
	UpdateCustomerOverride(ctx context.Context, input UpdateCustomerOverrideInput) (*CustomerOverride, error)
	GetCustomerOverride(ctx context.Context, input GetCustomerOverrideInput) (*CustomerOverride, error)
	DeleteCustomerOverride(ctx context.Context, input DeleteCustomerOverrideInput) error

	GetProfileWithCustomerOverride(ctx context.Context, input GetProfileWithCustomerOverrideInput) (*ProfileWithCustomerDetails, error)
}

type DeleteCustomerOverrideInput

type DeleteCustomerOverrideInput namespacedCustomerID

func (DeleteCustomerOverrideInput) Validate

func (d DeleteCustomerOverrideInput) Validate() error

type DeleteProfileInput

type DeleteProfileInput genericNamespaceID

func (DeleteProfileInput) Validate

func (i DeleteProfileInput) Validate() error

type GetCustomerOverrideAdapterInput

type GetCustomerOverrideAdapterInput struct {
	Namespace  string
	CustomerID string

	IncludeDeleted bool
}

func (GetCustomerOverrideAdapterInput) Validate

type GetCustomerOverrideInput

type GetCustomerOverrideInput namespacedCustomerID

func (GetCustomerOverrideInput) Validate

func (g GetCustomerOverrideInput) Validate() error

type GetDefaultProfileInput

type GetDefaultProfileInput struct {
	Namespace string
}

func (GetDefaultProfileInput) Validate

func (i GetDefaultProfileInput) Validate() error

type GetProfileInput

type GetProfileInput genericNamespaceID

func (GetProfileInput) Validate

func (i GetProfileInput) Validate() error

type GetProfileWithCustomerOverrideInput

type GetProfileWithCustomerOverrideInput namespacedCustomerID

func (GetProfileWithCustomerOverrideInput) Validate

type GranularityResolution

type GranularityResolution string
const (
	// GranularityResolutionDay provides line items for metered data per day
	GranularityResolutionDay GranularityResolution = "day"
	// GranularityResolutionPeriod provides one line item per period
	GranularityResolutionPeriod GranularityResolution = "period"
)

func (GranularityResolution) Values

func (r GranularityResolution) Values() []string

type HasCustomerOverrideReferencingProfileAdapterInput

type HasCustomerOverrideReferencingProfileAdapterInput genericNamespaceID

func (HasCustomerOverrideReferencingProfileAdapterInput) Validate

type Invoice

type Invoice struct {
	Namespace string `json:"namespace"`
	ID        string `json:"id"`

	InvoiceNumber InvoiceNumber `json:"invoiceNumber"`

	Type InvoiceType `json:"type"`

	Metadata map[string]string `json:"metadata"`

	Currency currencyx.Code    `json:"currency,omitempty"`
	Timezone timezone.Timezone `json:"timezone,omitempty"`
	Status   InvoiceStatus     `json:"status"`

	PeriodStart time.Time `json:"periodStart,omitempty"`
	PeriodEnd   time.Time `json:"periodEnd,omitempty"`

	DueDate *time.Time `json:"dueDate,omitempty"`

	CreatedAt time.Time  `json:"createdAt"`
	UpdatedAt time.Time  `json:"updatedAt"`
	VoidedAt  *time.Time `json:"voidedAt,omitempty"`
	IssuedAt  *time.Time `json:"issuedAt,omitempty"`
	DeletedAt *time.Time `json:"deletedAt,omitempty"`

	// Customer is either a snapshot of the contact information of the customer at the time of invoice being sent
	// or the data from the customer entity (draft state)
	// This is required so that we are not modifying the invoice after it has been sent to the customer.
	Profile  Profile         `json:"profile"`
	Customer InvoiceCustomer `json:"customer"`

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

type InvoiceCustomer

type InvoiceCustomer customer.Customer

func (*InvoiceCustomer) Validate

func (i *InvoiceCustomer) Validate() error

type InvoiceItem

type InvoiceItem struct {
	Namespace string `json:"namespace"`
	ID        string `json:"id"`

	CreatedAt time.Time  `json:"createdAt"`
	UpdatedAt time.Time  `json:"updatedAt"`
	DeletedAt *time.Time `json:"deletedAt,omitempty"`

	Metadata   map[string]string `json:"metadata"`
	InvoiceID  *string           `json:"invoiceID,omitempty"`
	CustomerID string            `json:"customer"`

	// Lifecycle
	PeriodStart time.Time `json:"periodStart"`
	PeriodEnd   time.Time `json:"periodEnd"`
	InvoiceAt   time.Time `json:"invoiceAt"`

	// Item details
	Name      string                 `json:"name"`
	Type      InvoiceItemType        `json:"type"`
	Quantity  *alpacadecimal.Decimal `json:"quantity"`
	UnitPrice alpacadecimal.Decimal  `json:"unitPrice"`
	Currency  currencyx.Code         `json:"currency"`

	TaxCodeOverride TaxOverrides `json:"taxCodeOverride"`
}

func (InvoiceItem) Validate

func (i InvoiceItem) Validate() error

type InvoiceItemAdapter

type InvoiceItemAdapter interface {
	CreateInvoiceItems(ctx context.Context, input CreateInvoiceItemsInput) ([]InvoiceItem, error)
	GetPendingInvoiceItems(ctx context.Context, customerID customer.CustomerID) ([]InvoiceItem, error)
}

type InvoiceItemService

type InvoiceItemService interface {
	CreateInvoiceItems(ctx context.Context, input CreateInvoiceItemsInput) ([]InvoiceItem, error)
}

type InvoiceItemType

type InvoiceItemType string
const (
	// InvoiceItemTypeStatic is a static item that is not calculated based on usage.
	InvoiceItemTypeStatic InvoiceItemType = "static"
	// InvoiceItemTypeUsage is an item that is calculated based on usage.
	InvoiceItemTypeUsage InvoiceItemType = "usage"
)

func (InvoiceItemType) Values

func (InvoiceItemType) Values() []string

type InvoiceNumber

type InvoiceNumber struct {
	Series string `json:"series"`
	Code   string `json:"code"`
}

type InvoiceService

type InvoiceService interface {
	// GetPendingInvoiceItems returns all pending invoice items for a customer
	// The call can return any number of invoices based on multiple factors:
	// - The customer has multiple currencies (e.g. USD and EUR)
	// - [later] The provider can also mandate separate invoices if needed
	GetPendingInvoiceItems(ctx context.Context, customerID customer.CustomerID) ([]InvoiceWithValidation, error)
}

type InvoiceStatus

type InvoiceStatus string
const (
	// InvoiceStatusPendingCreation is the status of an invoice summarizing the pending items.
	InvoiceStatusPendingCreation InvoiceStatus = "pending_creation"
	// InvoiceStatusCreated is the status of an invoice that has been created.
	InvoiceStatusCreated InvoiceStatus = "created"
	// InvoiceStatusDraft is the status of an invoice that is in draft both on OpenMeter and the provider side.
	InvoiceStatusDraft InvoiceStatus = "draft"
	// InvoiceStatusDraftSync is the status of an invoice that is being synced with the provider.
	InvoiceStatusDraftSync InvoiceStatus = "draft_sync"
	// InvoiceStatusDraftSyncFailed is the status of an invoice that failed to sync with the provider.
	InvoiceStatusDraftSyncFailed InvoiceStatus = "draft_sync_failed"
	// InvoiceStatusIssuing is the status of an invoice that is being issued.
	InvoiceStatusIssuing InvoiceStatus = "issuing"
	// InvoiceStatusIssued is the status of an invoice that has been issued both on OpenMeter and provider side.
	InvoiceStatusIssued InvoiceStatus = "issued"
	// InvoiceStatusIssuingFailed is the status of an invoice that failed to issue on the provider or OpenMeter side.
	InvoiceStatusIssuingFailed InvoiceStatus = "issuing_failed"
	// InvoiceStatusManualApprovalNeeded is the status of an invoice that needs manual approval. (due to AutoApprove is disabled)
	InvoiceStatusManualApprovalNeeded InvoiceStatus = "manual_approval_needed"
	// InvoiceStatusDeleted is the status of an invoice that has been deleted (e.g. removed from the database before being issued).
	InvoiceStatusDeleted InvoiceStatus = "deleted"
)

func (InvoiceStatus) Values

func (s InvoiceStatus) Values() []string

type InvoiceType

type InvoiceType cbc.Key
const (
	InvoiceTypeStandard   InvoiceType = InvoiceType(bill.InvoiceTypeStandard)
	InvoiceTypeCreditNote InvoiceType = InvoiceType(bill.InvoiceTypeCreditNote)
)

func (InvoiceType) CBCKey

func (t InvoiceType) CBCKey() cbc.Key

func (InvoiceType) Values

func (t InvoiceType) Values() []string

type InvoiceWithValidation

type InvoiceWithValidation struct {
	Invoice          *Invoice
	ValidationErrors []error
}

type InvoicingConfig

type InvoicingConfig struct {
	AutoAdvance bool          `json:"autoAdvance"`
	DraftPeriod time.Duration `json:"draftPeriod,omitempty"`
	DueAfter    time.Duration `json:"dueAfter"`

	ItemResolution GranularityResolution `json:"itemResolution"`
	ItemPerSubject bool                  `json:"itemPerSubject"`
}

InvoiceConfig groups fields related to invoice settings.

func (*InvoicingConfig) Validate

func (c *InvoicingConfig) Validate() error

type InvoicingOverrideConfig

type InvoicingOverrideConfig struct {
	AutoAdvance *bool          `json:"autoAdvance,omitempty"`
	DraftPeriod *time.Duration `json:"draftPeriod,omitempty"`
	DueAfter    *time.Duration `json:"dueAfter,omitempty"`

	ItemResolution *GranularityResolution `json:"itemResolution,omitempty"`
	ItemPerSubject *bool                  `json:"itemPerSubject,omitempty"`
}

func (*InvoicingOverrideConfig) Validate

func (c *InvoicingOverrideConfig) Validate() error

type NotFoundError

type NotFoundError struct {
	ID     string
	Entity string
	Err    error
}

func (NotFoundError) Error

func (e NotFoundError) Error() string

func (NotFoundError) Unwrap

func (e NotFoundError) Unwrap() error

type PaymentConfig

type PaymentConfig struct {
	CollectionMethod CollectionMethod
}

func (*PaymentConfig) Validate

func (c *PaymentConfig) Validate() error

type PaymentOverrideConfig

type PaymentOverrideConfig struct {
	CollectionMethod *CollectionMethod
}

func (*PaymentOverrideConfig) Validate

func (c *PaymentOverrideConfig) Validate() error

type Profile

type Profile struct {
	ID        string `json:"id"`
	Namespace string `json:"namespace"`

	CreatedAt time.Time  `json:"createdAt"`
	UpdatedAt time.Time  `json:"updatedAt"`
	DeletedAt *time.Time `json:"deletedAt"`

	TaxConfiguration       provider.TaxConfiguration       `json:"tax"`
	InvoicingConfiguration provider.InvoicingConfiguration `json:"invoicing"`
	PaymentConfiguration   provider.PaymentConfiguration   `json:"payment"`

	WorkflowConfig WorkflowConfig `json:"workflow"`

	Supplier SupplierContact `json:"supplier"`

	Default bool `json:"default"`
}

func (Profile) Merge

func (p Profile) Merge(o *CustomerOverride) Profile

func (Profile) Validate

func (p Profile) Validate() error

type ProfileAdapter

type ProfileAdapter interface {
	CreateProfile(ctx context.Context, input CreateProfileInput) (*Profile, error)
	GetProfile(ctx context.Context, input GetProfileInput) (*Profile, error)
	GetDefaultProfile(ctx context.Context, input GetDefaultProfileInput) (*Profile, error)
	DeleteProfile(ctx context.Context, input DeleteProfileInput) error
	UpdateProfile(ctx context.Context, input UpdateProfileAdapterInput) (*Profile, error)
}

type ProfileService

type ProfileService interface {
	CreateProfile(ctx context.Context, param CreateProfileInput) (*Profile, error)
	GetDefaultProfile(ctx context.Context, input GetDefaultProfileInput) (*Profile, error)
	GetProfile(ctx context.Context, input GetProfileInput) (*Profile, error)
	DeleteProfile(ctx context.Context, input DeleteProfileInput) error
	UpdateProfile(ctx context.Context, input UpdateProfileInput) (*Profile, error)
}

type ProfileWithCustomerDetails

type ProfileWithCustomerDetails struct {
	Profile  Profile           `json:"profile"`
	Customer customer.Customer `json:"customer"`
}

func (ProfileWithCustomerDetails) Validate

func (p ProfileWithCustomerDetails) Validate() error

type StripeTaxCode

type StripeTaxCode string

type StripeTaxOverride

type StripeTaxOverride struct {
	TaxCode StripeTaxCode `json:"taxCode,omitempty"`
}

type SupplierContact

type SupplierContact struct {
	Name    string         `json:"name"`
	Address models.Address `json:"address"`
}

func (SupplierContact) Validate

func (c SupplierContact) Validate() error

Validate checks if the supplier contact is valid for invoice generation (e.g. Country is required)

type TaxOverrides

type TaxOverrides struct {
	Stripe *StripeTaxOverride `json:"stripe,omitempty"`
}

type TxAdapter

type TxAdapter interface {
	ProfileAdapter
	CustomerOverrideAdapter
	InvoiceItemAdapter

	Commit() error
	Rollback() error
}

type UpdateAfterDeleteError

type UpdateAfterDeleteError genericError

func (UpdateAfterDeleteError) Error

func (e UpdateAfterDeleteError) Error() string

func (UpdateAfterDeleteError) Unwrap

func (e UpdateAfterDeleteError) Unwrap() error

type UpdateCustomerOverrideAdapterInput

type UpdateCustomerOverrideAdapterInput struct {
	UpdateCustomerOverrideInput

	ResetDeletedAt bool
}

func (UpdateCustomerOverrideAdapterInput) Validate

type UpdateCustomerOverrideInput

type UpdateCustomerOverrideInput struct {
	Namespace  string `json:"namespace"`
	CustomerID string `json:"customerID"`

	UpdatedAt time.Time `json:"updatedAt"`

	ProfileID string `json:"billingProfileID"`

	Collection CollectionOverrideConfig `json:"collection"`
	Invoicing  InvoicingOverrideConfig  `json:"invoicing"`
	Payment    PaymentOverrideConfig    `json:"payment"`
}

func (UpdateCustomerOverrideInput) Validate

func (u UpdateCustomerOverrideInput) Validate() error

type UpdateProfileAdapterInput

type UpdateProfileAdapterInput struct {
	TargetState      Profile
	WorkflowConfigID string
}

func (UpdateProfileAdapterInput) Validate

func (i UpdateProfileAdapterInput) Validate() error

type UpdateProfileInput

type UpdateProfileInput Profile

func (UpdateProfileInput) Validate

func (i UpdateProfileInput) Validate() error

type ValidationError

type ValidationError genericError

func (ValidationError) Error

func (e ValidationError) Error() string

func (ValidationError) Unwrap

func (e ValidationError) Unwrap() error

type WorkflowConfig

type WorkflowConfig struct {
	ID string `json:"id"`

	CreatedAt time.Time  `json:"createdAt"`
	UpdatedAt time.Time  `json:"updatedAt"`
	DeletedAt *time.Time `json:"deletedAt"`

	Timezone *timezone.Timezone `json:"timezone,omitempty"`

	Collection CollectionConfig `json:"collection"`
	Invoicing  InvoicingConfig  `json:"invoicing"`
	Payment    PaymentConfig    `json:"payment"`
}

func (WorkflowConfig) Validate

func (c WorkflowConfig) Validate() error

Directories

Path Synopsis
api

Jump to

Keyboard shortcuts

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