billing

package
v1.49.29 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 78 Imported by: 0

Documentation

Index

Constants

View Source
const PinnedPlansVersion = "1.4.4"

PinnedPlansVersion is the @hanzo/plans package version the vendored JSON under api/billing/plans is a copy of. Re-vendoring the JSON and bumping this pin go together; plans_drift_test.go asserts the embedded bytes still hash to the recorded digest for this version, so a stray edit to a vendored price (which the seed writes and resolveSubscriptionPlan charges) fails CI loudly. NOTE: the vendored plans/package.json is gitignored (a broad package.json ignore), so it is NOT the pin — this const + the digest test are.

Variables

This section is empty.

Functions

func AddAccountMember added in v1.36.3

func AddAccountMember(c *zip.Ctx) error

AddAccountMember is a stub. Member management is done via IAM.

POST /v1/billing/accounts/:id/members

func AddInvoiceLineItem added in v1.34.0

func AddInvoiceLineItem(c *zip.Ctx) error

AddInvoiceLineItem appends a line item to a draft invoice and recalculates the subtotal.

POST /v1/billing/invoices/:id/line-items

func AdjustCustomerBalance added in v1.34.0

func AdjustCustomerBalance(c *zip.Ctx) error

AdjustCustomerBalance manually adjusts a customer's balance.

POST /v1/billing/customer-balance/adjustments

func ApplyInvoiceDiscount added in v1.34.0

func ApplyInvoiceDiscount(c *zip.Ctx) error

ApplyInvoiceDiscount applies a discount to a draft invoice and recalculates the amount due.

POST /v1/billing/invoices/:id/apply-discount

func AuthorizeSpendCap added in v1.46.38

func AuthorizeSpendCap(c *zip.Ctx) error

AuthorizeSpendCap is the per-request cap verdict for a (project,service) scope and a proposed amount, over the org's spend-alert rows. It evaluates EVERY covering row (most-restrictive-wins) and DENIES when any HARD-enforceable ENFORCE=true row is exceeded, reporting the tightest one. Soft rows — and a project-scoped enforce row whose project axis is NOT validated (pv=0) — never block; they only raise the warn utilization.

FAIL OPEN on UNKNOWN spend: if an enforce row's spend sum cannot be read (a transient finance-ledger error), the verdict does NOT block — a backend blip must not 402 an under-cap customer, nor storm every capped org at once. A row DENIES only when spend is KNOWN and over the cap, so this never fails open on a real overage. Per-scope sums are memoized so covering rows sharing a scope cost one query. The row scan is bounded (loadOrgScopes).

GET /v1/billing/spend-alerts/authorize?user=&project=&service=&amount=&pv=

func BackfillEventID added in v1.49.2

func BackfillEventID(orgName, entityID, eventType string, at time.Time) string

BackfillEventID derives the STABLE id for one (org, entity, lifecycle transition). It is a SHA-256 over the org name, the entity id, the event name, and the transition time in unix-millis — every field immutable on a historical record — so a re-run recomputes the identical id and cannot double-count. Unit-separated (0x1f) so no two distinct inputs collide by concatenation. This is set as the commerce.events event_id (its ORDER BY key) and mirrored into properties.event_id for read-side dedup.

func BurnCredits

func BurnCredits(db *datastore.Datastore, userId string, amount int64, meterId string) (int64, error)

BurnCredits applies the credit burn-down algorithm: deducts amount from active grants in priority order. Returns the remaining amount (overage) and the grants that were modified.

func BurnCreditsPreview added in v1.34.0

func BurnCreditsPreview(db *datastore.Datastore, userId string, amount int64) (int64, error)

BurnCreditsPreview calculates credit burn without actually deducting. Returns the remaining amount after credits would be applied.

func CalculateInvoiceTax added in v1.34.0

func CalculateInvoiceTax(c *zip.Ctx) error

CalculateInvoiceTax computes tax for an invoice based on a customer address and updates the invoice with the resulting tax lines.

POST /v1/billing/invoices/:id/calculate-tax?country=...&state=...

func CancelBillingSubscription added in v1.34.0

func CancelBillingSubscription(c *zip.Ctx) error

CancelBillingSubscription cancels a subscription.

POST /v1/billing/subscriptions/:id/cancel

func CancelPaymentIntent added in v1.34.0

func CancelPaymentIntent(c *zip.Ctx) error

CancelPaymentIntent cancels a payment intent.

POST /v1/billing/payment-intents/:id/cancel

func CancelPayout added in v1.34.0

func CancelPayout(c *zip.Ctx) error

CancelPayout cancels a pending payout.

POST /v1/billing/payouts/:id/cancel

func CancelSetupIntent added in v1.34.0

func CancelSetupIntent(c *zip.Ctx) error

CancelSetupIntent cancels a setup intent.

POST /v1/billing/setup-intents/:id/cancel

func CancelSubscriptionSchedule added in v1.34.0

func CancelSubscriptionSchedule(c *zip.Ctx) error

CancelSubscriptionSchedule cancels a subscription schedule.

POST /v1/billing/subscription-schedules/:id/cancel

func CapturePaymentIntent added in v1.34.0

func CapturePaymentIntent(c *zip.Ctx) error

CapturePaymentIntent captures a previously authorized payment intent.

POST /v1/billing/payment-intents/:id/capture

func ChargeGPU added in v1.46.25

func ChargeGPU(c *zip.Ctx) error

ChargeGPU debits a GPU charge from PREPAID real money only. It is the ONLY commerce write that records a "gpu"-tagged withdrawal, and it is fail-closed:

	POST /v1/billing/gpu-charge  { user, amountCents, currency?, requestId?, tag? }

  - 402 {code: card_required}         — no chargeable card on file.
  - 402 {code: insufficient_prepaid}  — prepaid real money can't cover it
    (credits are NEVER consulted or consumed).
  - 201 {transactionId, prepaidBalance, ...} on success.

Admin/service token (mounted on the admin group) — called by the cloud GPU launch/meter path, never the browser.

func CloseDispute added in v1.34.0

func CloseDispute(c *zip.Ctx) error

CloseDispute closes a dispute.

POST /v1/billing/disputes/:id/close

func ConfirmPaymentIntent added in v1.34.0

