Skip to main content

6 posts tagged with "billing"

View All Tags

How we bill by the day: the service-day model

· 10 min read

Billing at Fibe runs on a unit we call the service-day. A Marquee is either funded for today or it isn't. Every day, for every funded environment, a small charge is taken from the player's Wallet and the Marquee's paid-through time is pushed to the end of the current day. There is no monthly subscription to reason about, no proration math, no surprise cliff at the end of a cycle — just one question, asked once a day, forever: did you pay for today?

This post is about why we chose that shape, how the daily charge keeps an environment running, and the single design rule underneath it that keeps every part of the billing lifecycle agreeing on what "today" actually means.

Idempotency everywhere: payments, wallet posts, and claim-once webhooks

· 10 min read

There's a moment every billing engineer eventually has. A customer emails: "I was charged twice." You open the logs, and the request looks fine — one checkout, one order. Then you find the second event. Same payment, redelivered by the provider three minutes later because our 200 got lost on the wire. We processed it twice, minted the currency twice. The math was, briefly, generous to exactly the wrong person.

The lesson isn't "be more careful" — careful doesn't scale. It's that at-least-once delivery is the only honest contract a distributed system can offer, and once you accept that, exactly-once effects become something you build, on purpose, at every layer that touches money. Here's how we do it at Fibe — across wallet posts, the Mana-to-Sparks conversion, daily funding, provider webhooks, and the keys our SDK ships.

Mana and Sparks: building a double-entry wallet that can not go wrong

· 22 min read

Every Fibe environment costs money to keep alive. A Marquee is a real Docker host with a real VM bill behind it, and the only thing standing between "your agent is coding" and "nothing runs" is whether the wallet had enough in it this morning. That makes the wallet the most boring-looking and least forgiving piece of the platform. It is not allowed to lose a credit, double-charge a day, or — the cardinal sin of any money system — let a balance drift negative.

This is the story of how we built that wallet: two currencies, a double-entry ledger where every movement is mirrored exactly once, pessimistic locks, and idempotency keys so aggressive that the same operation can be retried a hundred times and still only happen once. None of it is clever. That is the point. In billing, clever is a liability; the goal is a system whose invariants are so tight that the failure modes simply do not exist.

One 402 to rule them all: the not-funded gate

· 6 min read

Every platform that rents compute eventually asks the same question in a hundred different places: is this allowed to run right now? On Fibe, "right now" means funded — a Marquee that has paid for the current service-day. We answer that question with exactly one check and one HTTP status, and we route the consequences differently depending on who's asking.

This is the story of the not-funded gate — a single 402 that sits in front of roughly a hundred call sites.

Grace, suspension, and scheduled destroy: humane billing for ephemeral environments

· 9 min read

Every billing system has a moment it would rather not talk about: the one where the money stops. The card expires, the wallet empties, the trial ends — and now you have an environment that costs real money to keep alive and a customer no longer paying for it. The naive answer is brutal and tempting: tear it down, move on.

We didn't want to build that. Fibe funds a Marquee — your Docker host — out of a daily wallet, and when a day can't be funded, the system enters a deliberate, recoverable sequence rather than a guillotine. This post is about that sequence: the grace incident, the three-day window, the seven-day retention, and the invariant we cared about most — starting grace never marks your billing as paid, and a suspended-but-unrepaid environment can never slip back to "active."

One Subscription, three payment providers

· 9 min read

Most of our billing code does not know which payment provider charged the card. That is on purpose, and one of our better early decisions.

Fibe takes money through three processors — Stripe, Creem, and Paddle — but the rest of the platform sees exactly one thing: a subscription record and a paid order. The provider name is just a stored string. Everything downstream — minting Mana, provisioning a tutorial Marquee, converting to Sparks, the daily funding sweep that keeps your environment alive — reads from that neutral layer and never branches on "is this Stripe or Paddle." Here's how, and why it earns its keep.