# Sell Credit Packs

Make a credit pack in the console, price it in each currency, sell it in your app, and follow, grant, revoke, change and archive the credits it sells.

A credit pack is a number of credits your customers buy at a price: 1,000 credits for $10. You make it once in the console, your app sells it with `openCreditStore()` or `CreditStorePage`, and every purchase lands in the workspace's credit balance, which `useCreditBalance` reads and `useConsumeCredits` spends ([Credits overview](/credits/overview)).

> **Note:**

- Stripe connected ([Connect Stripe](/billing-setup/connect-stripe)); the **Credits** part of the **Billing** menu shows once it is.
- Your billing currencies saved under **Settings** > **General** ([Your catalog](/billing-setup/catalog)): a pack is priced in each.
- Credit packages on your BuildBase plan, which also sets how many you may keep and how long purchased credits may last.

[Open credit packages in the console](https://console.buildbase.app/dashboard/admin/subscriptions/credit-packages)

## 1. Open credit packages

In the **Billing** menu, under **Credits**, choose **Credit packages**, then **New credit package**.

![Credit packages, empty, with New credit package highlighted as step 1](/images/credits/credit-packages/console-packages-list.webp)

## 2. Describe the pack

Under **Package details**, give it a **Name**, a **Slug** and a **Description**, and in **Credit amount** the credits one purchase gives. **Sort order** places it among your packs, and only an **Active** pack is offered to your customers.

![Package details: Name 1,000 credits, Slug 1000-credits, a description, Credit amount 1000 highlighted as step 2, Sort order and Active](/images/credits/credit-packages/console-package-details.webp)

## 3. Choose when the credits expire

Off, purchased credits stay until they are used (**Never expires**). On, they expire the number of days after purchase you type. When your BuildBase plan caps how long credits may last, the switch stays on and the card says the most days it allows.

![Expires after 365 days, with the switch highlighted as step 3](/images/credits/credit-packages/console-package-expiry.webp)

## 4. Price it in each currency

Under **Pricing**, type a price for each billing currency in its usual unit (9.99 for $9.99); 0 leaves a currency out. Press **Create package**: BuildBase creates the Stripe prices for you.

![Pricing with EUR 9.00 and USD 10.00, and Create package highlighted as step 4](/images/credits/credit-packages/console-package-pricing.webp)

## 5. The customer buys it

In your app, `openCreditStore()` opens the **Credits** screen of the workspace settings, where **Buy Credits** opens **Buy Credit Packages** with your active packs, their price and how long their credits last. A pack is paid through Stripe Checkout, and its credits are added once Stripe confirms the payment.

![Buy Credit Packages for Jordan Lee's Workspace: 1,000 credits, valid for 365 days, $10.00, with Buy 1,000 Credits highlighted as step 5](/images/credits/credit-packages/app-credits-screen.webp)

## 6. See the balance

In the console, open the workspace (**User management** > **Workspaces**, then its row). The **Credit balance** card shows what it has **Available**, what is **Held** for work in progress, and the totals granted, consumed and expired. Below it, **Credit transactions**, **Credit holds** and **Credit buckets** list each movement, each open hold and each lot of credits with its expiry.

![The workspace's Credit balance: 1,000 Available highlighted as step 6, 0 Held, 1,000 Total granted, with Reconcile, Grant credits and Revoke credits](/images/credits/credit-packages/console-credit-balance.webp)

## The credit ledger

**Billing** > **Credit ledger** lists every credit movement in your organization: each row's **Customer**, **Type** (**Purchased**, **Plan grant**, **Consumed**, **Expired**, **Admin grant**, **Admin revoke**, **Refund**), **Amount**, **Balance after**, **Package** and **Description**. Filter it by type or workspace.

![Credit ledger, System-wide credit transactions: the Purchased row, +1000, balance after 1000, package 1,000 credits, with Purchased highlighted as step 7](/images/credits/credit-packages/console-credit-ledger.webp)

## Grant and revoke credits

On the workspace's **Credit balance** card, **Grant credits** gives a whole pack's credits for free: choose the **Credit package**, add a **Description (optional)**, and press **Grant**. The credits expire as the pack's do.

![Grant credits with the Credit package 1,000 credits, expiring in 365 days, highlighted as step 8, and a description](/images/credits/credit-packages/console-grant-credits.webp)

**Revoke credits** takes credits back: type the amount under **Amount (max: N)**, at most what is available, add a **Reason (optional)**, and press **Revoke**. Both appear in the ledger as **Admin grant** and **Admin revoke**.

![Revoke credits with Amount (max: 1000) at 100 highlighted as step 9, and a reason](/images/credits/credit-packages/console-revoke-credits.webp)

On the same page, an open hold that will never settle can be ended with **Release**, and **Reconcile** recomputes a balance from its buckets when it looks out of step.

## Changing a sold pack

Press **Edit** on the pack's row. Its name, description, order and **Active** change in place, and so do its credits, prices and expiry while nothing holds it. Once a sale, a plan grant or an automatic top-up holds it, a change to those is refused with `VERSION_REQUIRED`, and the page offers to carry it to a new draft version, which **Versions** lists; buyers keep the terms they paid for. A currency not priced yet can still be added in place. The card **Version moves** sets what publishing a new version does to the automatic top-ups that buy an older one:

- **Keep auto top-ups on their version**: nothing changes for them; new ones buy the new version.
- **Move auto top-ups that only gain**: a top-up that gets more credits for the same price or less moves at once.
- **Move gains, and ask about the rest**: gains move at once, and a payer for whom the new version is not better is told, and moves only if they agree.

![Edit: 1,000 credits with the notice What it sells is held, and Versions and Version moves highlighted as step 10](/images/credits/credit-packages/console-package-versions.webp)

## Taking a pack off sale

Switch **Active** off to stop new sales at once, or press **More actions** on its row, then **Archive**, to take it off sale and deactivate its Stripe prices. Credits already bought or granted from it stay.

![The pack's More actions menu with Archive highlighted as step 11](/images/credits/credit-packages/console-package-archive.webp)

## Check that it worked

The purchase shows in the **Credit ledger** as **Purchased**, with the balance after it, and the workspace's **Credit balance** rises by the pack's credits. `useCreditBalance` reads the same balance, and your webhook endpoint receives `credit.purchased`.

## Things to watch out for

- **No billing currencies, no prices.** The **Pricing** card says "No billing currencies configured" until you save them, and a pack needs a price above 0 in at least one currency ("At least one currency must have a price greater than 0.").
- **A grant takes a whole pack, and a workspace only.** A person's own wallet is shown on their page, read only.
- **Archiving is refused** (`CREDIT_PACKAGE_IN_USE`) while a plan version grants the pack, an automatic top-up buys it or credits from it are left; switch **Active** off meanwhile.
- **A saved-card top-up does not compute tax**, so an organization that collects tax sells packs through checkout ([Auto top-up](/credits/overview#auto-top-up)).
- **Spending more than the balance** is refused with `402 INSUFFICIENT_CREDITS`, with `available` and `requested`; releasing a hold that already settled answers `HOLD_NOT_OPEN`.

## Next steps

- [Credits overview](/credits/overview) - spend, hold and top up credits from your app and server
- [Plan credits](/credits/plan-credits) - give credits with a plan
- [Quotas](/credits/quotas) - a monthly allowance instead of a balance
