commerce

package
v1.801.79 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package commerce is the admin cockpit's typed reader for the commerce billing plane. It models the domain, not the endpoints: a billing subject (an org's slug) has orthogonal, independently-readable facets —

Spend    — what it consumed this month
Credits  — what prepaid balance it holds
Plan     — its subscription tier + monthly-recurring revenue
Ledger   — its transaction history

plus one fleet god-view (Costs, our vendor COGS) and one write (Deposit, the grant-credit primitive). Each read is total: an unwired or unreachable commerce degrades to an honest zero, never a fabricated number.

Commerce runs as its own deployment; these are HTTP calls authenticated with the admin-scoped COMMERCE_SERVICE_TOKEN (a KMS-sourced secret already on the cloud env — never hard-coded). A per-subject read resolves the org's billing namespace from the TRUSTED X-Org-Id header (commerce's EdgeAuth trusts it only when the bearer is the service token) AND keys the wallet under the bare slug — one value, the subject, is both. The fleet Costs god-view is org-independent and sends no subject.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client reads the commerce billing plane.

func New

func New(base, token string) *Client

New builds a commerce client for base + admin S2S token.

func (*Client) Costs

func (c *Client) Costs(ctx context.Context, period string) (Costs, error)

Costs reads commerce's vendor-COGS god-view (GET /v1/costs) for a period — the SINGLE source of truth for what we pay every vendor. It authenticates with the admin S2S service token (no IAM user identity) and is org-INDEPENDENT, so it sends no subject. Zero (not an error) when commerce is unwired.

func (*Client) Credits

func (c *Client) Credits(ctx context.Context, subject string) (money.Cents, error)

Credits reads a subject's available prepaid credit (GET /v1/billing/balance). Zero (not an error) when commerce is unwired.

func (*Client) Deposit

func (c *Client) Deposit(ctx context.Context, subject string, amount money.Cents, currency, notes, tags, idempotencyKey string) (Receipt, error)

Deposit grants credit to a subject's wallet (POST /v1/billing/deposit) — the ONE money-in primitive. Symmetric with Credits: the same X-Org-Id namespace + `user` subject the reads resolve. amount must be positive (the handler validates + caps).

idempotencyKey, when non-empty, is sent as X-Idempotency-Key so commerce dedupes a retried deposit AT MOST ONCE (a completed key REPLAYS the stored receipt, an in-flight key 409s; scoped billing-deposit:<subject>). This closes the commit-then-timeout double -credit: cloud's 15s client can time out AFTER commerce committed, and a retry carrying the SAME key lands nothing new. An EMPTY key preserves the additive default (distinct deposits to the same subject are legitimately cumulative) — commerce never dedupes by amount. See commerce api/billing/deposit.go.

func (*Client) Forward added in v1.801.79

func (c *Client) Forward(ctx context.Context, method, path, subject string, body []byte) ([]byte, int, error)

Forward proxies an admin-authenticated request to commerce VERBATIM and returns the raw body + status. It is the ONE seam a SuperAdmin surface drives commerce's own endpoints through — the platform plan-promo config (/v1/platform/promo) and a per-org spend-alert override (/v1/billing/spend-alerts) — without a typed method per shape. subject is the X-Org-Id namespace selector (the target org for a cap override, or the admin org for platform config); body is nil for GET/DELETE. The status is returned so the caller surfaces commerce's OWN verdict (400 validation, 403, 404) instead of flattening every non-2xx into one code.

func (*Client) Invoices added in v1.801.79

func (c *Client) Invoices(ctx context.Context, subject, status string) ([]Invoice, error)

Invoices lists a subject's invoices (GET /v1/billing/invoices), optionally filtered by status. The subject selects the org's billing namespace via X-Org-Id (trusted only after the service-token bearer verifies). Empty (not an error) when commerce is unwired.

func (*Client) Ledger

func (c *Client) Ledger(ctx context.Context, subject string, limit int) ([]Entry, error)

Ledger reads a subject's transaction history (GET /v1/billing/transactions), newest-first, bounded by limit. Empty (not an error) when commerce is unwired.

func (*Client) Metrics added in v1.801.79

func (c *Client) Metrics(ctx context.Context, window string, limit int) (SaaSMetrics, error)