func ConfirmPaymentIntent(c *zip.Ctx) error

ConfirmPaymentIntent confirms a payment intent.

POST /v1/billing/payment-intents/:id/confirm

func ConfirmSetupIntent added in v1.34.0

func ConfirmSetupIntent(c *zip.Ctx) error

ConfirmSetupIntent confirms a setup intent, saving the payment method.

POST /v1/billing/setup-intents/:id/confirm

func CreateBankTransferInstruction added in v1.34.0

func CreateBankTransferInstruction(c *zip.Ctx) error

CreateBankTransferInstruction creates bank transfer details for a customer.

POST /v1/billing/bank-transfer-instructions

func CreateBillingAccount added in v1.36.3

func CreateBillingAccount(c *zip.Ctx) error

CreateBillingAccount is a no-op stub. Billing accounts are provisioned via IAM/console org creation; Commerce does not manage org lifecycle. Returns 501 to signal the caller to redirect to the org provisioning flow.

POST /v1/billing/accounts

func CreateBillingSubscription added in v1.34.0

func CreateBillingSubscription(c *zip.Ctx) error

CreateBillingSubscription creates a new subscription and starts the billing lifecycle.

POST /v1/billing/subscriptions

func CreateCreditGrant

func CreateCreditGrant(c *zip.Ctx) error

CreateCreditGrant creates a new credit grant for a user.

POST /v1/billing/credit-grants

func CreateCreditNote added in v1.34.0

func CreateCreditNote(c *zip.Ctx) error

CreateCreditNote creates a credit note against an invoice.

POST /v1/billing/credit-notes

func CreateInvoice added in v1.34.0

func CreateInvoice(c *zip.Ctx) error

CreateInvoice creates a new draft billing invoice.

POST /v1/billing/invoices

func CreateMeter

func CreateMeter(c *zip.Ctx) error

CreateMeter creates a new usage meter definition.

POST /v1/billing/meters

func CreatePaymentIntent added in v1.34.0

func CreatePaymentIntent(c *zip.Ctx) error

CreatePaymentIntent creates a new payment intent.

POST /v1/billing/payment-intents

func CreatePaymentMethod added in v1.34.0

func CreatePaymentMethod(c *zip.Ctx) error

CreatePaymentMethod creates and attaches a payment method to a customer.

POST /v1/billing/payment-methods

func CreatePayout added in v1.34.0

func CreatePayout(c *zip.Ctx) error

CreatePayout creates a new outbound payout.

POST /v1/billing/payouts

func CreatePricingRule

func CreatePricingRule(c *zip.Ctx) error

CreatePricingRule creates a new pricing rule for a meter.

POST /v1/billing/pricing-rules

func CreateRefund added in v1.34.0

func CreateRefund(c *zip.Ctx) error

CreateRefund creates a full or partial refund.

POST /v1/billing/refunds

func CreateSetupIntent added in v1.34.0

func CreateSetupIntent(c *zip.Ctx) error

CreateSetupIntent creates a new setup intent for saving a payment method.

POST /v1/billing/setup-intents

func CreateSpendAlert added in v1.36.3

func CreateSpendAlert(c *zip.Ctx) error

CreateSpendAlert creates a spend alert / cap. UserId is optional (an org-wide or project/service scope cap has none). At least one limit must be meaningful: a Threshold>0 (spend cap) or a RateLimitRpm>0 (rate limit).

POST /v1/billing/spend-alerts

func CreateSubscriptionItem added in v1.34.0

func CreateSubscriptionItem(c *zip.Ctx) error

CreateSubscriptionItem adds an item to a subscription.

POST /v1/billing/subscription-items

func CreateSubscriptionSchedule added in v1.34.0

func CreateSubscriptionSchedule(c *zip.Ctx) error

CreateSubscriptionSchedule creates a new subscription schedule.

POST /v1/billing/subscription-schedules

func Credit added in v1.48.3

func Credit(c *zip.Ctx) error

Credit is THE ONE way credit enters an org ledger. It appends a single org-keyed, non-cash credit grant to the org's balance — the same ledger GET /v1/billing/balance and the cloud AI spend-gate read, so a granted credit is immediately spendable.

POST /v1/billing/credit
{"org":"acme","amountCents":500,"reason":"welcome","tag":"starter-credit",
 "currency":"usd","expiresAt":"2027-01-01T00:00:00Z","idempotencyKey":"signup:acme"}

MINT-GATED. The route is registered through middleware.Mint, which puts it behind middleware.PlatformOnly and records it in middleware.MintRoutes(), so ONLY the internal service token (cloud-api → commerce, COMMERCE_SERVICE_TOKEN) or a platform global admin (auth.IAMClaims.IsSuperAdmin, owner=="admin") reaches it; every self-service / org-owner / no-auth caller is refused (403/401) BEFORE the handler. A client-supplied mint amount is exactly what must never be self-service — that is why this is mint-gated and a user cannot credit itself.

Backing: when the host injects a double-entry ledger (creditledger, set by commerce.EmbedConfig.Ledger — the cloud-embedded path), the credit is a balanced posting to the org account the AI gate reads (one ledger, no split). Standalone (no ledger injected), it appends a tagged Deposit to commerce's own datastore.

"Starter credit" is not a special case — it is a parameterized call with tag=credit.StarterCreditTag, amountCents=credit.StarterCreditCents, and expiresAt=now+credit.StarterCreditDays; the billing/credit constants are the data a caller passes, not a second code path.

Idempotent on idempotencyKey: the same key credits AT MOST ONCE.

func DeletePricingRule

func DeletePricingRule(c *zip.Ctx) error

DeletePricingRule removes a pricing rule by ID.

DELETE /v1/billing/pricing-rules/:id

func DeleteSpendAlert added in v1.36.3

func DeleteSpendAlert(c *zip.Ctx) error

DeleteSpendAlert deletes a spend alert by ID.

DELETE /v1/billing/spend-alerts/:id

func DeleteSubscriptionItem added in v1.34.0

func DeleteSubscriptionItem(c *zip.Ctx) error

DeleteSubscriptionItem removes an item from a subscription.

DELETE /v1/billing/subscription-items/:id

func Deposit

func Deposit(c *zip.Ctx) error

