Version: v0.12.0 Latest Latest

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

Go to latest
Published: Jul 13, 2023 License: BSD-3-Clause Imports: 11 Imported by: 0



Package tier contains the local client for interacting with the tier sidecar API.

For more information, please see https://tier.run/docs.




View Source
const ClockHeader = "Tier-Clock"

ClockHeader is the header used to pass the clock ID to the tier sidecar. It is exported for use by the sidecar API. Most users want to use WithClock.

View Source
const Inf = 1<<63 - 1


This section is empty.


func WithClock added in v0.10.0

func WithClock(ctx context.Context, id string) context.Context

WithClock returns a context with the provided clock ID set. The clock ID is pass via the Tier-Clock header to be used by the tier sidecar.


type Answer added in v0.4.2

type Answer struct {
	// contains filtered or unexported fields

An Answer is the response to any question for Can. It can be used in a few forms to shorten the logic necessary to know if a program should proceed to perform a user request based on their entitlements.

func (Answer) Err added in v0.4.2

func (c Answer) Err() error

Err returns the error, if any, that occurred during the call to Can.

func (Answer) OK added in v0.4.2

func (c Answer) OK() bool

OK reports if the program should proceed with a user request or not. To prevent total failure if Can needed to reach the sidecar and was unable to, OK will fail optimistically and report true. If the opposite is desired, clients can check Err.

func (Answer) Report added in v0.4.2

func (c Answer) Report() error

Report is the same as calling ReportN(1).

func (Answer) ReportN added in v0.4.2

func (c Answer) ReportN(n int) error

ReportN reports usage of n units for the feature and org provided to Can.

type CheckoutParams added in v0.7.1

type CheckoutParams struct {
	TrialDays             int
	Features              []string
	CancelURL             string
	RequireBillingAddress bool
	Tax                   Taxation

type Client

type Client struct {
	// APIKey is the API key used, and set in the Authorization header.
	APIKey string

	BaseURL    string // the base URL of the tier sidecar; default is
	HTTPClient *http.Client

	Logf func(fmt string, args ...any)
package main

import (


func main() {
	c := &tier.Client{}

	m := http.NewServeMux()
	m.HandleFunc("/convert", func(w http.ResponseWriter, r *http.Request) {
		org := orgFromSession(r)
		ans := c.Can(r.Context(), org, "feature:convert")
		if ans.OK() {
		defer ans.Report()
		temp := convert(r.FormValue("temp"))
		io.WriteString(w, temp)

	m.HandleFunc("/subscribe", func(w http.ResponseWriter, r *http.Request) {
		org := orgFromSession(r)
		plan := r.FormValue("plan")
		if err := c.Subscribe(r.Context(), org, plan); err != nil {

	log.Fatal(http.ListenAndServe(":https", m))

func orgFromSession(r *http.Request) string {
	return "org:example"

func convert(temp string) string {
	return "80F"

func FromEnv added in v0.7.0

func FromEnv() (*Client, error)

FromEnv returns a Client configured from the environment. The BaseURL is set to the value of the TIER_BASE_URL environment variable, or if unset.

It returns an error if the TIER_BASE_URL environment variable is set to an invalid URL.

func (*Client) Advance added in v0.10.0

func (c *Client) Advance(ctx context.Context, t time.Time) error

Advance advances the test clock set in the context to t.

It is an error to call Advance if no clock is set in the context.

func (*Client) Can added in v0.4.2

func (c *Client) Can(ctx context.Context, org, feature string) Answer

Can is a convenience function for checking if an org has used more of a feature than they are entitled to and optionally reporting usage post check and consumption.

If reporting consumption is not required, it can be used in the form:

if c.Can(ctx, "org:acme", "feature:convert").OK() { ... }

reporting usage post consumption looks like:

ans := c.Can(ctx, "org:acme", "feature:convert")
if !ans.OK() {
  return ""
defer ans.Report() // or ReportN
return convert(temp)
Example (Basic)
package main

import (


func main() {
	c := &tier.Client{}

	// Check if the user can convert a temperature.
	if c.Can(context.Background(), "org:example", "feature:convert").OK() {
		// The user can convert a temperature.
	} else {
		// The user cannot convert a temperature.

Example (Report)
package main

import (


func main() {
	c := &tier.Client{}
	ans := c.Can(context.Background(), "org:example", "feature:convert")
	if !ans.OK() {
		// The user cannot convert a temperature.
	defer ans.Report() // report consumption after the conversion

func convert(temp string) string {
	return "80F"

func readInput() string {
	return "30C"

func (*Client) Cancel added in v0.10.0

func (c *Client) Cancel(ctx context.Context, org string) error

Cancel cancels the subscription for the provided org.

func (*Client) Checkout added in v0.7.1

func (c *Client) Checkout(ctx context.Context, org string, successURL string, p *CheckoutParams) (*apitypes.CheckoutResponse, error)

Checkout creates a new checkout link for the provided org and features, if any; otherwise, if no features are specified, and payment setup link is returned instead.

func (*Client) LookupLimit added in v0.4.2

func (c *Client) LookupLimit(ctx context.Context, org, feature string) (limit, used int, err error)

LookupLimit reports the current usage and limits for the provided org and feature. If the feature is not currently available to the org, both limit and used are zero and no error is reported.

It reports an error if any.

func (*Client) LookupLimits added in v0.3.1

func (c *Client) LookupLimits(ctx context.Context, org string) (apitypes.UsageResponse, error)

LookupLimits reports the current usage and limits for the provided org.

func (*Client) LookupOrg added in v0.6.0

func (c *Client) LookupOrg(ctx context.Context, org string) (apitypes.WhoIsResponse, error)

LookupOrg reports all known information about the provided org. The information is not cached by the server. If only the Stripe customer ID is needed and speed is of concern, users should use WhoIs.

func (*Client) LookupPaymentMethods added in v0.9.0

func (c *Client) LookupPaymentMethods(ctx context.Context, org string) (apitypes.PaymentMethodsResponse, error)

func (*Client) LookupPhase added in v0.4.2

func (c *Client) LookupPhase(ctx context.Context, org string) (apitypes.PhaseResponse, error)

LookupPhase reports information about the current phase the provided org is scheduled in.

func (*Client) LookupPhases

func (c *Client) LookupPhases(ctx context.Context, org string) (apitypes.PhasesResponse, error)

LookupPhases reports information about all recent, current, and future phases for org.

EXPERIMENTAL: This API is subject to change.

func (*Client) Pull

func (c *Client) Pull(ctx context.Context) (apitypes.Model, error)

Pull fetches the complete pricing model from Stripe.

func (*Client) PullJSON added in v0.4.2

func (c *Client) PullJSON(ctx context.Context) ([]byte, error)

PullJSON fetches the complete pricing model from Stripe and returns the raw JSON response.

func (*Client) Push

Push pushes the provided pricing model to Stripe.

func (*Client) PushJSON added in v0.4.2

func (c *Client) PushJSON(ctx context.Context, m []byte) (apitypes.PushResponse, error)

func (*Client) Report added in v0.4.2

func (c *Client) Report(ctx context.Context, org, feature string, n int) error

Report reports a usage of n for the provided org and feature at the current time.

func (*Client) ReportUsage

func (c *Client) ReportUsage(ctx context.Context, org, feature string, n int, rp *ReportParams) error

ReportUsage reports usage based on the provided ReportRequest fields.

func (*Client) Schedule added in v0.6.0

func (c *Client) Schedule(ctx context.Context, org string, p *ScheduleParams) (*apitypes.ScheduleResponse, error)

func (*Client) Subscribe

func (c *Client) Subscribe(ctx context.Context, org string, featuresAndPlans ...string) error

Subscribe subscribes the provided org to the provided feature or plan, effective immediately.

Any in-progress scheduled is overwritten and the customer is billed with prorations immediately.

func (*Client) WhoAmI added in v0.5.0

func (c *Client) WhoAmI(ctx context.Context) (apitypes.WhoAmIResponse, error)

func (*Client) WhoIs

func (c *Client) WhoIs(ctx context.Context, org string) (apitypes.WhoIsResponse, error)

WhoIs reports the Stripe customer ID for the provided org. OrgInfo is not set.

func (*Client) WithClock added in v0.10.0

func (c *Client) WithClock(ctx context.Context, name string, start time.Time) (context.Context, error)

WithClock creates a new test clock with the provided name and start time, and returns a new context with the clock ID set.

It is an error to call WithClock if a clock is already set in the context.

Example (TestClocks)
package main

import (


func main() {
	c, err := tier.FromEnv()
	if err != nil {

	now := time.Now()

	ctx, err := c.WithClock(context.Background(), "testName", now)
	if err != nil {

	// Use ctx with other Client methods

	// This creates the customer and subscription using the clock.
	_ = c.Subscribe(ctx, "org:example", "plan:free@0")

	// Advance the clock by 24 hours, and then report usage.
	_ = c.Advance(ctx, now.Add(24*time.Hour))

	_ = c.Report(ctx, "org:example", "feature:bandwidth", 1000)

type OrgInfo added in v0.6.0

type OrgInfo = apitypes.OrgInfo

type Phase

type Phase = apitypes.Phase

type ReportParams added in v0.7.0

type ReportParams struct {
	At      time.Time // default is 'now' at Stripe
	Clobber bool      // default is false

type ScheduleParams added in v0.6.0

type ScheduleParams struct {
	Info            *OrgInfo
	Phases          []Phase
	PaymentMethodID string

	Tax Taxation

type Taxation added in v0.10.0

type Taxation = apitypes.Taxation

Jump to

Keyboard shortcuts

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