Metrics reads the fleet SaaS-operations god-view (GET /v1/metrics/saas). Like Costs it is org-INDEPENDENT — the engine walks every org namespace itself — so it authenticates with the admin S2S service token and sends NO subject. Empty (not an error) when commerce is unwired, so a partial deploy degrades to an honest empty snapshot.

func (*Client) Plan

func (c *Client) Plan(ctx context.Context, subject string) (Plan, error)

Plan reads a subject's subscription tier + MRR in ONE decode (GET /v1/billing/subscriptions), so the customer + revenue surfaces share a single upstream read. Only "active"/"trialing" subscriptions count. Honest zero/"pay-as-you-go" (not an error) when commerce is unwired.

func (*Client) Ready

func (c *Client) Ready() bool

Ready reports whether a commerce endpoint is wired on this deployment.

func (*Client) Spend

func (c *Client) Spend(ctx context.Context, subject string) (Spend, error)

Spend reads a subject's month-to-date consumption (GET /v1/billing/usage-rollup). Zero (not an error) when commerce is unwired, so a partial deploy degrades to honest zeros.

func (*Client) Subscriptions added in v1.801.79

func (c *Client) Subscriptions(ctx context.Context, subject, status string) ([]Subscription, error)

Subscriptions lists a subject's subscriptions (GET /v1/billing/subscriptions), optionally filtered by status, as fleet rows with a monthly-normalized MRR. Empty (not an error) when commerce is unwired.

type Costs

type Costs struct {
	Period   string      `json:"period"`
	Vendors  []Vendor    `json:"vendors"`
	Total    money.Cents `json:"totalCents"`
	Currency string      `json:"currency"`
}

Costs is the fleet COGS god-view: every vendor line for a period plus the total.

type Entry

type Entry struct {
	ID       string      `json:"id"`
	Kind     string      `json:"type"`
	Amount   money.Cents `json:"amount"`
	Currency string      `json:"currency"`
	Tags     string      `json:"tags,omitempty"`
	Notes    string      `json:"notes,omitempty"`
	At       string      `json:"createdAt"`
}

Entry is one ledger row. Kind is "deposit" (credit) or "withdraw" (usage). At is the RFC3339 event time analytics buckets on.

type Invoice added in v1.801.79

type Invoice struct {
	ID        string      `json:"id"`
	Number    string      `json:"numberStr"`
	Status    string      `json:"status"`
	AmountDue money.Cents `json:"amountDue"`
	Currency  string      `json:"currency"`
	Issued    string      `json:"createdAt"`
	Due       string      `json:"dueDate"`
}

Invoice is one issued invoice as the fleet god-view renders it: the id (for a future /v1/billing/invoices/:id detail fetch), the human number, status, amount due, currency, and the issue/due dates. Sourced from GET /v1/billing/invoices (invoiceResponse); all timestamps are RFC3339 strings.

type Plan

type Plan struct {
	Name   string
	MRR    money.Cents
	Active bool
}

Plan is a subject's subscription: the active tier, the monthly-normalized recurring revenue, and whether any subscription is active. Name is "pay-as-you-go" for a metered subject with no active subscription (the honest default, never a fabricated tier).

type Receipt

type Receipt struct {
	TxID     string      `json:"transactionId"`
	Amount   money.Cents `json:"amount"`
	Currency string      `json:"currency"`
}

Receipt is the result of a Deposit — the transaction id of the credit that landed.

type SaaSCategory added in v1.801.79

type SaaSCategory struct {
	Category      string      `json:"category"`
	MRRCents      money.Cents `json:"mrrCents"`
	Subscriptions int         `json:"subscriptions"`
}

SaaSCategory is one plan-category bucket of run-rate MRR (the plan mix).

type SaaSCustomer added in v1.801.79

type SaaSCustomer struct {
	Org        string      `json:"org"`
	Plan       string      `json:"plan"`
	Category   string      `json:"category"`
	Status     string      `json:"status"`
	MRRCents   money.Cents `json:"mrrCents"`
	UsageCents money.Cents `json:"usageCents"`
	Seats      int         `json:"seats"`
	Since      string      `json:"since,omitempty"`
}

SaaSCustomer is one top customer by MRR + windowed usage.

type SaaSEvent added in v1.801.79

type SaaSEvent struct {
	At            string      `json:"at"`
	Org           string      `json:"org"`
	Type          string      `json:"type"`
	Plan          string      `json:"plan"`
	Category      string      `json:"category"`
	MRRDeltaCents money.Cents `json:"mrrDeltaCents"`
}

