Freeze, then settle: how SaaScaffold charges credits for AI tasks

Why credits are frozen when a task is accepted, deducted only after complete delivery, and released when a task truly ends without a result.

Three rows of blocks showing credits frozen, settled and released

The problem with charging at the end

An AI video can take minutes to generate. A provider can time out, return an empty file, or report success before the file is actually downloadable. Meanwhile a customer with credits for three videos can click “Generate” ten times in a row.

If you deduct credits only when a task finishes, those ten clicks all start work you cannot be paid for. If you deduct at the start, every failure becomes a manual refund. SaaScaffold uses a third approach: freeze, then settle.

Quote before accepting

Every tool computes its price in your site’s own integer credits from the tool, the model and the declared parameters, such as duration or number of images. The price is set by your configuration, not derived from what the provider charges you. Provider price changes never silently change what your customers pay.

The quote is shown before the customer confirms. If it changed in the meantime, for example because an admin edited the price, the submission is rejected and the customer sees the new price instead of being charged a number they never saw.

Freeze on acceptance

Accepting a task is one database transaction: the task is created, the quoted credits are frozen against the customer’s balance, and the work is queued. Either all three happen or none do. Because the freeze is a conditional update inside that transaction, ten concurrent submissions cannot overdraw a balance that covers three.

Frozen credits are no longer spendable, but they are not gone. Each customer also has a limit on tasks running at once (three by default); extra tasks wait in a queue with their credits already frozen and can still be cancelled safely.

Settle only on complete delivery

A task succeeds only when its promised results are saved and readable: text is stored, and files are copied into the site’s own storage. At that point the frozen amount is deducted in the same transaction that marks the task as successful and records the result. There is no partial charge and no top-up for actual usage.

Release only on a trusted ending

If the provider reports a final failure, or the task is cancelled before it reached the provider, the frozen credits are released in full. An unknown outcome is not a failure. When a status check times out, the task keeps its frozen credits and the site keeps checking. Releasing early and then receiving a successful result would mean delivering work for free, or charging twice to fix it.

Admins can still stop a stuck task by hand. They record a reason and decide whether the frozen credits go back, and that decision is audited.

Retries without double effects

Networks retry, queues redeliver and payment platforms resend events. Stripe’s documentation states that webhook endpoints might receive the same event more than once, and its API supports idempotency keys so a retried request does not repeat an operation. SaaScaffold applies the same idea internally: every grant, freeze, deduction and release is tied to a unique operation, so replaying it changes nothing.

What customers see

In the user center, each task shows its frozen, deducted or released credits next to its status. Customers do not have to trust a single balance number; they can see exactly why it moved.

Sources & further reading

  1. Stripe API reference: Idempotent requests ↗Accessed
  2. Stripe documentation: Receive Stripe events in your webhook endpoint ↗Accessed

Spotted a mistake? Let us know.