Credits
Transactional credits for Bijection background jobs: reserve, complete, release, refund, and reconcile.
git clone https://github.com/bijectionhq/credits.git
cd credits
git checkout e5da372a6fb082cdef168d7c82361a6e0e2c7330
cd packages/convex-creditsBijection repository access is required. Request access.
Description
Transactional credits for Bijection background jobs: reserve, complete, release, refund, and reconcile.
Explore the package README for API concepts, configuration, and examples. Check the Bijection source for adaptation-specific setup.
Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.
Getting started
- Get the source at the revision above and read its package documentation.
- Check the required Bijection SDK version, dependencies, and external service credentials.
- Follow the package setup instructions and the guide to using components.
- Exercise the component in your deployment according to your project’s verification rules.
Open source
Maintained source: bijectionhq/credits. Based on clipinfit/convex-credits. License: Apache-2.0. Consult the repository for license terms, notices, and contributor attribution.
From the upstream publisher
Transactional credits for Convex background jobs: reserve, complete, release, refund, and reconcile.
Explore the demo ↗Upstream overview
From the upstream package documentation.
Convex Credits manages credit balances and charges for Convex apps. Grant gifts and rewards, reserve credits before work starts, and complete or release charges when work ends. The component also supports refunds, atomic transfers, safe retries with stable operation keys, and an auditable history of balance changes. Maintained by CLIPIN.
Use cases
From the upstream package documentation.
- Grant welcome credits, gifts, and referral rewards.
- Credit an account after the host app verifies a purchase.
- Reserve credits for AI generations and other background jobs, then complete successful charges or release failed reservations.
- Refund all or part of a completed charge.
- Transfer credits between accounts in one transaction.
- Audit balance changes and import an existing credit ledger.
How it works
From the upstream package documentation.
Mount the component in your Convex app and create a Credits client in the host backend. The host validates the user and chooses prices.
Use grant() for gifts, verified purchases, and rewards. reserve() debits the available balance and creates a pending charge. complete() finalizes that charge without another credit movement. release() returns a pending reservation once. refund() returns all or part of a completed charge, capped at the unrefunded amount.
Supply a stable operation key for every mutation. Identical retries return the stored result; changed arguments with the same key fail. Transfers update both accounts in one transaction.
Paginated history records nonzero balance movements. Import helpers preserve source timestamps and pending charges, then verify balances and counts before activating the account. See https://convex-credits.vercel.app/docs for setup and examples.
Upstream package FAQ
How do I install and mount convex-credits in a Convex project?
Run `npm install @clipin/convex-credits convex` to add the package. In `convex/convex.config.ts`, import the component config and call `app.use(credits)` to mount it. Then instantiate `new Credits(components.credits)` in your host backend and call its methods from inside authorized Convex mutations.
What happens if a credit operation is retried with the same key?
convex-credits uses a stable operation key for every write. Submitting the same key a second time returns the original result without applying the operation again, so retries from failed or re-executed Convex mutations are safe. Submitting the same key with different arguments throws an error to catch accidental key collisions.
Can credit balances go negative in convex-credits?
No. convex-credits enforces that available balances cannot become negative. Any operation that would overdraw an account is rejected, which makes it safe to use for metered billing where users must have sufficient credits before work is performed.
Does convex-credits handle concurrent mutations safely?
Yes. Because convex-credits is called from host Convex mutations, both the component writes and the host writes are committed in the same Convex transaction. This ensures atomicity for operations like transfers between accounts and prevents race conditions from concurrent mutations.
How do I query credit history in convex-credits?
convex-credits stores history as nonzero balance movements and supports cursor pagination through convex-helpers, which is compatible with Convex component queries. Completion operations update charge state but do not add a history entry, keeping the history log focused on actual balance changes.
Use with agents and CLI
Give your coding agent the component’s source identity and setup guidance.
Help me integrate Credits with Bijection.
Read: https://bijection.com/components/credits/SKILL.md
Check SDK compatibility and dependency availability.
Follow this project's execution and verification rules.Upstream README.md
View repository ↗Documentation from clipinfit/convex-credits, recorded October 23, 2026. APIs and setup may differ in the Bijection adaptation.
Credit balances and charges for background jobs, maintained by CLIPIN.
Stable package: @clipin/convex-credits@1.0.1.
Grant gifts and rewards. Reserve credits before work starts. Complete a successful charge without another debit, or release a failed reservation once. Refund completed charges and transfer credits between accounts atomically.
npm install @clipin/convex-credits convex
Mount the component in convex/convex.config.ts:
import { defineApp } from "convex/server";
import credits from "@clipin/convex-credits/convex.config.js";
const app = defineApp();
app.use(credits);
export default app;
Create a client in your host backend:
import { Credits } from "@clipin/convex-credits";
import { components } from "./_generated/api";
const credits = new Credits(components.credits);
// Inside an authorized host mutation:
await credits.grant(ctx, {
owner: accountId,
amount: 20,
key: JSON.stringify(["gift", requestId]),
reason: "Welcome gift",
});
The host controls authentication, grant permissions, prices, and payment verification. Call the component from a host mutation to commit both sets of database writes together.
Supply a stable operation key for each write. An identical retry returns its original result. Reusing a key with different arguments fails. Amounts are positive safe integers, and available balances cannot become negative.
History contains nonzero balance movements. Completion updates charge state without adding a movement. History uses cursor pagination through convex-helpers, which supports component queries. Import helpers preserve source timestamps and pending charges, then verify balances and counts before account activation.