Before any real end user signs in, run the whole chain once: a plan that grants a capability, a customer who holds that plan, a usage event from your backend, and the refusal when the allowance is used up. None of it needs a brand domain or a payment account.
1. Define what you sell
In the application's operator console, open Products & Plans (the page is titled Plans & Catalog). It has two tabs, Plans and Capabilities; create things in this order.
A product, on the Plans tab
Choose New Product: a name (for example Reports), a product type (the default, Base Product, is right here) and an optional Stripe price ID you can leave empty. New Plan stays disabled until a product exists.
A metered capability, on the Capabilities tab
A capability is the thing your backend rules on and reports. Give it a key your code will use, for example report_exports (lowercase letters, digits and underscores), a name, the type count, and what happens beyond the allowance: block, allow and bill, or prompt to upgrade. Choose block for this rehearsal so the refusal is visible.
A plan, back on the Plans tab, then publish its version
Choose New Plan and create it under the product with a name, a currency, a price and a billing interval. Version 1 of the plan is a draft until you publish it: grant the capability with an allowance (for example 1 export a month) and a reset interval, then Publish Version. A published version is frozen; price or allowance changes become a new version, and existing subscribers stay on the version they subscribed to.
Publishing syncs to Stripe only once Stripe is connected
Publishing a plan version makes it available to subscribe to. If the application's payment gateway is connected, publishing also creates the matching product and price on your Stripe account; without one, nothing is sent anywhere and the version is synced once you connect an account, which is fine for this rehearsal.
2. Create a test customer
A customer is one buyer organization of your application. Real customers arrive through your brand domain; for the rehearsal, create one directly.
- Open Customers and choose Add test customer. Enter an organization name and the owner's email address.
- The dialog shows the new customer's
organization_id. Copy it: your backend names it when it rules and reports usage. - Choose Activate a plan in the same dialog. It opens Billing with the customer selected; activate the plan you published in step 1.
The test customer is a buyer organization with one end-user account as its owner, shaped exactly as one created by sign-up. Its owner has no password and receives no email: the customer exists to hold a subscription and usage. Creating a second customer with the same email address is refused with 409 CUSTOMER_EXISTS.
3. Send the first usage event
With your backend configured as in Backend, the smallest program that proves the connection is one started client and one event for the test customer:
import { randomUUID } from 'node:crypto';
import { createClient } from '@shiprev/server-sdk-node';
const client = createClient({
api_key: process.env.SHIPREV_API_KEY!,
base_url: process.env.SHIPREV_BASE_URL!,
});
const started = await client.start();
console.log('state', started.state); // LIVE once the region answered
await client.reportUsage({
usage_event_id: randomUUID(),
organization_id: '<organization_id from step 2>',
capability_key: 'report_exports',
quantity: 1,
occurred_at: new Date().toISOString(),
});
await client.stop(); // flushes the buffered eventBack in the operator console, open Metering & Events: the event appears under the test customer within a few seconds. In the developer console, Usage counts it against your own plan's monthly events.
4. Watch the allowance run out
With your guarded routes from Backend in place, the chain behaves like this:
| Step | Expect |
|---|---|
| Call a guarded route without a token, and with a made-up one | 401 both times |
A write on report_exports for the test customer, within the allowance | 200; within a flush interval Metering & Events shows 1 used |
Once the ruling shows remaining: 0, the same write again | 403: the allowance is used up and the capability blocks beyond it |
| Move the customer's subscription to a plan with a larger allowance, in the operator console's Billing | Without restarting your service, the next write is 200: the region pushed the change |
The test customer cannot sign in, so the rows that need a session token are easiest to exercise once a brand domain is verified and a real end user exists; see End users and payments. Until then, call adjudicate() and reportUsage() directly with the test customer's organization_id.
Stripe test mode
Subscriptions in this rehearsal are activated from the operator console and need no payment. When you connect a Stripe account later, use Stripe's test mode first: published plans sync to the test-mode account, end users check out with Stripe's test cards, and nothing is charged. The console shows whether the connected account is in test or live mode.