Deposit creates a deposit (credit) transaction for an IAM user.

POST /v1/billing/deposit

Used by internal services to add funds to a user's account (payment processor settlement, manual credit, promotional grants, etc.).

func DetachPaymentMethod added in v1.34.0

func DetachPaymentMethod(c *zip.Ctx) error

DetachPaymentMethod detaches (soft-deletes) a payment method.

DELETE /v1/billing/payment-methods/:id

func DownloadInvoicePDF added in v1.46.33

func DownloadInvoicePDF(c *zip.Ctx) error

DownloadInvoicePDF renders and serves an invoice as a PDF.

GET /v1/billing/invoices/:id/pdf

Tenant isolation: the invoice is loaded from the caller's OWN org namespace (datastore.New(org.Namespaced(c.Context()))). GetById scopes the lookup to that namespace at the storage layer, so an org can only ever fetch its own invoice — a foreign id resolves to nothing and returns 404. It is mounted on the user group so a normal authenticated org member can download their own invoice.

func FinalizeInvoice added in v1.34.0

func FinalizeInvoice(c *zip.Ctx) error

FinalizeInvoice transitions an invoice from draft to open.

POST /v1/billing/invoices/:id/finalize

func FireSpendAlerts added in v1.49.2

func FireSpendAlerts(ctx context.Context, db *datastore.Datastore, orgName string, test bool, project, service string, ev *events.Client)

FireSpendAlerts is the exported trigger the co-resident HOST calls right after it records a usage debit on the finance path. Commerce's own RecordUsage — where the internal fire runs — is NOT on the unified binary's usage path (usage goes to the finance ledger), so the host invokes this to fire the alert on the SAME crossing, reading the host-injected period spend (SetPeriodSpendReader). Standalone commerce keeps firing from RecordUsage directly; this is a no-op-safe additional entry point (idempotent per (period,level) debounce), never blocking the money path.

func GPUChargeEligibility added in v1.46.25

func GPUChargeEligibility(c *zip.Ctx) error

GPUChargeEligibility is the read-only launch gate: may a GPU of this size be launched/charged from prepaid right now?

GET /v1/billing/gpu-eligibility?user=<subj>&amountCents=<n>&minPrepaidCents=<m>

Returns 200 with {eligible,reason,...} in ALL cases (the caller decides how to render) — it never 402s, so the launch UI can show the exact remedy (add a card / add prepaid). amountCents is the immediate charge; minPrepaidCents is the 24h-minimum prepaid the GPU policy requires before launch (the gate needs prepaidAvailable >= max(amountCents, minPrepaidCents)).

func GetAutoRecharge added in v1.42.38

func GetAutoRecharge(c *zip.Ctx) error

GetAutoRecharge returns the org's auto-recharge config (or disabled defaults).

GET /v1/billing/auto-recharge

func GetBalance

func GetBalance(c *zip.Ctx) error

GetBalance returns the current balance for an IAM user.

GET /v1/billing/balance?user=hanzo/alice&currency=usd

All amounts in cents. available = balance - holds.

func GetBalanceAll

func GetBalanceAll(c *zip.Ctx) error

GetBalanceAll returns balances across all currencies for an IAM user.

GET /v1/billing/balance/all?user=hanzo/alice

func GetBankTransferInstruction added in v1.34.0

func GetBankTransferInstruction(c *zip.Ctx) error

GetBankTransferInstruction returns a single bank transfer instruction by ID.

GET /v1/billing/bank-transfer-instructions/:id

func GetBillingEvent added in v1.34.0

func GetBillingEvent(c *zip.Ctx) error

GetBillingEvent retrieves a single billing event.

GET /v1/billing/events/:id

func GetBillingStatus added in v1.37.0

func GetBillingStatus(c *zip.Ctx) error

GetBillingStatus returns a unified billing status for a user. Used by the bot gateway billing-gate to decide whether to allow LLM requests.

GET /v1/billing/status?user=<userId>

Response:

{
  "user": "alice",
  "hasPaymentMethod": true,
  "creditBalance": 500,   // cents
  "tier": "developer"
}

func GetBillingSubscription added in v1.34.0

func GetBillingSubscription(c *zip.Ctx) error

GetBillingSubscription returns a single subscription.

GET /v1/billing/subscriptions/:id

func GetCapabilities added in v1.34.0

func GetCapabilities(c *zip.Ctx) error

GetCapabilities returns the billing platform's supported features, payment methods, and currencies.

GET /v1/billing/capabilities

func GetCreditBalance

func GetCreditBalance(c *zip.Ctx) error

GetCreditBalance returns the total available credit balance for a user.

GET /v1/billing/credit-balance?userId=...

func GetCreditBalanceBreakdown added in v1.36.4

func GetCreditBalanceBreakdown(c *zip.Ctx) error

GetCreditBalanceBreakdown returns the credit balance grouped by tag. Used by Chat to distinguish trial vs paid credits.

GET /v1/billing/credit-balance/breakdown?userId=...

func GetCreditNote added in v1.34.0

func GetCreditNote(c *zip.Ctx) error

GetCreditNote retrieves a credit note by ID.

GET /v1/billing/credit-notes/:id

func GetCustomerBalance added in v1.34.0

func GetCustomerBalance(c *zip.Ctx) error

GetCustomerBalance retrieves the customer balance for a customer+currency.

GET /v1/billing/customer-balance?customerId=...&currency=...

func GetDNSUsageSummary added in v1.36.4

func GetDNSUsageSummary(c *zip.Ctx) error

GetDNSUsageSummary returns a usage summary for DNS queries, zones, and records.

GET /v1/dns/usage/summary?user={owner/name}&period=day|month

func GetDispute added in v1.34.0

func GetDispute(c *zip.Ctx) error

GetDispute retrieves a dispute by ID.

GET /v1/billing/disputes/:id

func GetInvoice added in v1.34.0

func GetInvoice(c *zip.Ctx) error

GetInvoice returns a single billing invoice by ID.

GET /v1/billing/invoices/:id

func GetMeter

func GetMeter(c *zip.Ctx) error

GetMeter returns a single meter by ID.

GET /v1/billing/meters/:id

func GetMeterEventsSummary

func GetMeterEventsSummary(c *zip.Ctx) error

