What does scheduledAmounts mean in the subscription request?
scheduledAmounts is an optional list inside productInfo that lets you charge
a different amount in specific billing periods instead of the same amount
every period. Each entry has exactly two fields:
amount,
and the listed periods do not have to be consecutive — listing only periods
1 and 5 is valid.
You can set scheduledAmounts when you create the subscription and change it
later with /api/v1/subscription/update.
Is period counted from the first period, or from the first period after the trial?
From the first period of the subscription. period is an absolute, 1-based
index over every billing period, and trial periods are included in that count.
This matters when a trial exists: if you configure a 2-period trial, then
period: 1 and period: 2 address the two trial periods, and the first
period at the regular price is period: 3.
There is no offset applied anywhere: Waffo looks up the period number of the
charge it is about to create and reads
scheduledAmounts with that exact
number. To see where a live subscription currently is, read
productInfo.currentPeriod from /api/v1/subscription/inquiry — the stored
plan comes back in the same response as productInfo.scheduledAmounts, so you
can always confirm which period numbers are still in the future before you send
an update.
How does Waffo decide the amount for each period?
Three inputs are consulted in this order; the last rule that matches wins:
So a
scheduledAmounts entry overrides the trial amount for that period.
If you want the trial to be billed at trialPeriodAmount, do not list the trial
period numbers in scheduledAmounts.
This is the first thing to check when a charge does not match what you expected:
work out the period number of the charge, then walk the three rules in order.
What are the exact limits on scheduledAmounts?
Two details worth calling out because they are commonly assumed the other way
round:
- Amounts are decimal strings in the currency’s normal unit, not minor units.
"9.90", not"990". Extra decimal places are rejected, not rounded. amount: "0"passes field validation, so a free period is expressible — but the value still has to satisfy the minimum amount on your agreement, so whether 0 is accepted depends on your contract.
Can I raise the next period’s subscription amount directly?
No — not through/api/v1/subscription/update. By default that endpoint
rejects any increase. This is enforced on all three amount fields:
The per-period baseline is the currently stored scheduled amount for that same
period, or the subscription’s
amount if that period is not in the stored
plan. That closes the obvious loophole: you cannot lower a period first and then
raise it back in a second call, because the second call is compared against the
value you just wrote.
Violations come back as a parameter error whose message names what was rejected
(amount is not allowed to increase,
trialPeriodAmount is not allowed to increase, or
scheduledAmounts.amount is not allowed to increase for period N).
To charge more, either use /api/v1/subscription/change and move the user
to a new plan, or — where the increase is a seat add-on — send the update with
a topupInfo block: that path collects the difference for the current period
immediately and is allowed to raise amount from the next period (see the
proration table below). Plain increases through update are not open to
accounts generally; if you believe your integration needs them, raise it with
integration support rather than designing around it.
How do I set prorate?
There is no proration field, and Waffo does not calculate proration. If you are looking for aprorate / proration_behavior parameter, it does not exist —
neither on /subscription/update nor on /subscription/change.
Here is what actually happens in each case, so you can decide what to implement
on your side:
In short: amount changes are period-boundary events, and any money that
should move because a change landed mid-period is yours to compute and yours to
collect.
What exactly does /subscription/update change, and when does it take effect?
It changes amounts only, from the next billing period onward.
It can change: amount, productInfo.trialPeriodAmount,
productInfo.scheduledAmounts — individually or together. At least one of the
three must be present, otherwise the request is rejected.
It does not change: the plan, periodType, periodInterval, the number of
periods remaining, the billing date, or the payment method. It does not trigger
proration and it does not create a new subscription.
Timing: the new values apply from the next period. A charge for the current
period that has already been generated or is already in flight is not
affected. The response tells you the period number the change lands on:
When is an amount update rejected outright?
The last row means updates are serialized per subscription. If you are
re-pricing many subscriptions, treat a “being modified, please retry later”
response as retryable rather than as a failure.
If I send scheduledAmounts in an update, does it merge with the existing plan?
No — the list you send replaces the stored plan as a whole. It is not a
patch: periods present in the old plan but absent from your request stop having
a scheduled amount and fall back to amount.
Two consequences to design for:
- Always send the complete set of future periods you want priced, not just the ones you are changing.
- Because an update may only address periods after the current one, entries for already-charged periods are dropped from storage when you replace the plan. That is expected and does not change any charge that already happened.
/subscription/update; to get back to a single
flat amount, list every remaining future period at the amount you want, or move
the user to a new plan with /subscription/change.
What happens to scheduledAmounts when I upgrade or downgrade?
Nothing is inherited. /subscription/change creates a new subscription, and
that new subscription’s amount and scheduledAmounts come entirely from the
change request. If you omit scheduledAmounts there, the new subscription has
no per-period plan at all and every period is billed at the new amount.
So if a tiered price ramp should survive an upgrade, you have to restate it in
the change request.
Will the end user be told that the amount changed?
Yes — Waffo emails the subscriber after a successful amount update. The mail carries the previous amount, the new amount, the previous and new per-period plans, and the period number the change takes effect from. Two operational caveats:- The email is sent only if the amount-change notification is enabled for your account and product. If it is switched off, nothing is sent to the user.
- Sending is best-effort and asynchronous: a mail failure does not roll back the amount change. The API response is the record of what changed.
Does Waffo send me a webhook when an amount update succeeds?
Yes. After a successful/subscription/update, Waffo pushes
SUBSCRIPTION_UPDATE_NOTIFICATION to the notifyUrl stored on the
subscription. For a plain amount change it is sent as soon as the update is
committed; for a seat add-on (see below) it is sent once the top-up charge
succeeds and the new amount is applied. The payload is the subscription as the
inquiry API returns it, so it already reflects the new amounts.
To keep your own records aligned:
- Treat the
/subscription/updateresponse as the primary record — readnewAmount,newScheduledAmountsandnextEffectivePeriodfrom it and store them. The webhook confirms the same change asynchronously and is the signal to use when the change was committed outside your immediate request path (the top-up case). - Keep listening to the per-period notification and the subscription payment order notification for the actual charged amount of each period — those reflect what was really taken, which is the number you should reconcile against.
Which subscriptions can use per-period amounts at all?
Per-period amounts and/subscription/update are available on subscriptions
where Waffo drives the billing schedule. For some payment methods the
payment method itself drives the schedule; those subscriptions reject
scheduledAmounts at creation and are not eligible for amount updates. If a
creation call comes back saying scheduled amounts are not supported for the
subscription, that is why — the fix is a different payment method, not a
different request shape.