Skip to main content

Billing Overview

The AIQLick billing system spans two services that share a single PostgreSQL database. The backend (NestJS) owns plan management, Stripe integration, and credit allocation. The background-tasks service (FastAPI) enforces billing rules before executing AI operations and records consumption.

Architecture

Backend Responsibilities

  • Plans and subscriptions -- defining subscription tiers and syncing state with Stripe.
  • Credit packs -- purchasable credit bundles processed through Stripe Checkout.
  • Stripe webhooks -- handling invoice.paid, invoice.payment_failed, charge.refunded, and checkout.session.completed events.
  • Invoices -- generating and tracking invoice records tied to Stripe payment intents.
  • Promo codes -- percentage or fixed-amount discounts, invitation-based codes, and reseller bundles.
  • Credit replenishment -- a daily cron job at 2 AM that tops up credits on a 30-day cycle.

Background-Tasks Responsibilities

  • BillingGate -- the enforcement layer that runs before every billable AI operation.
    1. pre_check() -- verifies billing context, resolves billing mode, checks subscription status, plan limits, and credit balance.
    2. The AI pipeline executes.
    3. check_and_consume() -- deducts credits (PREPAID) or logs usage (POSTPAID) and writes an AIOperationLog entry.
    4. log_failure() / log_rejected() -- records failed or rejected operations for audit trail.
  • Gradual rollout -- billing enforcement is controlled by the BILLING_ENABLED environment variable, allowing incremental activation across environments.

Both services read and write the same PostgreSQL database. Schema changes are managed exclusively through Prisma in the backend; background-tasks uses raw AsyncPG queries.

Billing Enforcement Status

Complete status of billing integration across all pipeline operations:

OperationExternal ServiceBillablepre_checkcheck_and_consumeNotes
CV ExtractionClaude Sonnet 4.5YesYesYesReference implementation
Job ParsingClaude Sonnet 4.5YesYesYes
Meeting InsightClaude Haiku 4.5YesYesYes
Text RewriteClaude Haiku 4.5YesYesYes
Agent ChatAmazon Nova LiteYesYesYes
Face ExtractionAWS RekognitionYesYesYes
User-Job MatchingNone (internal scoring)No----CPU-only, no external AI calls
Candidate-Job MatchingNone (internal scoring)No----CPU-only, no external AI calls
Basic MatchingNone (internal scoring)No----CPU-only, no external AI calls
Add CandidateNone (CPU-only pipeline)No----Validation + DB operations only
Inbound Job EmailClaude Sonnet 4.5YesYesVia JobParsingServiceWorker runs pre_check, billing via underlying service
Inbound CV EmailClaude Sonnet 4.5YesYesVia CVExtractionServiceWorker runs pre_check, billing via underlying service
TranscriptionAWS TranscribeNo----Managed AWS service, billed via AWS directly
Task/Metrics SubscriptionsNoneNo----System monitoring, not billable

Gradual Rollout (BILLING_ENABLED)

The BILLING_ENABLED environment variable controls billing enforcement for PREPAID plans:

BILLING_ENABLEDPREPAID BehaviorPOSTPAID Behavior
false (default)Operations logged with credits_cost=0 but not charged. Pre-checks pass.Operations always logged to AIOperationLog (source of truth for invoicing). UNPAID blocking still enforced.
trueFull enforcement: pre-check validates subscription + limits + balance. Credits deducted after execution.Same as above -- POSTPAID always logs regardless of flag.
info

Enterprise (POSTPAID) blocking is always enforced, even when BILLING_ENABLED=false. This prevents blocked companies from bypassing access control via the feature flag.

Credit Routing

Credits are routed based on the user's current view mode and company context:

ModeConditionBalance Used
EMPLOYERselectedCompanyId is setCompany credit balance
JOB_SEEKERNo company contextUser's personal credit balance

This routing applies to both consumption (background-tasks) and balance queries (backend).

Plans