GetMeterEventsSummary returns aggregated usage for a meter+user+period.

GET /v1/billing/meter-events/summary?meterId=...&userId=...&periodStart=...&periodEnd=...

func GetMyBalance added in v1.42.0

func GetMyBalance(c *zip.Ctx) error

GetMyBalance returns the calling user's balance for a given currency. Identity comes from the gateway-injected X-Org-Id / X-User-Id headers; no admin token required.

GET /v1/billing/me/balance?currency=usd

func GetOSSPayoutSummary added in v1.42.45

func GetOSSPayoutSummary(c *zip.Ctx) error

GetOSSPayoutSummary rolls up accruals per package: the running total Hanzo owes each OSS package and where it would be paid. This is the payout-ready view — the disbursement job consumes it.

GET /v1/billing/oss-payout/summary?org=

func GetPaymentConfig added in v1.42.38

func GetPaymentConfig(c *zip.Ctx) error

GetPaymentConfig returns the PUBLIC Square config (application id, location id, environment) the browser's Web Payments SDK must use to tokenize a card for THIS org. It resolves sandbox-vs-production through the SAME single authority as the charge path (org.TestMode / SQUARE_ENVIRONMENT) and the same KMS-then-env fallback, so the app id the browser tokenizes with always matches the env + access token commerce will vault/charge with. All values are public (safe to expose to the client).

GET /v1/billing/payment-config

func GetPaymentIntent added in v1.34.0

func GetPaymentIntent(c *zip.Ctx) error

GetPaymentIntent retrieves a payment intent by ID.

GET /v1/billing/payment-intents/:id

func GetPaymentMethod added in v1.34.0

func GetPaymentMethod(c *zip.Ctx) error

GetPaymentMethod retrieves a payment method by ID.

GET /v1/billing/payment-methods/:id

func GetPayout added in v1.34.0

func GetPayout(c *zip.Ctx) error

GetPayout retrieves a payout by ID.

GET /v1/billing/payouts/:id

func GetPlan added in v1.36.3

func GetPlan(c *zip.Ctx) error

GetPlan returns a single plan by slug, annotated with the active platform promo.

GET /v1/billing/plans/:id

func GetRefund added in v1.34.0

func GetRefund(c *zip.Ctx) error

GetRefund retrieves a refund by ID.

GET /v1/billing/refunds/:id

func GetSetupIntent added in v1.34.0

func GetSetupIntent(c *zip.Ctx) error

GetSetupIntent retrieves a setup intent by ID.

GET /v1/billing/setup-intents/:id

func GetSubscriptionItem added in v1.34.0

func GetSubscriptionItem(c *zip.Ctx) error

GetSubscriptionItem retrieves a subscription item by ID.

GET /v1/billing/subscription-items/:id

func GetSubscriptionSchedule added in v1.34.0

func GetSubscriptionSchedule(c *zip.Ctx) error

GetSubscriptionSchedule retrieves a subscription schedule by ID.

GET /v1/billing/subscription-schedules/:id

func GetTier added in v1.36.4

func GetTier(c *zip.Ctx) error

GetTier returns the billing tier, limits, and effective balance for a user.

For IAM-authenticated requests the tier is read from the JWT claim. For service-to-service calls the tier may be passed as a query parameter.

GET /v1/billing/tier?user=hanzo/alice

Response includes the tier config plus the effective available balance. There is no free tier: a zero-balance account has effectiveAvailable == 0 and is gated. The daily-credit term is 0 for every tier (see billing/tier); onboarding funds an account once via the starter-credit grant, and once that is spent the account is gated until it is topped up.

func GetUsage

func GetUsage(c *zip.Ctx) error

GetUsage returns usage transactions for an IAM user, filtered by tag "api-usage".

GET /v1/billing/usage?user=hanzo/alice&currency=usd

func GetUsageRollup added in v1.42.32

func GetUsageRollup(c *zip.Ctx) error

GetUsageRollup returns the unified plan + included-usage + consumed + overage + balance view for a user, for the current UTC month. This is the single read surface the console billing UI renders. All figures are derived from the same transactions the gateway's balance gate reads — no separate store.

GET /v1/billing/usage-rollup?user=hanzo/alice&plan=pro

`plan` is optional; when omitted it is resolved from the user's subscription.

func GrantAllotment added in v1.42.32

func GrantAllotment(c *zip.Ctx) error

GrantAllotment grants the calling/target user's plan-included monthly usage credit for the current UTC month, idempotently.

POST /v1/billing/allotment/grant   { "user": "hanzo/alice", "plan": "pro" }

The credit lands as an expiring balance deposit, so the gateway prepaid balance gate (available > 0) passes while the tenant is within allotment and fails closed once both the included credit and any purchased balance are exhausted. Admin token required.

func HandleProviderWebhook added in v1.37.0

func HandleProviderWebhook(c *zip.Ctx) error

HandleProviderWebhook is the single ingress for payment-provider webhooks. It dispatches to the matching processor in payment/router, validates the signature, records the event in billing_events, and — for subscription lifecycle events — updates the local subscription row keyed by ProviderId.

POST /v1/billing/webhooks/:provider

The :provider path segment is informational; signature verification picks the right processor regardless. We pass the path segment as a lightweight filter so webhook endpoints are URL-scoped per-provider (easier in Stripe dashboard configuration).

func IncludedMonthlyCents added in v1.42.32

func IncludedMonthlyCents(slug string) int64

IncludedMonthlyCents returns the recurring monthly included-usage allotment for a plan slug, in cents. Returns 0 when the plan is unknown or declares no included allotment. This is the single catalog-derived input to the monthly allotment grant — the dollar value is the plan's declared cloud credit (@hanzo/plans limits.includedCloudCredits / includedCloudCreditsPerUser, i.e. the cloud.included_credits_usd entitlement).

func IngestSBOM added in v1.42.45

func IngestSBOM(c *zip.Ctx) error

IngestSBOM stores the normalized SBOM for a built image.

POST /v1/billing/sbom

Called by the arcd build pipeline after `docker push`: it runs `syft <image> -o cyclonedx-json`, normalizes the component graph to {purl, name, ecosystem, version, scope}, and POSTs it here keyed by the immutable image digest. Idempotent on ImageDigest — re-ingesting the same image updates the record in place.

