Failed bills, retries and the customer's own page

QBitFlow retries a failing bill for a week and tells you why. Point your customer to their page.

A bill fails when the wallet can't pay.

  1. Attempt 1The bill fails: pastDue
  2. Day 1Attempt 2
  3. Day 3Attempt 3
  4. Day 5Attempt 4
  5. Day 7Attempt 5, the last
  6. CancelledIf the last one fails

What happens

  • First failure: the subscription is pastDue, and subscription.billingFailed arrives.
  • Retries: 1, 3, 5 and 7 days after that first failure, or at once when the customer tops up or raises their maximum. It's active again once a bill is paid (subscription.billed).
  • Last attempt failed: it's cancelled (cancellationReason: "billingFailed"). remainingAttempts: 0 on the last billingFailed warns you.
  • A price above the customer's maximum (the token's price moved) spends no attempt: actionRequired becomes raiseMaximum, and the bill waits up to 7 days for a new maximum before retrying.
  • QBitFlow's own trouble (a network down, no fresh price): retried every 30 minutes, no event, no blame.

subscription.billingFailed· the body your endpoint receives

{  "createdAt": "2026-10-01T12:00:00Z",  "data": {    "managementPageLink": "https://qbitflow.app/user/019cadfd-8900-7a00-8000-0000000000a1/manage?uuid=sub@01a05cd7-2a00-7000-8000-000000000003",    "nextAttemptAt": "2026-10-02T12:00:00Z",    "reason": "insufficientBalance",    "remainingAttempts": 4,    "status": "pastDue",    "uuid": "sub@01a05cd7-2a00-7000-8000-000000000003",    … 24 more fields  },  "id": "evt_82950239-430c-595f-ad42-595955b921a0",  "test": false,  "type": "subscription.billingFailed",  "version": "v2"}
The contract's example (webhooks.md § Examples)
  1. data.managementPageLink: Where the customer fixes it.
  2. data.reason: The table below says its fix.
  3. data.remainingAttempts: 0: the last one; cancellation follows.

Tell your customer what to do

Each reason has one fix, on the customer's page:

reasonTell them
insufficientBalanceAdd funds to the paying wallet
allowanceExhaustedTop up the allowance
approvalRevokedApprove the token again
maxAmountExceededSign a new maximum per period
otherThe network refused the charge: it's retried

Before each bill, subscription.upcomingBill says whether the wallet can pay (balanceSufficient, allowanceSufficient): time for a reminder.

Live mode emails the customer at each failed attempt (your settings can turn it off) when QBitFlow has their address: with only your customerReference, only if a customer of your space has it. Otherwise, and always in test mode, tell them yourself.

Access while a bill fails

pastDue means accessUntil (its currentPeriodEnd) is past: the rule says no; a grace period is your policy. A read carries dunning (failedAttempts, remainingAttempts, failingSince, nextAttemptAt).

Check it

Empty the paying wallet, then after nextBillingAt run the bill (Run next bill now in Dashboard/Subscriptions, or step 7): subscription.billingFailed shows in Dashboard/Settings/Events, and the subscription reads pastDue with its dunning.