Purchased and promotional credits should remain separate balance buckets—or, preferably, traceable ledger lots—whenever their usage rules differ. A wallet may display one aggregate total for convenience, but eligibility, expiration, consumption, refunds, and adjustments should be applied to the underlying lots rather than to an undifferentiated balance.
The recommended design: separate value by source, even if the interface shows one total
A prepaid wallet needs to preserve what each unit of value represents and which rules apply to it. If purchased credits can be used broadly while promotional credits are limited to a product, workload, campaign period, or expiration date, combining them into one authoritative balance removes information needed at spend time.
The practical pattern is to maintain distinct internal records while deriving customer-facing totals from those records. Depending on the business model, the interface might show:
- Total balance: All active purchased and promotional credits.
- Currently usable balance: Credits eligible for the requested product or workload at that moment.
- Purchased balance: Remaining value originating from customer purchases.
- Promotional balance: Remaining grants subject to promotional rules.
- Expiring balance: Eligible credits that will expire within a defined period.
The total is a presentation value, not the source of truth. For example, a wallet might display 1,300 total credits, but only 1,000 may be available for a particular workload because the other 300 are promotional credits restricted to a different use case.
Why an undifferentiated balance cannot enforce different rules
When credits are merged without retaining provenance, the system may be unable to answer basic operational questions:
- Which grant funded a particular usage event?
- Was the usage eligible for the promotional offer?
- Which credits should expire at the end of the campaign?
- How much purchased value remains after a mixed-balance transaction?
- What should happen if usage is canceled or reversed?
- Should a policy change affect existing grants or only new ones?
A single mutable number also makes historical reconstruction difficult. If the balance changes from 1,300 to 1,120, the difference alone does not show whether 180 purchased credits, promotional credits, or a combination of both were consumed.
Preserving the distinction does not require presenting a complicated interface. The wallet can show a simple total while the ledger retains source, rule, and allocation details. Customer-facing presentation and internal accounting or operational reporting can therefore serve different needs without losing traceability.
Balance buckets versus immutable credit lots
Separate balance buckets can be sufficient when every credit within a category follows exactly the same rules. A basic implementation might maintain one purchased bucket and one promotional bucket.
Credit lots are more flexible when grants can differ by issuance date, expiration date, eligible workload, campaign, contract, or rule version. Under a lot-based design, each purchase or promotion creates a distinct grant record. Spend events are then allocated against one or more eligible lots.
A useful distinction is:
- Bucket model: Groups credits by broad type and maintains a balance for each group.
- Lot model: Retains each grant as a separately identifiable record with its own rule profile.
A hybrid model can use lots as the authoritative record and maintain bucket-level projections for fast balance display. If projected balances are cached, they should be reproducible from the underlying grants and ledger events.
Represent every credit grant as a traceable lot with its own rule profile
Each credit grant should have a stable identity and enough information to determine how it may be used. The grant record establishes the origin and applicable policy; subsequent ledger events record consumption, expiration, reversal, cancellation, or adjustment.
Core fields for provenance, amount, dates, scope, and status
A practical credit-lot record can include:
- Lot ID: A unique identifier for the grant.
- Credit type: Purchased, promotional, or another explicitly defined category.
- Provenance: The purchase, campaign, contract, service adjustment, or other source.
- Issuance event ID: A link to the event that created the lot.
- Original amount: The number of credit units granted.
- Remaining amount: A current projection or value derived from ledger allocations.
- Eligibility scope: The products, workloads, accounts, regions, or actions for which the lot may be used.
- Activation date: When the credits become eligible.
- Expiration date: When eligibility ends, if applicable.
- Status: Pending, active, exhausted, expired, canceled, or another defined state.
- Rule-set reference: The policy and version governing the lot.
The rule-set reference is particularly important. Storing only a current global policy can make historical behavior difficult to reproduce after rules change. A versioned reference lets the system determine whether an existing grant keeps its original terms or moves to a newer policy.
The authoritative history should be append-oriented. Instead of rewriting the original grant or deleting prior usage, record a new event that references the affected transaction. This approach preserves the sequence of decisions without implying that it satisfies any particular legal, regulatory, or accounting standard.
Rules for expiry, rollover, transferability, refunds, and cash-equivalent treatment
Purchased and promotional credits may follow different policies, but those differences should be explicit rather than inferred from the balance label alone.
| Rule dimension | Purchased credits may be configured to | Promotional credits may be configured to |
|---|---|---|
| Eligibility | Apply across contracted products or workloads | Apply only to a campaign, model class, or workload |
| Expiration | Remain active or expire under stated terms | Expire at the end of a promotion |
| Rollover | Continue into a later period if policy permits | End with the campaign or renewal period |
| Transferability | Follow account or contract-level rules | Remain tied to the recipient account |
| Refundability | Follow the applicable purchase policy | Be non-refundable unless a policy states otherwise |
| Cash-equivalent treatment | Be classified under the organization’s applicable policy | Remain non-cash promotional value unless explicitly classified otherwise |
These are design examples, not universal rules. The governing contract and documented business policy should determine the actual treatment. Legal, tax, revenue-recognition, and formal accounting decisions require review under the organization’s applicable policies and professional advice.
A rule profile should also specify what happens at boundaries. For example, does a credit remain eligible through the exact expiration timestamp, or does it expire at the beginning of that date? Which time zone controls the decision? What happens to an in-progress request that begins before expiration but completes afterward? Explicit definitions prevent different services from reaching inconsistent answers.
Expiration, cancellation, refunds, reversals, and manual adjustments should be recorded as events rather than edits to historical transactions. Each event should identify its reason, effective time, related lot or allocation, and idempotency key where appropriate.
Apply eligibility checks and a deterministic consumption policy at spend time
The wallet should decide which credits can fund a usage event before changing any balance. Credit type alone is not enough: eligibility may depend on account, product, workload, activation time, expiration time, and the rule version attached to each lot.
A deterministic consumption process can follow these steps:
- Validate the usage event. Confirm its account, workload, quantity, timestamp, and unique event or idempotency identifier.
- Find candidate lots. Select active lots associated with the account and relevant wallet.
- Evaluate eligibility. Apply each lot’s activation, expiration, scope, status, and other documented rules.
- Order eligible lots deterministically. Apply the configured policy, with stable tie-breakers such as issuance time and lot ID.
- Allocate the charge. Consume one lot or split the usage across multiple lots when partial allocation is allowed.
- Record the result atomically. Write the usage event and all lot allocations as one consistent operation.
- Preserve the linkage. Retain a direct relationship between the usage event and every lot that funded it.
“Earliest-expiring eligible credits first” is one possible ordering policy because it may reduce avoidable expiration. It is not always the correct policy. An organization might choose promotional-first, purchased-first, contract-specific ordering, or another method based on commercial terms and customer experience goals.
Whatever policy is selected, it should produce the same result when the same event is replayed against the same ledger state. Stable ordering matters when multiple lots share an expiration timestamp or issuance date.
Partial consumption, concurrency, and idempotency
A usage event may consume only part of a lot or span several lots. The allocation record should therefore capture the usage event ID, lot ID, allocated amount, rule version, decision timestamp, and transaction status.
Concurrency controls are also necessary. Two requests should not both spend the same remaining credits after reading an identical pre-transaction balance. The implementation can use transactional updates, version checks, reservations, serialized wallet operations, or another suitable mechanism, but the result should prevent over-allocation and preserve a reproducible history.
Idempotency protects against duplicate delivery. If a metering service retries the same usage event, the wallet should return or reconstruct the prior allocation rather than charging it again. Reversal requests need their own identifiers and should reference the original event.
Worked example: purchased and promotional lots
Consider a wallet with these active grants:
- Lot P-101: 1,000 purchased credits, eligible for all contracted workloads, with no expiration defined in this example.
- Lot M-204: 300 promotional credits, eligible only for batch enrichment, expiring at the end of the campaign.
The interface may show 1,300 total credits. That number does not mean every workload can use all 1,300.
A batch-enrichment event requires 180 credits. If the documented policy is to use the earliest-expiring eligible lot first, all 180 credits are allocated to M-204. The resulting projections are:
- P-101 remaining: 1,000 credits
- M-204 remaining: 120 credits
- Aggregate remaining: 1,120 credits
If 40 credits of that usage are later reversed, the system should create a reversal linked to the original event and allocation. Under a policy that restores value to the original lot, M-204 would return to 160 remaining credits. The original 180-credit transaction remains in history; the new reversal explains the net result.
If the reversal occurs after M-204 has expired, the policy must define whether restored credits remain expired, receive a limited reinstatement period, or are handled through another adjustment. That decision should not be improvised by the transaction handler.
A chat workload, meanwhile, would not be eligible to consume M-204 in this example. It could use P-101 if the purchased lot’s scope includes chat. The relevant available balance for chat would therefore be 1,000, even if the interface’s aggregate total were higher.
Edge cases to define and test
Implementation testing should cover more than the normal purchase-and-spend path. Important cases include:
- Multiple eligible lots expiring at the same timestamp.
- Promotional balance that is positive but insufficient for the full usage event.
- Promotional credits that exist but are ineligible for the requested workload.
- An event spanning promotional and purchased lots.
- Concurrent requests competing for the final available balance.
- Duplicate metering events and delayed retries.
- Usage initiated near an activation or expiration boundary.
- Cancellation before settlement and reversal after settlement.
- Reversal after the original lot has expired or been canceled.
- A policy change after a lot has been issued.
- Manual adjustments that increase or decrease available value.
- Rebuilding displayed balances from the underlying event history.
Tests should verify both the final balance and the exact allocations that produced it. A correct-looking aggregate can conceal an incorrect source allocation.
Reporting and design questions
Operational and customer reports should distinguish total, eligible, purchased, promotional, expiring, consumed, and adjusted amounts where those distinctions are relevant. Finance teams may need different reporting views from product teams, but both should reconcile to the same underlying event and allocation history.
When configuring or designing a prepaid wallet, consider these questions:
- Are purchased and promotional grants isolated at the bucket or lot level?
- Can the system prove which lots funded each usage event?
- Are eligibility and consumption rules versioned?
- Does the displayed total remain separate from the authoritative ledger state?
- How are partial allocations recorded across multiple lots?
- What deterministic tie-breaker is used when lots have equal priority?
- How does the system prevent duplicate or concurrent consumption?
- Are expiration, cancellation, reversal, and adjustment recorded without deleting history?
- What happens when a reversal targets an expired promotional lot?
- Do policy changes apply retrospectively or only to newly issued grants?
- Can reports reconcile source-specific balances with individual usage events?
- Can balances be rebuilt and verified from grants and transaction history?
For metered AI services, a model request or other measured inference activity may generate a usage event for a separate commercial ledger to evaluate. The boundary should remain clear: serving telemetry identifies measured activity, while the wallet applies commercial eligibility and consumption rules.
Token Forge Cloud focuses on AI model access, private LLM inference, and serving-layer controls such as caching, routing, batching, quantization, and GPU scheduling. Token Forge Cloud also treats latency-sensitive chat, batch enrichment, and agentic workflows as different serving-policy problems. Those workload distinctions can inform metering design, while wallet and ledger policies should be evaluated as a separate commercial architecture concern.
Contact Token Forge Cloud to discuss API access, private deployment, and LLM inference cost control.