Plans define subscription tiers with the following properties:

  • 16 feature limits -- each field uses a consistent convention: -1 means unlimited, 0 means disabled, and any positive integer is the specific limit.
  • creditsPerMonth -- the number of credits allocated on each billing cycle.
  • Stripe sync -- each plan maps to a Stripe Product and Price for recurring billing.

Plans are company-scoped. When a company subscribes to a plan, all users operating under that company inherit its limits.

Subscriptions

Subscriptions are company-based, not per-user. Key characteristics:

  • Tied to a single Company entity in the database.
  • Status is synchronized with Stripe (ACTIVE, PAST_DUE, CANCELED, TRIALING, INCOMPLETE).
  • Expiry warnings are sent at 7, 3, and 1 days before expiration via a daily cron job at 9 AM.

Credit Balance

Each credit balance record is scoped to either a company or a user, enforced by a database-level XOR constraint -- a balance row must have exactly one of companyId or userId set, never both.

ScopeUse Case
Company balanceEmployer-mode AI operations, team-shared credits
User balanceJob seeker AI operations, personal credit packs

Credit Transactions

Every credit movement is recorded as an immutable CreditTransaction with one of the following types:

TypeDescription
PLAN_ALLOCATIONMonthly credit top-up from the active subscription plan
PACK_PURCHASEOne-time credit pack bought through Stripe Checkout
CONSUMPTIONCredits deducted when an AI operation completes
MANUAL_ADJUSTMENTAdmin-initiated balance correction
INITIAL_GRANTCredits granted on account creation (9 credits by default for job seekers)
REFUNDCredits returned after a Stripe refund event
TRANSFERCredits moved between balances — personal↔company or company↔company — via transferCredits

Credit Packs

Credit packs are purchasable bundles that provide a one-time credit deposit. Key rules:

  • Purchased through Stripe Checkout sessions.
  • Credits always land in the purchasing user's personal balance, regardless of their current company context.
  • To fund a company balance, the billing owner uses the transferCredits mutation to move credits from their personal balance (or another company they billing-own) to the target company. Transfers run in both directions: personal↔company and company↔company. See Credit Transfers for the full matrix.

Stripe Integration

The backend processes four Stripe webhook events:

EventAction
invoice.paidAllocate plan credits, activate or renew subscription
invoice.payment_failedMark subscription as past due, notify billing owner
charge.refundedCredit the refunded amount back to the appropriate balance
checkout.session.completedFulfill credit pack purchase, apply promo code if present

All webhook handlers are idempotent -- duplicate event deliveries do not produce duplicate transactions.

Promo Codes

Promo codes support three distribution models:

  • Percentage discount -- reduces the price of a subscription or credit pack by a percentage.
  • Fixed amount -- subtracts a fixed dollar amount from the purchase price.
  • Invitation and reseller bundles -- codes tied to referral campaigns or reseller agreements that grant bonus credits or extended trials.

Credit Replenishment

A scheduled cron job runs daily at 2 AM and processes credit replenishment for all active subscriptions:

  • Checks each subscription's 30-day billing cycle.
  • Allocates creditsPerMonth from the plan as a PLAN_ALLOCATION transaction.
  • Credits are additive, not reset -- unused credits from previous cycles carry forward.

Enterprise Post-Paid Billing

For enterprise customers, the platform supports a post-paid billing model where companies receive unlimited platform access without upfront payment. Instead of purchasing credits, enterprise companies are invoiced monthly based on actual AI usage.

Key differences from prepaid:

  • Plans with billingMode: POSTPAID bypass all credit checks in the BillingGate.
  • AI operations are still logged to AIOperationLog (source of truth for invoice generation) but no credits are deducted.
  • A monthly cron job generates Stripe invoices based on aggregated usage, with a 5-day payment window.
  • Overdue invoices trigger automatic access blocking (UNPAID subscription status).
  • Admin API provides full subscription, usage breakdown, and invoice management.

See Enterprise Post-Paid Billing for full details.

Job Seeker Initial Credits

New job seeker accounts receive an INITIAL_GRANT of 9 credits by default. This value is configurable and allows job seekers to use AI features before purchasing a credit pack.