SaaSEvent is one recent subscription movement ("created" or "canceled").

type SaaSMetrics added in v1.801.79

type SaaSMetrics struct {
	AsOf      string         `json:"asOf"`
	Currency  string         `json:"currency"`
	Window    string         `json:"window"`
	Revenue   SaaSRevenue    `json:"revenue"`
	Subs      SaaSSubs       `json:"subscriptions"`
	Usage     SaaSUsage      `json:"usage"`
	Customers []SaaSCustomer `json:"customers"`
	Orgs      int            `json:"orgs"`
	Gaps      []string       `json:"gaps"`
}

SaaSMetrics mirrors commerce's GET /v1/metrics/saas snapshot — the whole-business SaaS-operations aggregate (MRR/ARR, new/churn, plan mix, top customers, recent movements) computed IN commerce across every org namespace. It is org-INDEPENDENT (like Costs) so the reader sends NO subject. Only the fields the admin god-view renders are modeled; commerce fields we don't consume (upgrades/downgrades, untagged-request counts) are simply ignored by the decoder.

type SaaSPlan added in v1.801.79

type SaaSPlan struct {
	Plan     string      `json:"plan"`
	Name     string      `json:"name"`
	Category string      `json:"category"`
	Active   int         `json:"active"`
	Trialing int         `json:"trialing"`
	Seats    int         `json:"seats"`
	MRRCents money.Cents `json:"mrrCents"`
}

SaaSPlan is one plan's active/trialing counts, seats, and MRR contribution.

type SaaSRevenue added in v1.801.79

type SaaSRevenue struct {
	MRRCents            money.Cents    `json:"mrrCents"`
	ARRCents            money.Cents    `json:"arrCents"`
	ActiveSubscriptions int            `json:"activeSubscriptions"`
	PayingCustomers     int            `json:"payingCustomers"`
	Trials              int            `json:"trials"`
	NewMRRCents         money.Cents    `json:"newMrrCents"`
	ChurnedMRRCents     money.Cents    `json:"churnedMrrCents"`
	NetNewMRRCents      money.Cents    `json:"netNewMrrCents"`
	ByCategory          []SaaSCategory `json:"byCategory"`
}

SaaSRevenue is the recurring-revenue headline (run-rate MRR/ARR + windowed movement).

type SaaSSubs added in v1.801.79

type SaaSSubs struct {
	ByPlan       []SaaSPlan  `json:"byPlan"`
	TrialsActive int         `json:"trialsActive"`
	New          int         `json:"new"`
	Canceled     int         `json:"canceled"`
	Recent       []SaaSEvent `json:"recent"`
}

SaaSSubs is the subscription-operations panel (per-plan mix, trials, new/canceled, recent movements).

type SaaSUsage added in v1.801.79

type SaaSUsage struct {
	Instrumented     bool        `json:"instrumented"`
	WindowUsageCents money.Cents `json:"windowUsageCents"`
	Requests         int64       `json:"requests"`
}

SaaSUsage is the metered / pay-as-you-go revenue headline for the window.

type Spend

type Spend struct {
	Consumed money.Cents `json:"consumedCents"`
	Overage  money.Cents `json:"overageCents"`
}

Spend is a subject's month-to-date consumption.

type Subscription added in v1.801.79

type Subscription struct {
	ID      string      `json:"id"`
	User    string      `json:"user"`
	Plan    string      `json:"plan"`
	Status  string      `json:"status"`
	MRR     money.Cents `json:"mrrCents"`
	Started string      `json:"started"`
	Renews  string      `json:"renews"`
}

Subscription is one subscription row the fleet god-view renders: the id, the buyer (userId), plan tier, status, monthly-normalized MRR, and the current-period start/end (started/renews). MRR reuses monthlyNormalized so a yearly plan is comparable to a monthly one in the fleet total.

type Vendor

type Vendor struct {
	Name    string      `json:"vendor"`
	Service string      `json:"service"`
	Amount  money.Cents `json:"amountCents"`
	Source  string      `json:"source"` // "actual" | "estimated"
	Note    string      `json:"note,omitempty"`
}

Vendor is one line of what WE pay a vendor for a service in a period (COGS).

Jump to

Keyboard shortcuts

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