PPalladium AI
HomeFeaturesPricingDevelopersBlog
PPalladium AI
Docs
Sign InSign Up
Back to Blog
ProductJune 6, 20266 min read

Billing Balance, Admin API Configuration, and a Live Marketplace

Three interconnected features shipped together: a linear-decay plan balance card that shows exactly how much value remains in the current billing period, a platform-owner API Configuration console for managing the product catalog, and a developer marketplace that now merges built-in and custom products in real time.


Overview

The previous billing page showed a subscription card and an invoice list but gave subscribers no sense of how much of their plan value they had already consumed. The developer marketplace displayed a hardcoded list of built-in API products with no mechanism for the platform owner to extend or adjust the catalog without a code change.

These enhancements close both gaps. A new billingAccounts table tracks the start of each billing period, enabling a server-side balance computation that decays linearly across the period. A new apiConfigs table lets platform owners publish, edit, and retire API products without touching source code, and the marketplace page reads from both the static catalog and Convex simultaneously.

Plan balance card — linear decay

When a team subscribes to a paid plan, the checkout mutation now does three things instead of two: it creates the subscriptions record, inserts the invoices record, and upserts a row in the new billingAccounts table, stamping billingStart to the current time. Every subsequent read of billing.getRemainingBalance applies the formula:

remaining = planAmount × (1 − elapsed / periodMs)

The query also handles roll-overs on read: if the stored billingStart is more than one period in the past, it advances the start date forward by the required number of full periods before computing the remaining fraction. This keeps the card accurate even if the background cron fires late or the team is on a non-30-day plan.

The billing page renders the result as a card with three pieces of information: a colour-coded decay bar (green above 50%, amber between 20% and 50%, red below 20%), a “K{remaining} of K{planAmount}” label, and a days-remaining / period-end line. Teams without a paid subscription see a “Subscribe to a paid plan” empty state instead.

Daily cron — advancing billing periods

A new convex/crons.ts file registers a Convex cron job that runs every day at midnight UTC. It calls the billing.advanceBillingPeriods internal mutation, which scans every row in billingAccounts and advances billingStart for any account whose current period has elapsed. This keeps the stored start date tidy and ensures that the balance formula always reflects the most recent period even when the client has been idle.

Because the getRemainingBalance query also handles roll-overs on read, the cron is an optimisation rather than a correctness requirement — the balance card will never show a stale number regardless of whether the cron has fired.

Admin API Configuration console

Platform owners now have a dedicated /dashboard/admin/apis page for managing the API product catalog. Every product is stored as a document in the new apiConfigs Convex table with the following fields: name, description, gateway endpoint, documentation path, status (active or draft), and an inline plans array.

The page layout is a summary strip at the top (total products, active count, total plan count) followed by a grid of product cards. Each card shows the name, description, gateway endpoint, and a status badge. An activate/draft toggle switches visibility in the marketplace without deleting the product. Edit and delete actions open modal dialogs.

Expanding a product card reveals its plans accordion: a compact table with columns for plan name, price label, quota (calls/month), rate limit (calls/min), and a billing mode badge (Free, Fixed, or Metered). Each row has edit and remove buttons. The “Add plan” dialog uses a three-button group to select the billing mode visually, making it impossible to submit a plan without choosing one. All write operations go through apiConfigs Convex mutations that verify the caller holds the platform_owner global role before proceeding.

Live API Marketplace

The developer marketplace at /dashboard/[teamId]/apis has been converted from a server component to a client component so it can subscribe to live Convex data. On mount it fires two concurrent data sources: the existing static product list from lib/api-marketplace.ts (Risk Score API, KYC Verify API, Ledger Events API) and the new api.apiConfigs.listActive query that streams only products with status: "active".

While the Convex query resolves, the dynamic products section shows skeleton cards to avoid layout shift. Convex-managed products render with a Custom badge and display their full plans table inline — price label, monthly quota, rate limit, and a billing mode badge per row. Each plan row ends with a “Select → billing” link that passes the subscription parameters to the billing checkout page via URL query params, so the checkout flow requires no extra clicks.

Because the product catalog is now live data, a platform owner can publish a new API product from the admin console and watch it appear in the marketplace immediately — no deployment required.

Data model changes

Two new tables were added to convex/schema.ts:

  • billingAccounts — one row per team; stores billingStart (ms epoch), billingPeriodDays, and planAmount (numeric value parsed from the plan's price label, e.g. "K30/month" → 30).
  • apiConfigs — one row per API product; stores all catalog metadata including an inline plans array so plan data travels with its product in a single read.

What's next

The billing model is designed to accommodate real payment processing. The next step is wiring a Stripe checkout session to the checkout mutation so that paid plans require successful card authorisation before the subscription record is written. Metered billing will follow once the API gateway proxy layer is in place and can emit per-request usage events.

On the marketplace side, the next planned feature is a per-product API key provisioning flow triggered directly from the plan selection step, so developers get a usable key immediately after subscribing.

Built by Palladium AI. Multi-tenant finance infrastructure with open foundations on GitHub.