Recurring Revenue. Automated.
Customers subscribe. We handle billing cycles, renewal recovery, and lifecycle management. You focus on your product.How It Works
past_due. Waffo schedules no retries of its own: the payment channel retries the charge once, typically the next day. If that retry succeeds the subscription returns to active (subscription.recovered); if it fails, the subscription is canceled immediately (subscription.canceled) and the customer has to subscribe again. There is no separate grace-period timer. Customers receive a reminder email before each renewal (1 day ahead for weekly plans, 3 days for monthly and quarterly, 7 days for yearly; 1 day before a trial ends) and a receipt after each successful charge.
Subscription Plan Structure
In Waffo Pancake, each separately purchasable subscription option is an independent subscription product. The most common distinction is billing interval, such as:- monthly
- yearly
Subscription States
Billing Intervals
Trial Periods
Reduce signup friction. Let customers try before they commit — free, or for a small charge.Configure Trials
When creating a subscription product, enable the trial toggle and set the number of days in the Dashboard.Platform-Level Trial Protection
Waffo Pancake acts as the Merchant of Record and automatically prevents trial abuse:
How the two layers interact:
- If the merchant requests ≤ the platform maximum → the merchant’s requested value is used
- If the merchant requests > the platform maximum → falls back to the platform maximum
- If the merchant doesn’t specify → the full platform maximum is used
Paid Trials
Trials don’t have to be free. You can charge a small, reduced amount during the trial period instead of waiving it entirely — the classic “$1 trial” pattern. It’s optional, can be set per currency, and always stays lower than the regular price. When the trial ends, billing switches automatically to the full price.Set a trial price via API
See the
trialAmount field reference for request format and rules.Buyer Identity & Trial Protection
Trial eligibility is tracked bybuyerIdentity — a stable identifier you provide via authenticated checkout. The platform uses this to detect repeat trial claims across sessions.
Renewal Recovery
When a renewal charge fails, the subscription transitions topast_due and you receive subscription.past_due. The recovery window is short and fixed by the payment channel: it retries the charge once, typically the next day.
- Retry succeeds — the subscription returns to
activeand you receivesubscription.recoveredplussubscription.payment_succeeded. - Retry fails — the subscription is canceled immediately and you receive
subscription.canceled. The customer must subscribe again; there is no further retry and no grace-period timer.
past_due day and prompt the customer to update their payment method before the retry, since a second failure ends the subscription.
Treat
past_due as “renewal requires recovery”, not simply “payment failed and service stopped”.Managing Subscriptions
Cancel
Cancellation is always effective at the end of the current billing period. When a cancellation is requested, the subscription enters thecanceling intermediate state. The customer retains access until the current billing period ends, at which point the status transitions to canceled.
currentPeriodEnd so you know when access expires. The returned status will be canceling (or canceled if the period has already ended).
There is no immediate cancellation option. Customers always retain access through the end of their paid period. The
canceling → canceled transition happens automatically when the current billing period expires.Resume Subscription
If a subscription is still incanceling, the customer can resume it before the current period ends.
After resuming:
- the subscription returns to
active - access continues without interruption
- future renewals continue on the original billing cycle
Resuming applies to subscriptions that were canceled but have not reached the end of the current period yet. It is effectively an undo for cancellation, not a brand-new purchase.
Changing Plans
A plan change moves a subscriber to a different plan without making them cancel and buy again. It is modelled as one cancellation plus one new subscription — the old order closes, a new one opens. There is no in-place edit of a subscription’s plan. The customer always confirms on a hosted change confirmation page: old and new plans side by side, the prorated difference itemized, and the effective date stated.Direction decides the default timing
On an immediate change the unused value of the current plan is credited against the new plan’s charge. That credit is recalculated at submission time from the days actually remaining — the figure shown when the link was issued is an estimate, not a promise.
Who can start one
Two routes, and they follow different rules:Starting a plan change from the Dashboard UI is not available yet — the entry point on the subscriptions page is marked coming soon. The API works today.
Customer self-service
Self-service happens in the Customer Portal, and it needs no integration work from you. The customer signs in, opens the subscription, picks another plan in the same group, and confirms. To enable it: put the plans in one product group and turn onselfServicePlanChange.
The portal is not the only self-service surface. You can offer the same thing in your own UI with a customer session token —
customer.createPlanChangeSession() in the SDKs — which runs under the customer’s own credential and is gated by exactly the same three conditions: their own subscription, same product group, selfServicePlanChange on. Issuing the link with your API Key instead is a different path: none of the three apply, and you can move a subscription to any plan — see below.Merchant-initiated changes via API
1
Issue the change link
Call
checkout/create-session with originOrderId set to the subscription you want to move. That puts the endpoint into plan-change mode and returns a checkoutUrl for the confirmation page.2
Deliver it yourself
Email, in-app message, however you already reach the customer. The platform does not send this link.
3
Customer confirms
They review the comparison and confirm. Your system finds out by webhook.
Guards checked when issuing the link — these fail before the customer ever sees the page:
What your system should expect
Three webhook events cover the lifecycle:
An immediate change reaches its switch moment right after authorization, so it goes straight to
plan_changed with no scheduled event first.
While a scheduled change is pending, the new subscription has no billing period yet (
currentPeriod is null) — the first period is confirmed by the payment channel at the switch moment.canceling puts it back to active. You can then issue a new change.
Cross-currency changes are not supported, and a subscription cannot change plan during a trial.
Metrics
MRR (Monthly Recurring Revenue)
Key Metrics
Webhooks
Subscribe to subscription lifecycle events via webhooks. Configure webhook endpoints in Settings —> Webhooks. Webhook payloads use standard Waffo Pancake conventions:- IDs are UUID v4 format
- Amounts as display format strings
- Timestamps in ISO 8601 UTC
- Billing frequency uses the
billingPeriodfield (e.g.,monthly,yearly)
Customer Portal
Let customers manage their own subscriptions:- View details
- Update payment method
- Change plans
- Cancel
- Resume subscription
- Download invoices
Customer Portal
Self-service subscription management.
Best Practices
Don't cut access immediately
Don't cut access immediately
A missed renewal charge does not need to mean instant cancellation. Give the customer time to recover the subscription.
Send reminders
Send reminders
Trial ending. Upcoming charge. No surprises.