func InvoicePreview

func InvoicePreview(c *zip.Ctx) error

InvoicePreview calculates an invoice preview: usage x pricing - credits.

POST /v1/billing/invoice-preview

func ListAccountMembers added in v1.36.3

func ListAccountMembers(c *zip.Ctx) error

ListAccountMembers returns the members of a billing account (org). Currently returns the requesting IAM user as the sole member, since Commerce does not store a full membership roster (that lives in IAM).

GET /v1/billing/accounts/:id/members

func ListBalanceTransactions added in v1.34.0

func ListBalanceTransactions(c *zip.Ctx) error

ListBalanceTransactions lists balance transactions for a customer.

GET /v1/billing/balance-transactions?customerId=...

func ListBankTransferInstructions added in v1.34.0

func ListBankTransferInstructions(c *zip.Ctx) error

ListBankTransferInstructions lists bank transfer instructions, optionally filtered by customerId.

GET /v1/billing/bank-transfer-instructions?customerId=...

func ListBillingAccounts added in v1.36.3

func ListBillingAccounts(c *zip.Ctx) error

ListBillingAccounts returns billing accounts visible to the caller. In Commerce each organization is one billing account. The authenticated org is returned as the single account for the current token.

GET /v1/billing/accounts

func ListBillingEvents added in v1.34.0

func ListBillingEvents(c *zip.Ctx) error

ListBillingEvents lists billing events, optionally filtered by type or objectId.

GET /v1/billing/events?type=...&objectId=...

func ListBillingSubscriptions added in v1.34.0

func ListBillingSubscriptions(c *zip.Ctx) error

ListBillingSubscriptions lists subscriptions for a user.

GET /v1/billing/subscriptions?userId=...

func ListCreditGrants

func ListCreditGrants(c *zip.Ctx) error

ListCreditGrants lists credit grants for a user.

GET /v1/billing/credit-grants?userId=...

func ListCreditNotes added in v1.34.0

func ListCreditNotes(c *zip.Ctx) error

ListCreditNotes lists credit notes, optionally filtered by invoiceId or customerId.

GET /v1/billing/credit-notes?invoiceId=...&customerId=...

func ListDNSPlans added in v1.36.4

func ListDNSPlans(c *zip.Ctx) error

ListDNSPlans returns the available DNS plans.

GET /v1/dns/plans

func ListDisputes added in v1.34.0

func ListDisputes(c *zip.Ctx) error

ListDisputes lists disputes.

GET /v1/billing/disputes?paymentIntentId=...

func ListInvoices added in v1.34.0

func ListInvoices(c *zip.Ctx) error

ListInvoices lists billing invoices, optionally filtered by userId and status.

GET /v1/billing/invoices?userId=...&status=...

func ListMeters

func ListMeters(c *zip.Ctx) error

ListMeters returns all meters for the organization.

GET /v1/billing/meters

func ListOSSAccruals added in v1.42.45

func ListOSSAccruals(c *zip.Ctx) error

ListOSSAccruals returns accrual ledger lines, optionally filtered by package PURL or spending org.

GET /v1/billing/oss-accruals?purl=&org=

func ListPaymentIntents added in v1.34.0

func ListPaymentIntents(c *zip.Ctx) error

ListPaymentIntents lists payment intents, optionally filtered by customerId.

GET /v1/billing/payment-intents?customerId=...

func ListPaymentMethods added in v1.34.0

func ListPaymentMethods(c *zip.Ctx) error

ListPaymentMethods lists payment methods for a customer.

GET /v1/billing/payment-methods?customerId=...&type=...

func ListPayouts added in v1.34.0

func ListPayouts(c *zip.Ctx) error

ListPayouts lists payouts.

GET /v1/billing/payouts

func ListPlans added in v1.36.3

func ListPlans(c *zip.Ctx) error

ListPlans returns the list of available plans, optionally filtered by category, annotated with the active platform promo. Catalog data is embedded; the promo is admin-configured and resolved per request.

GET /v1/billing/plans
GET /v1/billing/plans?category=dns

func ListPricingRules

func ListPricingRules(c *zip.Ctx) error

ListPricingRules lists pricing rules, optionally filtered by meter or plan.

GET /v1/billing/pricing-rules?meterId=...&planId=...

func ListRefunds added in v1.34.0

func ListRefunds(c *zip.Ctx) error

ListRefunds lists refunds, optionally filtered by paymentIntentId or invoiceId.

GET /v1/billing/refunds?paymentIntentId=...&invoiceId=...

func ListSBOMs added in v1.42.45

func ListSBOMs(c *zip.Ctx) error

ListSBOMs returns the stored SBOM records (metadata only, not components).

GET /v1/billing/sbom

func ListSpendAlerts added in v1.36.3

func ListSpendAlerts(c *zip.Ctx) error

ListSpendAlerts returns the ORG's spend alerts (budgets/caps) plus derived period spend. It is the console Budgets read AND the source ScopeRules uses for the rate-limit config, so it MUST key on the same org the writer stored under.

GET /v1/billing/spend-alerts

func ListSubscriptionItems added in v1.34.0

func ListSubscriptionItems(c *zip.Ctx) error

ListSubscriptionItems lists items for a subscription.

GET /v1/billing/subscription-items?subscriptionId=...

func ListSubscriptionSchedules added in v1.34.0

func ListSubscriptionSchedules(c *zip.Ctx) error

ListSubscriptionSchedules lists subscription schedules.

GET /v1/billing/subscription-schedules?customerId=...&status=...

func ListTransactions added in v1.37.0

func ListTransactions(c *zip.Ctx) error

ListTransactions returns transactions for an IAM user, newest first.

GET /v1/billing/transactions?user=hanzo/alice&limit=100&offset=0&currency=usd

Response: { "transactions": [...], "count": N, "user": "hanzo/alice" }

func MigrateHUSD added in v1.46.38

func MigrateHUSD(c *zip.Ctx) error

MigrateHUSD moves every org's existing DB-ledger balance onto chain with zero drift (one-time). Dry-run by default (reports the snapshot + reconcile without minting); pass ?execute=true to mint. Platform-only.

POST /v1/billing/husd/migrate?execute=true

