Documentation
¶
Index ¶
- Variables
- func Query(db *datastore.Datastore) datastore.Query
- type BillingType
- type Status
- type Subscription
- func (s *Subscription) Load(ps []datastore.Property) (err error)
- func (s Subscription) NumberFromId() (i int, err error)
- func (s Subscription) PeriodsRemaining() int
- func (s *Subscription) Save() (ps []datastore.Property, err error)
- func (s Subscription) TrialPeriodsRemaining() int
- func (s *Subscription) Validator() *val.Validator
Constants ¶
This section is empty.
Variables ¶
var IgnoreFieldMismatch = datastore.IgnoreFieldMismatch
Functions ¶
Types ¶
type BillingType ¶
type BillingType string
const ( Charge BillingType = "charge_automatically" Invoice BillingType = "send_invoice" )
type Status ¶
type Status string
func (Status) CountsTowardMRR ¶ added in v1.49.48
CountsTowardMRR reports whether a subscription in this status is recurring revenue RIGHT NOW. Only an active one is.
A trialing subscription is not yet revenue: nobody has been charged, and the trial may end in a cancel. Counting it books money that does not exist, and it does so worst exactly when a promotion drives a wave of trial signups — the revenue board climbs on the day the discounting starts. past_due and unpaid are billed but uncollected, and canceled is over; none of them is run-rate revenue either.
This is the ONE definition, and it exists because there were three. commerce's rollup counted active only, the hanzoai/cloud admin summed active+trialing off the subscriptions wire, and the warehouse SQL summed everything except trialing — so one account reported three different MRRs depending on which screen you opened. Every summation now asks this.
It answers "is this revenue", NOT "is this customer entitled". A trialing customer IS entitled to the product; that is the paywall's question and stays a separate predicate on purpose.
It tolerates wire noise (case and surrounding space) because hanzoai/cloud reads the status off JSON before asking.
type Subscription ¶
type Subscription struct {
mixin.Model[Subscription]
Number int `json:"number,omitempty" datastore:"-"`
// Immutable buyer data from time of payment, may or may not be associated
// with a user.
Buyer Buyer `json:"buyer"`
Type BillingType `json:"billing_type"`
PlanId string `json:"planId"`
UserId string `json:"userId"`
StoreId string `json:"storeId,omitempty"`
FeePercent float64 `json:"application_fee_percent"`
EndCancel bool `json:"cancel_at_period_end"`
PeriodStart time.Time `json:"current_period_start"`
PeriodEnd time.Time `json:"current_period_end"`
Start time.Time `json:"start"`
Ended time.Time `json:"ended_at"`
Canceled bool `json:"canceled"`
CanceledAt time.Time `json:"canceled_at"`
TrialStart time.Time `json:"trial_start"`
TrialEnd time.Time `json:"trial_end"`
Plan plan.Plan `json:"plan"`
Quantity int `json:"quantity"`
Status Status `json:"status"`
Metadata Map `json:"metadata" datastore:"-" orm:"default:{}"`
Metadata_ string `json:"-" datastore:"-"`
// Provider-agnostic support
ProviderId string `json:"providerId,omitempty"` // External subscription ID (Stripe, etc.)
ProviderType string `json:"providerType,omitempty"` // "stripe", "internal"
// Billing configuration
DefaultPaymentMethod string `json:"defaultPaymentMethod,omitempty"` // "stripe:pm_xxx" | "balance"
BillingAnchor int `json:"billingAnchor,omitempty"` // Day of month 1-28
CurrentInvoiceId string `json:"currentInvoiceId,omitempty"`
// Stripe livemode
Live bool `json:"live"`
// Internal testing flag
Test bool `json:"-"`
Account accounts.Account `json:"account,omitempty"`
Ref refs.EcommerceRef `json:"ref,omitempty"`
}
func Fake ¶
func Fake(db *datastore.Datastore) *Subscription
func New ¶
func New(db *datastore.Datastore) *Subscription
New creates a new Subscription wired to the given datastore.
func (Subscription) NumberFromId ¶
func (s Subscription) NumberFromId() (i int, err error)
func (Subscription) PeriodsRemaining ¶
func (s Subscription) PeriodsRemaining() int
func (Subscription) TrialPeriodsRemaining ¶
func (s Subscription) TrialPeriodsRemaining() int
func (*Subscription) Validator ¶
func (s *Subscription) Validator() *val.Validator