Upgrade dialog looks nice now
This commit is contained in:
parent
695c1349e8
commit
4092f7fd51
9 changed files with 160 additions and 85 deletions
|
@ -49,7 +49,6 @@ func (s *Server) handleAccountGet(w http.ResponseWriter, _ *http.Request, v *vis
|
|||
return err
|
||||
}
|
||||
limits, stats := info.Limits, info.Stats
|
||||
|
||||
response := &apiAccountResponse{
|
||||
Limits: &apiAccountLimits{
|
||||
Basis: string(limits.Basis),
|
||||
|
|
|
@ -24,12 +24,30 @@ const (
|
|||
stripeBodyBytesLimit = 16384
|
||||
)
|
||||
|
||||
var (
|
||||
errNotAPaidTier = errors.New("tier does not have Stripe price identifier")
|
||||
)
|
||||
|
||||
func (s *Server) handleAccountBillingTiersGet(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||
tiers, err := v.userManager.Tiers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response := make([]*apiAccountBillingTier, 0)
|
||||
freeTier := defaultVisitorLimits(s.config)
|
||||
response := []*apiAccountBillingTier{
|
||||
{
|
||||
// Free tier: no code, name or price
|
||||
Limits: &apiAccountLimits{
|
||||
Messages: freeTier.MessagesLimit,
|
||||
MessagesExpiryDuration: int64(freeTier.MessagesExpiryDuration.Seconds()),
|
||||
Emails: freeTier.EmailsLimit,
|
||||
Reservations: freeTier.ReservationsLimit,
|
||||
AttachmentTotalSize: freeTier.AttachmentTotalSizeLimit,
|
||||
AttachmentFileSize: freeTier.AttachmentFileSizeLimit,
|
||||
AttachmentExpiryDuration: int64(freeTier.AttachmentExpiryDuration.Seconds()),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tier := range tiers {
|
||||
if tier.StripePriceID == "" {
|
||||
continue
|
||||
|
@ -48,10 +66,18 @@ func (s *Server) handleAccountBillingTiersGet(w http.ResponseWriter, r *http.Req
|
|||
s.priceCache[tier.StripePriceID] = priceStr // FIXME race, make this sync.Map or something
|
||||
}
|
||||
response = append(response, &apiAccountBillingTier{
|
||||
Code: tier.Code,
|
||||
Name: tier.Name,
|
||||
Price: priceStr,
|
||||
Features: tier.Features,
|
||||
Code: tier.Code,
|
||||
Name: tier.Name,
|
||||
Price: priceStr,
|
||||
Limits: &apiAccountLimits{
|
||||
Messages: tier.MessagesLimit,
|
||||
MessagesExpiryDuration: int64(tier.MessagesExpiryDuration.Seconds()),
|
||||
Emails: tier.EmailsLimit,
|
||||
Reservations: tier.ReservationsLimit,
|
||||
AttachmentTotalSize: tier.AttachmentTotalSizeLimit,
|
||||
AttachmentFileSize: tier.AttachmentFileSizeLimit,
|
||||
AttachmentExpiryDuration: int64(tier.AttachmentExpiryDuration.Seconds()),
|
||||
},
|
||||
})
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
@ -75,9 +101,8 @@ func (s *Server) handleAccountBillingSubscriptionCreate(w http.ResponseWriter, r
|
|||
tier, err := s.userManager.Tier(req.Tier)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tier.StripePriceID == "" {
|
||||
return errors.New("invalid tier") //FIXME
|
||||
} else if tier.StripePriceID == "" {
|
||||
return errNotAPaidTier
|
||||
}
|
||||
log.Info("Stripe: No existing subscription, creating checkout flow")
|
||||
var stripeCustomerID *string
|
||||
|
@ -92,10 +117,11 @@ func (s *Server) handleAccountBillingSubscriptionCreate(w http.ResponseWriter, r
|
|||
}
|
||||
successURL := s.config.BaseURL + apiAccountBillingSubscriptionCheckoutSuccessTemplate
|
||||
params := &stripe.CheckoutSessionParams{
|
||||
Customer: stripeCustomerID, // A user may have previously deleted their subscription
|
||||
ClientReferenceID: &v.user.Name,
|
||||
SuccessURL: &successURL,
|
||||
Mode: stripe.String(string(stripe.CheckoutSessionModeSubscription)),
|
||||
Customer: stripeCustomerID, // A user may have previously deleted their subscription
|
||||
ClientReferenceID: &v.user.Name,
|
||||
SuccessURL: &successURL,
|
||||
Mode: stripe.String(string(stripe.CheckoutSessionModeSubscription)),
|
||||
AllowPromotionCodes: stripe.Bool(true),
|
||||
LineItems: []*stripe.CheckoutSessionLineItemParams{
|
||||
{
|
||||
Price: stripe.String(tier.StripePriceID),
|
||||
|
@ -212,6 +238,11 @@ func (s *Server) handleAccountBillingSubscriptionDelete(w http.ResponseWriter, r
|
|||
return err
|
||||
}
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*") // FIXME remove this
|
||||
if err := json.NewEncoder(w).Encode(newSuccessResponse()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ type apiAccountTier struct {
|
|||
}
|
||||
|
||||
type apiAccountLimits struct {
|
||||
Basis string `json:"basis"` // "ip", "role" or "tier"
|
||||
Basis string `json:"basis,omitempty"` // "ip", "role" or "tier"
|
||||
Messages int64 `json:"messages"`
|
||||
MessagesExpiryDuration int64 `json:"messages_expiry_duration"`
|
||||
Emails int64 `json:"emails"`
|
||||
|
@ -305,10 +305,10 @@ type apiConfigResponse struct {
|
|||
}
|
||||
|
||||
type apiAccountBillingTier struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Price string `json:"price"`
|
||||
Features string `json:"features"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Price string `json:"price,omitempty"`
|
||||
Limits *apiAccountLimits `json:"limits"`
|
||||
}
|
||||
|
||||
type apiAccountBillingSubscriptionCreateResponse struct {
|
||||
|
|
|
@ -212,7 +212,7 @@ func (v *visitor) ResetStats() {
|
|||
}
|
||||
|
||||
func (v *visitor) Limits() *visitorLimits {
|
||||
limits := &visitorLimits{}
|
||||
limits := defaultVisitorLimits(v.config)
|
||||
if v.user != nil && v.user.Tier != nil {
|
||||
limits.Basis = visitorLimitBasisTier
|
||||
limits.MessagesLimit = v.user.Tier.MessagesLimit
|
||||
|
@ -222,15 +222,6 @@ func (v *visitor) Limits() *visitorLimits {
|
|||
limits.AttachmentTotalSizeLimit = v.user.Tier.AttachmentTotalSizeLimit
|
||||
limits.AttachmentFileSizeLimit = v.user.Tier.AttachmentFileSizeLimit
|
||||
limits.AttachmentExpiryDuration = v.user.Tier.AttachmentExpiryDuration
|
||||
} else {
|
||||
limits.Basis = visitorLimitBasisIP
|
||||
limits.MessagesLimit = replenishDurationToDailyLimit(v.config.VisitorRequestLimitReplenish)
|
||||
limits.MessagesExpiryDuration = v.config.CacheDuration
|
||||
limits.EmailsLimit = replenishDurationToDailyLimit(v.config.VisitorEmailLimitReplenish)
|
||||
limits.ReservationsLimit = 0 // No reservations for anonymous users, or users without a tier
|
||||
limits.AttachmentTotalSizeLimit = v.config.VisitorAttachmentTotalSizeLimit
|
||||
limits.AttachmentFileSizeLimit = v.config.AttachmentFileSizeLimit
|
||||
limits.AttachmentExpiryDuration = v.config.AttachmentExpiryDuration
|
||||
}
|
||||
return limits
|
||||
}
|
||||
|
@ -288,3 +279,16 @@ func replenishDurationToDailyLimit(duration time.Duration) int64 {
|
|||
func dailyLimitToRate(limit int64) rate.Limit {
|
||||
return rate.Limit(limit) * rate.Every(24*time.Hour)
|
||||
}
|
||||
|
||||
func defaultVisitorLimits(conf *Config) *visitorLimits {
|
||||
return &visitorLimits{
|
||||
Basis: visitorLimitBasisIP,
|
||||
MessagesLimit: replenishDurationToDailyLimit(conf.VisitorRequestLimitReplenish),
|
||||
MessagesExpiryDuration: conf.CacheDuration,
|
||||
EmailsLimit: replenishDurationToDailyLimit(conf.VisitorEmailLimitReplenish),
|
||||
ReservationsLimit: 0, // No reservations for anonymous users, or users without a tier
|
||||
AttachmentTotalSizeLimit: conf.VisitorAttachmentTotalSizeLimit,
|
||||
AttachmentFileSizeLimit: conf.AttachmentFileSizeLimit,
|
||||
AttachmentExpiryDuration: conf.AttachmentExpiryDuration,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue