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 ¶
- type Client
- func (c *Client) Costs(ctx context.Context, period string) (Costs, error)
- func (c *Client) Credits(ctx context.Context, subject string) (money.Cents, error)
- func (c *Client) Deposit(ctx context.Context, subject string, amount money.Cents, ...) (Receipt, error)
- func (c *Client) Ledger(ctx context.Context, subject string, limit int) ([]Entry, error)
- func (c *Client) Plan(ctx context.Context, subject string) (Plan, error)
- func (c *Client) Ready() bool
- func (c *Client) Spend(ctx context.Context, subject string) (Spend, error)
- type Costs
- type Entry
- type Plan
- type Receipt
- type Spend
- type Vendor
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 (*Client) Costs ¶
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 ¶
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) Ledger ¶
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) Plan ¶
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.
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 Plan ¶
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 Spend ¶
type Spend struct {
Consumed money.Cents `json:"consumedCents"`
Overage money.Cents `json:"overageCents"`
}
Spend is a subject's month-to-date consumption.
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).