commerceclient

package
v1.801.218 Latest Latest
Warning

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

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

Documentation

Overview

activeplan.go answers the subscription paywall's ONE question: does org X hold a LIVE PAID plan? It is the commerce "active-subscription check" — the tier sibling of CheckEntitlement (per-product license). CheckEntitlement deliberately cannot answer this: it filters Status=Active ONLY (a TRIALING subscriber would be mis-read as unentitled) and it is scoped to a single product id, whereas the paywall gates on the PLAN TIER regardless of product. So ActivePaidPlan is a distinct read over the SAME org resolver + subscription store, counting ACTIVE *and* TRIALING subscriptions and classifying the tier through @hanzo/plans (clients/plan.Paid) — the single source of truth for which tiers cost money.

It is an OPTIONAL capability on the in-process client (not on the narrow types.CommerceClient interface): the paywall (routers.PlanChecker) resolves it by type-assertion, mirroring types.ModelLister. A commerce build that cannot answer (split-deploy ZAP client, disabled stub) simply does not implement it, and the paywall fails OPEN — an outage never locks out a subscriber.

client.go is the in-process inter-subsystem commerce client — the REAL implementation of cloud's types.CommerceClient, absorbed here from the retired in-process stub that used to fail closed on entitlement. It answers cloud's licensing/entitlements tier with DIRECT Go calls into the embedded commerce datastore (subscriptions) plus the @hanzo/plans vocabulary (plan → license features) — no HTTP hop, no network.

MONEY-SAFETY. CheckEntitlement NEVER fabricates a grant. It returns Active:true ONLY when a real active, unexpired subscription in the org's own datastore namespace holds a plan tier whose @hanzo/plans license-features actually name the product. Any machinery it cannot resolve (commerce not co-resident, org not resolvable, subscription query error, plans vocabulary unavailable) returns an ERROR — the entitlements gate treats an erroring client as "cannot verify ⇒ 503", the specified secure default, so an unverifiable product is never enabled. A clean "resolved, but no plan licenses this product" is a real Active:false answer (the gate turns it into a 402 upgrade prompt), never an error and never a grant.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BalanceCents

func BalanceCents(ctx context.Context, org, subject, currency string, test bool) (int64, error)

BalanceCents returns subject's available prepaid balance (USD cents) in org, read DIRECTLY from the co-resident embedded commerce ledger — no HTTP hop. It is the native twin of the /v1/billing/balance read (billing.zapGetBalance): resolve the org's own datastore namespace, tally the subject's iam-user transactions in the currency, and return Balance - Holds clamped at zero. It reuses the SAME currentEmbedded seam the in-process entitlement client resolves through.

This is the read the money cutover (admin/finance backfill) and the admin cockpit's credit panels use when commerce runs in the SAME binary: the admin commerce HTTP client dials an unroutable in-proc address and reads $0, which would silently migrate/report nothing. When commerce is NOT co-resident this returns an ERROR (never 0), so a caller can tell "not wired" from a real zero balance and fail loud rather than move money on a phantom figure. Subject is lowercased + trimmed; an empty currency defaults to usd.

func PublishEmbedded

func PublishEmbedded(e *commercemod.Embedded)

PublishEmbedded records the mounted Embedded as the in-process entitlement source. Mount calls it once; nil un-publishes (tests).

Types

type Client

type Client = types.CommerceClient

Client is the in-process inter-subsystem seam cloud's licensing/entitlements tier calls. It IS cloud's types.CommerceClient — one narrow interface (GetOrgConfig + the real CheckEntitlement), not a second copy — kept as an alias so a value satisfies both names with no adapter. Add methods here only when a consumer needs them; keep it narrow.

func InProcessClient

func InProcessClient(brand string) Client

InProcessClient returns the process-wide, lazily-resolved client cloud's pickCommerceClient wires as deps.Commerce. BuildDeps runs before MountAll, so it resolves the published Embedded per call rather than capturing one; brand answers OrgConfig even before Mount publishes.

Jump to

Keyboard shortcuts

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