func PayInvoice added in v1.34.0

func PayInvoice(c *zip.Ctx) error

PayInvoice attempts to collect payment on an open invoice.

POST /v1/billing/invoices/:id/pay

func PortalInvoices added in v1.34.0

func PortalInvoices(c *zip.Ctx) error

PortalInvoices returns the customer's invoice list.

GET /v1/billing/portal/invoices?customerId=...

func PortalOverview added in v1.34.0

func PortalOverview(c *zip.Ctx) error

PortalOverview returns a billing summary for the authenticated customer.

GET /v1/billing/portal/overview?customerId=...

func PortalPaymentMethods added in v1.34.0

func PortalPaymentMethods(c *zip.Ctx) error

PortalPaymentMethods returns the customer's payment methods.

GET /v1/billing/portal/payment-methods?customerId=...

func PortalSubscriptions added in v1.34.0

func PortalSubscriptions(c *zip.Ctx) error

PortalSubscriptions returns the customer's subscriptions.

GET /v1/billing/portal/subscriptions?customerId=...

func ReactivateBillingSubscription added in v1.34.0

func ReactivateBillingSubscription(c *zip.Ctx) error

ReactivateBillingSubscription reactivates a canceled subscription.

POST /v1/billing/subscriptions/:id/reactivate

func ReconcileInboundTransfer added in v1.34.0

func ReconcileInboundTransfer(c *zip.Ctx) error

ReconcileInboundTransfer matches an incoming bank transfer by reference and creates a balance transaction for the customer.

POST /v1/billing/bank-transfer-instructions/reconciliation/match

func RecordDNSUsage added in v1.36.4

func RecordDNSUsage(c *zip.Ctx) error

RecordDNSUsage records a batch of DNS query usage for a zone owner. The zone's owner is looked up via the user field. Usage is checked against the plan's daily query limit.

POST /v1/dns/usage

func RecordMeterEvents

func RecordMeterEvents(c *zip.Ctx) error

RecordMeterEvents records one or more meter events (batch up to 100).

POST /v1/billing/meter-events

func RecordUsage

func RecordUsage(c *zip.Ctx) error

RecordUsage records an API usage event as a Withdraw transaction.

POST /v1/billing/usage

Creates a withdraw transaction deducting the cost from the user's balance.

func Refund

func Refund(c *zip.Ctx) error

Refund creates a deposit tagged "refund" to REVERSE a prior charge, correcting an overcharge. The metadata links back to the original transaction.

H1 (money-correctness). Previously this minted an arbitrary, uncapped credit against an UNVALIDATED originalTransactionId — a refund could exceed the original, name a non-existent or foreign transaction, refund a credit (doubling a deposit), or be replayed to double-refund. It is now fully validated and idempotent: the original MUST exist in THIS org's ledger, be a charge (Withdraw) for the SAME subject, and bound the amount (refund ≤ original); and there is AT MOST ONE refund per original transaction (keyed idempotency), so a retry replays and any second refund of the same charge is refused. Fail-closed throughout.

POST /v1/billing/refund

func ReleaseSubscriptionSchedule added in v1.34.0

func ReleaseSubscriptionSchedule(c *zip.Ctx) error

ReleaseSubscriptionSchedule releases a subscription schedule.

POST /v1/billing/subscription-schedules/:id/release

func RemoveAccountMember added in v1.36.3

func RemoveAccountMember(c *zip.Ctx) error

RemoveAccountMember is a stub. Member removal is done via IAM.

DELETE /v1/billing/accounts/:id/members/:memberId

func RemoveInvoiceLineItem added in v1.34.0

func RemoveInvoiceLineItem(c *zip.Ctx) error

RemoveInvoiceLineItem removes a line item from a draft invoice by index or line item ID.

DELETE /v1/billing/invoices/:id/line-items/:itemId

func RenewBillingSubscription added in v1.34.0

func RenewBillingSubscription(c *zip.Ctx) error

RenewBillingSubscription manually triggers a billing cycle renewal. Normally this would be automated by Temporal, but this endpoint allows manual triggering for testing and for deployments without Temporal.

POST /v1/billing/subscriptions/:id/renew

func Route

func Route(r zip.Router, args ...zip.Handler)

Route registers billing endpoints for service-to-service calls. These are internal endpoints used by Cloud-API; require admin token.

func RunAllotments added in v1.42.32

func RunAllotments(c *zip.Ctx) error

RunAllotments grants the monthly included allotment to every user with an active/trialing subscription in the request's organization, for the current UTC month. Idempotent per (user, period). Intended for the platform scheduler to invoke at period start (alongside the billing cycle).

POST /v1/billing/allotment/run

func RunAutoRechargeAllOrgs added in v1.42.38

func RunAutoRechargeAllOrgs(c *zip.Ctx) error

RunAutoRechargeAllOrgs iterates every organization and, for those with auto-recharge enabled whose available balance is below the threshold, charges the default payment method and credits the balance. Intended to be invoked on a recurring schedule (CronJob) by the platform.

POST /v1/billing/auto-recharge/run-all

func RunBillingCycle added in v1.36.4

func RunBillingCycle(c *zip.Ctx) error

RunBillingCycle processes all subscriptions whose current period has ended for the request's organization. It generates invoices and attempts collection for each due subscription.

POST /v1/billing/cycle/run

func RunBillingCycleAllOrgs added in v1.36.4

func RunBillingCycleAllOrgs(c *zip.Ctx) error

RunBillingCycleAllOrgs iterates every organization and processes due subscriptions across all of them. This is intended for the platform scheduler to invoke on a recurring basis.

POST /v1/billing/cycle/run-all

func RunBillingCycleUser added in v1.36.4

func RunBillingCycleUser(c *zip.Ctx) error

RunBillingCycleUser processes due subscriptions for a single user within the request's organization.

POST /v1/billing/cycle/run-user

func SeedPlans added in v1.49.13

func SeedPlans(ctx context.Context) (created, corrected int, err error)

SeedPlans reconciles the subscription + DNS plan authority to the embed (SyncStripe/StaticPlans read the SAME source). Safe on every boot: it creates missing plans and FORCE-CORRECTS any unmanaged partial row (Red: the bundle expansion wrote Price=0 rows the old count-gated seed then skipped) while leaving admin-edited (managed) rows authoritative. Seed values equal the embed, so it changes NO charge — it only makes prices editable + repairs bad rows. Returns (created, corrected).

