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
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 whencheck returns allowed: false or track returns 409 insufficient_credits. The customer doesn’t need a plan. Attach it with addOnId and redirect to Checkout:
{ 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
creditAmountorpriceCentsreturns409 purchase_pendinguntil 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.