Model your pricing as data and let the billing run itself
Most billing bugs are modelling mistakes wearing a disguise: a plan duplicated as a second product, an upgrade that charges twice, a trial that converts a day late, a failed renewal treated as a cancellation. This page is how the objects fit together and which call to make at each of those moments.
The objects your pricing table becomes
- Products, plans and offers
- A product is the thing you sell. Plans express the tiers inside a subscription product. An offer is the purchasable price on top: currency, billing interval, trial. Monthly and annual are two offers, not two products, and that distinction is what keeps upgrades and reporting coherent.
- Trials, including ending them early
- Start a subscription in trial and let it convert on its own, or call the API to end the trial when somebody upgrades before it runs out and take the first payment there and then.
- Plan changes with proration
- Move a subscription to another plan mid-cycle and the difference is worked out to the day. You can preview the upcoming renewal through the API first, so the figure you show the customer is the figure they are charged.
- Usage and one-off amounts
- Usage-based and pay-as-you-go pricing are supported as plan shapes, and you can charge a single amount onto a live subscription for an overage, an add-on, or seats bought halfway through a month — no second checkout required.
- Retries on a declined renewal
- A failed charge is retried on a schedule and the customer is told, rather than the subscription being dropped on the first decline. The failure arrives as an event if you want your own recovery messaging running alongside ours.
- The records each charge produces
- Every charge, first or fortieth, is its own payment object, and the buyer receives either a receipt or a tax invoice depending on whether they entered business details at checkout. The documents are issued in our name, because we are the seller of record on the sale.
From a pricing table to the first renewal
- 01
Create the product, then an offer per price
In the dashboard or over the API — the same objects either way. The interval, the currency and any trial belong to the offer rather than to the product, which is why a new price point never needs a new product.
- 02
Open a checkout that tells you who it was
Point a button, a link or an SDK call at a checkout element and pass a custom field carrying your own user identifier. That field is what lets the webhook you get back map cleanly onto a row in your database.
- 03
Grant access on payment_success
It fires for the first charge and for every renewal, and it is the only event that means money actually arrived. subscription_created can fire while the first payment is still pending, so treat it as information rather than as permission.
- 04
Handle changes through the subscription endpoints
Update with proration, pause collection, charge a one-off amount, end a trial, cancel. When a subscription_updated arrives, read the subscription back instead of inferring its state from the order the events turned up in.
Modelling decisions that pay off later
One product, many offers
Duplicating a product per price point is the cheapest mistake to make and among the most expensive to unwind: reporting splits down the middle, upgrades degrade into cancel-and-resubscribe, and proration stops being available at all. Offers exist so the price can vary while the product identity holds still.
Show the prorated number before you commit the change
Previewing the upcoming renewal turns a plan change from a surprise on a statement into an amount the customer agreed to. It is also, in practice, the difference between a completed upgrade and a support ticket.
Treat events as notifications, not as state
Delivery is at-least-once and can arrive out of order, so store the event id, skip anything already handled, and read the object back when correctness matters. A billing integration that trusts event ordering fails in a way that is very hard to reproduce afterwards.
The tax on each charge is not your code
As Merchant of Record we calculate and file the transaction tax on the first charge and every renewal. There is no rate table in your application, no tax branch in your billing tests, and no filing that depends on your deploy schedule.
What sellers say once they have switched
★★★★★ 4.8/5 from 10 reviews on G2 →
Vadim Finayev “We work with quite a few merchants of record, but none comes close to the support and speed of implementation of Fungies. If you want a payment partner that actually gives you the feeling they want to work with you — rather than leaving you on read for three days or randomly restricting your account — you are in the right place.”
David Elliott “I researched the options and Fungies was the best fit for functionality and customisation within a store builder you can connect to your own domain. Taking a small percentage of sales, instead of charging a subscription for every environment and plugin, is refreshing.”
Elnura Abdimanap Kyzy “The platform is user-friendly, integrates easily with APIs and webhooks, and simplifies managing digital products and subscriptions. We were up and running quickly and support has been responsive throughout. Fungies is clearly tailored to the needs of SaaS businesses.”
Francisco Magnone Rienzi “Fungies has been a great partner — fast setup, competitive pricing, and real humans providing quick answers. They are constantly rolling out new features, and I am excited to see what is next.”
Billing model questions
Recurring revenue, and the paperwork that comes with it.
Model it once and stop maintaining billing
Create a product with two offers, run a subscription through the sandbox including a declined renewal, and read the events that arrive before you write any of it into your app.