func SeedRows added in v1.49.12

func SeedRows() []*plan.Plan

SeedRows projects the embedded plan catalog onto authority model rows. Typed money fields (Price/PriceAnnual/Category/ContactSales/PerSeat/…) become columns; the rich display envelope rides Metadata. This is the ONE seed source, so the DB authority starts byte-for-byte equal to the embed.

func SetAutoRecharge added in v1.42.38

func SetAutoRecharge(c *zip.Ctx) error

SetAutoRecharge upserts the org's auto-recharge config.

PUT /v1/billing/auto-recharge

Enabling requires a default payment method on file (the card that will be charged off-session when the balance runs low).

func SetDefaultPaymentMethod added in v1.34.0

func SetDefaultPaymentMethod(c *zip.Ctx) error

SetDefaultPaymentMethod sets the default payment method for a customer.

POST /v1/billing/customers/:id/default-payment-method

func SetOrgTestMode added in v1.42.38

func SetOrgTestMode(c *zip.Ctx) error

SetOrgTestMode toggles the org's live flag (org.Live) and its test-mode view. org.Live marks transactions Test=true and is the FALLBACK Square-environment signal: when the deployment does NOT set SQUARE_ENVIRONMENT, a test org uses Square sandbox and a live org uses production (via org.TestMode). When the deployment DOES set SQUARE_ENVIRONMENT (the per-env authority: mainnet=production, testnet/devnet=sandbox), that env governs which Square environment is charged regardless of this flag — on mainnet there is no sandbox charge. Admin-only — a user must not be able to move their own org to sandbox to dodge real charges.

POST /v1/billing/test-mode   { testMode: bool }

func SetPeriodSpendReader added in v1.49.2

func SetPeriodSpendReader(f PeriodSpendFunc)

SetPeriodSpendReader installs the host's period-spend source. Pass nil to clear (standalone commerce). Set once at boot, read per request; safe for concurrent use.

func SettleHUSD added in v1.46.38

func SettleHUSD(c *zip.Ctx) error

SettleHUSD sweeps every org's on-chain drift back to the treasury (metered usage settled org→treasury). Platform-only, CronJob-driven. Idempotent (self-correcting drift). Returns the per-org settlement outcomes.

POST /v1/billing/husd/settle

func StatusHUSD added in v1.46.38

func StatusHUSD(c *zip.Ctx) error

StatusHUSD reports the chain-ledger configuration + whether it is enabled — a read-only observability surface (no secrets: the treasury key is never exposed).

GET /v1/billing/husd/status

func SubmitDisputeEvidence added in v1.34.0

func SubmitDisputeEvidence(c *zip.Ctx) error

SubmitDisputeEvidence submits evidence for a dispute.

PATCH /v1/billing/disputes/:id

func SubscribeWithCard added in v1.49.5

func SubscribeWithCard(c *zip.Ctx) error

SubscribeWithCard vaults a Square card nonce as a reusable card-on-file, charges it for the plan's FIRST period at the SERVER-AUTHORITATIVE catalog price, and creates the subscription — all server-side, in one transaction of intent. The settled charge IS the mint authority (mirrors topup_token's mintauth.WithAuthorized rationale), so it creates the paid-tier subscription WITHOUT the CreateBillingSubscription C1-a mint gate (which forbids a self-serve paid tier with zero payment). The plan's INCLUDED monthly credits flow through the existing allotment path unchanged; the plan FEE is NOT credited to the spendable AI-credit wallet (a subscription is not a top-up).

POST /v1/billing/subscribe/card

Body: { sourceId, planId, userId?, quantity?, currency? } — NO client amount: the price is the plan's catalog price, always. Header (optional): X-Idempotency-Key — a retry/double-submit with the same key (or, absent a key, the same single-use nonce) never double-charges: it replays the first result. Returns: { subscriptionId, invoiceId, planId, amountCents, currency, status }

func SyncHUSD added in v1.46.38

func SyncHUSD(c *zip.Ctx) error

SyncHUSD runs one indexer pass — the backfill + reconcile safety net behind the synchronous mint-time projection. Driven by an external CronJob (mirrors the contributor-payout execute endpoint). Platform-only (touches the money ledger).

POST /v1/billing/husd/sync

func TierCheck added in v1.36.4

func TierCheck(c *zip.Ctx) error

TierCheck is a lightweight endpoint for model-access gating. It returns the tier config and whether a specific model is allowed, without computing the full balance. Used by Chat and white-label services.

GET /v1/billing/tier-check?user=hanzo/alice&model=zen4-max

func TokenizeCard added in v1.36.3

func TokenizeCard(c *zip.Ctx) error

TokenizeCard accepts raw card data server-side and returns a provider token. Raw PAN is never stored; it is forwarded directly to the configured payment provider and discarded.

Card tokenization should be done client-side using the Square Web Payments SDK. This endpoint returns 503 as server-side tokenization requires PCI DSS Level 1 compliance. Use the Square Web Payments SDK (SqPaymentForm) instead.

POST /v1/billing/card/tokenize

func Topup added in v1.36.4

func Topup(c *zip.Ctx) error

Topup charges a saved payment method and credits the user's balance.

POST /v1/billing/topup

Body: { userId, paymentMethodId, amountCents, currency? } Returns: { transactionId, balanceCents, status }

func TopupWithToken added in v1.37.0

func TopupWithToken(c *zip.Ctx) error

TopupWithToken charges a Square Web Payments SDK nonce and credits the org's canonical balance. Use this for one-time card top-ups without saving a payment method first — the cold-customer "add credits" path.

POST /v1/billing/topup/token

Body: { sourceId, amountCents, currency? } Header (optional): X-Idempotency-Key — a retry/double-submit with the same key (or, absent a key, the same (subject, amount) inside a 15-minute window) never double-charges or double-credits; it replays the first result. The same key is forwarded to Square, so the charge is exactly-once at the processor even if the local guard store is down. Returns: { transactionId, balanceCents, status }

func UpcomingInvoice added in v1.34.0

func UpcomingInvoice(c *zip.Ctx) error

