Skip to main content
A credit pack is a one-time purchase: a fixed creditAmount for a priceCents. Customers buy one when they run out before their plan renews, or instead of a plan. Pack credits never expire, and Ledger spends them after the plan allowance. In the API and the JSON file, packs are add-ons with type: "credit_pack" (/v1/add-ons, addOnId).

Define a pack

Publish with npx integrateledger-cli push. Packs aren’t synced to Stripe ahead of time; Ledger prices each Checkout when it opens.

Sell it

Offer the pack when check returns allowed: false or track returns 409 insufficient_credits. The customer doesn’t need a plan. Attach it with addOnId and redirect to Checkout:
The response is { checkoutUrl, addOnPurchaseId }. Ledger grants the credits when Stripe’s signed checkout.session.completed event confirms the payment; Stripe also sends the customer an invoice with a line such as “Top-up – 500 credits”. Balances shows the purchase history. Setting up Checkout redirects and testing are covered in Display billing.

Rules

  • One open pack Checkout at a time. Attaching a different pack while one is open returns 409 purchase_pending. Attaching the same pack returns the same URL. Stripe expires an unpaid Checkout after 24 hours.
  • Prices lock while a Checkout is open. Changing the pack’s creditAmount or priceCents returns 409 purchase_pending until it completes or expires. Renaming is fine.
  • Archiving stops new sales. Removing a pack from the file archives it; a Checkout already open can still complete.
  • Refunds happen in Stripe. A full refund expires the pack’s unused credits; credits already spent stay spent, so the balance never goes negative. A partial refund changes no credits. A lost dispute expires the unused credits as a full refund does. See Refunds and disputes.
Other ways. Packs can also be managed in the dashboard under Add-ons, or with the add-on endpoints.