Skip to content

Credits

Credits let a Customer prepay or receive a balance that its metered calls draw down, checked before each call and settled on the Invoice.

Credits let a Customer prepay or receive a balance that its metered calls draw down. Each call checks the balance as a Limit first, and the Invoice settles what was spent.

Contract

A balance is a set of Credit Grants. db.sb keeps the live balance, and Stripe settles it when each Invoice finalizes.

CategoryComes fromBooks asIssued by
paidAn Order for an Offer that sets Offer.credit, such as a $50 packCash on purchase, deferred revenue until spentOrder.pay
promotionalA gift: a launch bonus, an apology, a referral rewardAn expense when spent, never cashCreditGrant.issue
RuleDetail
Before each callThe Meter’s next unit is checked against CreditGrant.remaining. At zero, the Offer’s bound applies: stop, bill overage through the Meter, or upgrade.
After each callCreditGrant.remaining drops once per metered Event, never twice.
Order of usePromotional grants spend first, then the lowest CreditGrant.priority, then the earliest CreditGrant.expiresAt.
ScopeCreditGrant.appliesTo holds a grant to one metered Offer; without it, the grant pays for any metered Offer of the Startup.
SettlementCreditGrant.apply pays the metered lines of each finalizing Invoice through Stripe credit grants.
ExpiryA balance lapses at CreditGrant.expiresAt. CreditGrant.void ends a promotional grant early and tells the Customer why.
RechargeCustomer.creditRecharge buys another pack when the balance falls below its floor, charged to the default Payment Source.
Closed loopCreditGrant.apply spends credit only on the Startup’s own metered Offers: never transferred, never spent at another Startup, never paid out.

Verbs

Interfaces

Example

TypeScript
import { $ } from 'startup-builder'

// routewise.dev sells routes at $0.002 each. A logistics team bought the $50 credit pack,
// and Order.pay issued a paid Credit Grant. Add a $10 launch bonus that lapses at year end.
await $.CreditGrant.issue({
  customer: 'customer_1',
  amount: { amount: 10, currency: 'USD' },
  category: 'promotional',
  expiresAt: '2026-12-31T23:59:59Z',
})

// When the balance falls below $5, buy another $50 pack with the default card.
await $.Customer.update({ id: 'customer_1', creditRecharge: { below: 5, amount: 50, offer: 'offer_credit_pack' } })

// After 27,600 routes ($55.20, the bonus spent first), the balance falls to $4.80 and the recharge runs.
const creditGrants = await $.CreditGrant.list({ where: 'remaining.amount > 0' })