UpcomingInvoice generates a preview of the next invoice for a subscription.

GET /v1/billing/invoices/upcoming?userId=...&subscriptionId=...

func UpdateBillingSubscription added in v1.34.0

func UpdateBillingSubscription(c *zip.Ctx) error

UpdateBillingSubscription updates a subscription (plan change, quantity).

PATCH /v1/billing/subscriptions/:id

func UpdateMemberRole added in v1.36.3

func UpdateMemberRole(c *zip.Ctx) error

UpdateMemberRole is a stub. Role updates are done via IAM.

PATCH /v1/billing/accounts/:id/members/:memberId

func UpdatePaymentMethod added in v1.34.0

func UpdatePaymentMethod(c *zip.Ctx) error

UpdatePaymentMethod updates a payment method.

PATCH /v1/billing/payment-methods/:id

func UpdateSpendAlert added in v1.36.3

func UpdateSpendAlert(c *zip.Ctx) error

UpdateSpendAlert patches an existing spend alert / cap. Only the fields present in the body change; the rest are preserved.

PATCH /v1/billing/spend-alerts/:id

func UpdateSubscriptionItem added in v1.34.0

func UpdateSubscriptionItem(c *zip.Ctx) error

UpdateSubscriptionItem updates a subscription item (e.g. seat count).

PATCH /v1/billing/subscription-items/:id

func UpdateSubscriptionSchedule added in v1.34.0

func UpdateSubscriptionSchedule(c *zip.Ctx) error

UpdateSubscriptionSchedule updates phases or end behavior.

PATCH /v1/billing/subscription-schedules/:id

func VoidCreditGrant

func VoidCreditGrant(c *zip.Ctx) error

VoidCreditGrant voids a specific credit grant, making it unusable.

POST /v1/billing/credit-grants/:id/void

func VoidCreditNote added in v1.34.0

func VoidCreditNote(c *zip.Ctx) error

VoidCreditNote voids a credit note.

POST /v1/billing/credit-notes/:id/void

func VoidInvoice added in v1.34.0

func VoidInvoice(c *zip.Ctx) error

VoidInvoice voids a draft or open invoice.

POST /v1/billing/invoices/:id/void

func Withdraw added in v1.37.0

func Withdraw(c *zip.Ctx) error

Withdraw creates a withdrawal transaction for an IAM user.

POST /v1/billing/withdraw

Used when a user explicitly moves funds out of their Commerce balance (e.g. funding a bot wallet, manual withdrawal). Non-admin callers may only withdraw from their own account; admin callers may withdraw on behalf of any user.

Fails with 402 if the user has insufficient available balance.

func ZapDispatch

func ZapDispatch(c *zip.Ctx) error

ZapDispatch is the single ZAP-over-HTTP endpoint for billing.

Types

type BackfillOptions added in v1.49.2

type BackfillOptions struct {
	Org    string         // single org name to replay; empty = every org
	Since  time.Time      // only replay transitions at/after this instant; zero = all history
	DryRun bool           // count only, emit NOTHING
	Events *events.Client // collector client; nil (or DryRun) => nothing is posted
}

BackfillOptions bounds one backfill run.

type BackfillReport added in v1.49.2

type BackfillReport struct {
	DryRun bool
	Orgs   []OrgBackfill
	Totals map[string]int // event name -> fleet total
	Total  int
}

BackfillReport is the run summary across every org walked.

func BackfillEvents added in v1.49.2

func BackfillEvents(ctx context.Context, opts BackfillOptions) (*BackfillReport, error)

BackfillEvents walks every organization once — root-namespace org list, then each org's own namespace — the SAME walk api/metrics.buildRollup uses, and replays each org's existing subscriptions, invoices, and api-usage transactions as lifecycle events. In DryRun it only tallies what WOULD be emitted; otherwise it fires each event best-effort through the deterministic-id backfill emit.

type OrgBackfill added in v1.49.2

type OrgBackfill struct {
	Org           string
	Subscriptions int            // subscription rows scanned
	Invoices      int            // invoice rows scanned
	Usage         int            // api-usage transaction rows scanned
	Emitted       map[string]int // event name -> count
	Total         int
}

OrgBackfill is one org's tally: how many source rows were scanned and, per event name, how many lifecycle events were (or in dry-run WOULD be) emitted.

type PeriodSpendFunc added in v1.49.2

type PeriodSpendFunc func(ctx context.Context, org string, test bool, project, service string) (int64, error)

PeriodSpendFunc reports a scope's cumulative spend (cents) in the CURRENT UTC period for an org — the value scopeExhausted/warn compare a cap against. The HOST injects it (SetPeriodSpendReader) so the cap reads the SAME ledger the host records usage in. In the co-resident cloud binary usage is recorded on the FINANCE ledger (fin.RecordUsage), NOT commerce's own transaction store — which the unified binary leaves empty — so without this the cap would sum 0 and never enforce. nil (standalone commerce) → the append-only transaction-ledger query below, unchanged.

type Plan added in v1.42.20

type Plan struct {
	Slug        string
	Name        string
	Description string
	Category    string
	PriceMonth  int64
	PriceYear   int64
	Currency    string
}

Plan is the exported snapshot used by external seeders (e.g. the Stripe parity seed in commerce.go). It mirrors the subset of fields the seed populates onto seed.Plan, with field names that match the caller's expectations (PriceMonth / PriceYear are cent-denominated monthly + annual prices). Internal callers stick with staticPlan; this type exists so the public surface doesn't leak the unexported shape and so we can evolve them independently.

func LookupStaticPlan added in v1.37.0

func LookupStaticPlan(slug string) *Plan

LookupStaticPlan resolves a single plan by slug from the embedded catalog and returns it in the exported Plan shape. Returns nil when the slug is unknown. It is the single-plan analogue of StaticPlans and shares the same staticPlan -> Plan projection, so external seeders (e.g. cmd/grant) never touch the unexported wire type.

func StaticPlans added in v1.37.0

func StaticPlans() []Plan

StaticPlans returns a snapshot of the embedded plan catalog as the exported Plan shape. The slice is freshly allocated so callers may mutate freely without bleeding into the canonical hanzoPlans var.

Jump to

Keyboard shortcuts

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