deprecated: use 'npm install tier' instead


License
ISC
Install
npm install @tier.run/sdk@2.2.1

Documentation

tier Node SDK

SDK for using https://tier.run in Node.js applications

INSTALLING

First, install the Tier binary.

Run tier connect to authorize Tier to your Stripe account, or provide a STRIPE_API_KEY environment variable.

npm install tier

Overview

This is the SDK that can may be used to integrate Tier into your application. More details on the general concepts used by Tier may be found at https://www.tier.run/docs/.

The SDK works by talking to an instance of the Tier binary running as a sidecar, using tier serve.

USAGE

Note: the Tier client is not designed to be used in web browsers.

This module exports both a zero-dependency client class, suitable for use in non-Node.js environments such as edge workers and Deno, as well as a simple functional SDK that manages spinning up the sidecar automatically.

Automatic Mode

Import the main module, and use the API methods provided. The sidecar will be started on the first API method, or may be started immediately using the init() method. It will listen on a port determined by the process ID.

import tier from 'tier'
// that's it, it'll start the sidecar as needed

To point at a pre-existing running Tier sidecar, set the TIER_SIDECAR environment variable to its base URL.

To operate on live Stripe data (that is, to start the sidecar in live mode), set TIER_LIVE=1 in the environment.

Turn on debug output by setting TIER_DEBUG=1 or NODE_DEBUG=tier in the environment.

Note that you must have previously run tier connect to authorize Tier to access your Stripe account, or set the STRIPE_API_KEY environment variable.

This of course requires that Node's child_process module is available. If fetch is not available, then the optional node-fetch dependency will be loaded as a polyfill.

Raw Client Mode

To use Tier in an environment where child_process.spawn is not available, or where you simply don't need this added functionality because you are managing the sidecar yourself, you can load and instantiate the client:

import { Tier } from 'tier/client'

const tier = new Tier({
  // Required: the base url to the running `tier serve` instance
  sidecar: myTierSidecarBaseURL,
  // Optional, only needed if fetch global is not available
  fetchImpl: myFetchImplementation,
  // Optional, defaults to false
  debug: false
})

Then call API methods from the tier instance.

Error Handling

All methods will raise a TierError object if there's a non-2xx response from the Tier sidecar, or if a response is not valid JSON.

This Error subclass contains the following fields:

  • status - number, the HTTP status code received
  • code - Short string representation of the error, something like not_found
  • message - Human-readable explanation of the error.
  • path - The API path being accessed
  • requestData - The data sent to the API path (query string for GETs, request body for POSTs.)
  • responseData - The response data returned by the API endpoint.

API METHODS

subscribe(org, plan, [effective])

Subscribe an org to the specified plan. If no effective date is provided, then the plan is effective immediately.

Plan may be either a versioned plan name, or an array of versioned plan names.

If no effective date is provided, then the plan is effective immediately.

subscribe(org, phases)

Subscribe an org to each of the sets of plans specified in the phases array.

Each item in phases must be an object containing:

  • features Array of plan names
  • effective Optional effective date

If no effective date is provided, then the phase takes effect immediately.

limits(org)

Retrieve the usage data and limits for an org.

{
  "org": "org:user",
  "usage": [
    {
      "feature": "feature:storage",
      "used": 341,
      "limit": 10000
    },
    {
      "feature": "feature:transfer",
      "used": 234213,
      "limit": 10000
    }
  ]
}

limit(org, feature)

Retrieve the usage and limit data for an org and single feature.

{
  "feature": "feature:storage",
  "used": 341,
  "limit": 10000
}

If the org does not have access to the feature, then an object is returned with usage and limit set to 0.

{
  "feature": "feature:noaccess",
  "used": 0,
  "limit": 0
}

report(org, feature, [n = 1], [at = new Date()], [clobber = false])

Report usage of a feature by an org.

The optional n parameter indicates the number of units of the feature that were consumed.

The optional at parameter is a Date object indicating when the usage took place.

The optional clobber parameter indicates that the usage should override any previously reported usage of the feature for the current subscription phase.

whois(org)

Retrieve the Stripe Customer ID for an org.

{
  "org": "org:user",
  "stripe_id": "cus_v49o7xMpZaMbzg"
}

phase(org)

Retrieve the current schedule phase for the org. This provides a list of the features and plans that the org is currently subscribed to, which can be useful information when creating a user interface for upgrading/downgrading pricing plans.

{
  "effective": "2022-10-13T16:52:11-07:00",
  "features": ["feature:storage@plan:free@1", "feature:transfer@plan:free@1"],
  "plans": ["plan:free@1"]
}

Note: This should not be used for checking entitlements and feature gating. Instead, use the Tier.limit() method and check the limit and usage for the feature in question.

For example:

// Do not do this!  You will regret it!
const phase = await Tier.phase(`org:${customerID}`)
if (phase.plans.some(plan => plan.startsWith('plan:pro')) {
  showSpecialFeature()
}

Instead, do this:

const usage = await Tier.limit(`org:${customerID}`, 'feature:special')
if (usage.limit < usage.used) {
  showSpecialFeature()
}

pull()

Fetches the pricing model from Stripe.

pullLatest()

Experimental

Fetches the pricing model from Stripe, but only shows the plans with the highest versions (lexically sorted). This can be useful in building pricing pages in your application (assuming that "highest lexically sorted plan version" is the one that you want to show, of course).

For example, if Tier.pull() returns this:

{
  "plans": {
    "plan:foo@1": {},
    "plan:foo@0": {},
    "plan:bar@7": {},
    "plan:foo@2": {},
    "plan:bar@0": {}
  }
}

then Tier.pullLatest() will return:

{
  "plans": {
    "plan:foo@2": {},
    "plan:bar@7": {}
  }
}

push(model)

Creates the Product and Price objects in Stripe corresponding to the supplied pricing Model (as would be found in a pricing.json file).

Returns an object detailing which features were created, and which either had errors or already existed. Note that a successful response from this method does not mean that all of the features were created (since, for example, some may already exist), only that some of them were.