# Error codes: billing

The codes of the Billing area: package, licenses, add-on bookings, payment methods, invoices, orders, and the responses of the payment service provider.

> **Type:** reference
> **For:** Anyone who reads billing data or builds an operation that can fail on a contractual block.
> **Prerequisite:** know the error format — see [The error format](/api/error-format)

## How to read the tables

Read the tables like this: **Code** is the value of the `code` field in the error body. Your logic switches on it, never on `message`. **Meaning** and **Typical trigger** classify the case. **HTTP** is the status actually sent. **Expected reaction** is your client’s response, drawn from a fixed vocabulary that is the same on all seven error-code pages: “check credentials” (401), “check permission or package” (402, 403), “correct the input” (400, 413, 415, 422), “reload, resend” (version conflicts), “do not retry, check the operation” (404, 409, 410, 426), “wait (Retry-After)” (429), and “retry later, report the trace ID if it recurs” (5xx).

## The codes

### Billing

The status codes carry meaning here: **402** marks blocks that a booking resolves, namely payment method, contract limit, licenses, add-on booking, app, and package. **403** `Billing.FeatureNotEntitled` means that a contractual capability is missing, such as API access or webhooks. Only a different package or the operator resolves this, not a booking in the portal. Which package contains which capability is described in the handbook under [Billing](https://szenera.com/docs/billing). **409** marks cases where something else has to be done first (billing profile, payment method, sequence of steps). The `Stripe.*` codes keep their literal names because that is how they appear in the catalog.

| Code | Meaning | Typical trigger | HTTP | Expected reaction |
|---|---|---|---|---|
| `Subscription.NotFound` | Contract not found | Unknown contract ID | 404 | do not retry, check the operation |
| `Subscription.AlreadyExists` | Contract already exists | Duplicate creation | 409 | do not retry, check the operation |
| `Subscription.InvalidStatusTransition` | Invalid contract transition | Disallowed status change | 409 | do not retry, check the operation |
| `PaymentMethod.Required` | Payment method required | Action without a payment method on file | 402 | check permission or package |
| `Quota.Exceeded` | Limit exceeded | Contractual limit reached | 402 | check permission or package |
| `Billing.LicensesExhausted` | All licenses in use | Pairing another display although the contract no longer carries a free license. The detail names booked and in use, so that the interface can show the way to book more | 402 | check permission or package |
| `Billing.LicenseReductionBlocked` | License count below usage | Reducing the booked licenses to fewer than are currently in operation — first detach displays, then reduce | 409 | do not retry, check the operation |
| `Billing.BelowPackageMinimum` | Reduction below the package minimum | Reducing the displays below the minimum number of the package (Premium: 5) — fewer is only possible with a smaller package. The detail carries `minimum` | 409 | do not retry, check the operation |
| `Billing.PackageChangeBlocked` | Package change not possible | Enterprise is negotiated instead of booked, the target package caps fewer displays than are in operation, or the contract is canceled | 409 | do not retry, check the operation |
| `Billing.AddonRequired` | Add-on not booked | First use of a capability that is sold as an add-on (API access, company sign-in). Existing usage keeps working — only the new one requires the booking | 402 | check permission or package |
| `Billing.SkuNotFound` | Item not in the catalog | Price lookup or booking for an item code that the catalog does not (or no longer) actively list | 404 | do not retry, check the operation |
| `Billing.SkuAlreadyExists` | Item code already taken | Creating a catalog item with a code that is already in use. The code is the business key and appears on issued invoices — it is never overwritten | 409 | do not retry, check the operation |
| `Billing.AppRequired` | App not booked | Use of a priced app without a booking. The detail carries the price, so that the interface can offer “€X/month — book now?” | 402 | check permission or package |
| `Billing.PackageRequired` | Larger package needed | Use of an app that is included only from a higher package. Unlike `Billing.AppRequired`, no booking in the store solves the problem here, only a package change. The detail carries the lower bound | 402 | check permission or package |
| `Billing.FeatureNotEntitled` | Capability not enabled | A contractual capability is missing (e.g., `browserDisplays`, `multiDisplayPerDevice`, `displayPowerControl`). Not resolved by a booking, only by the operator. The withdrawal is **soft** — commands already issued run to completion, only new ones are rejected | 403 | check permission or package |
| `Billing.PastDueBlocksUpgrade` | Open invoice blocks expansion | Upgrade or add-on booking (package, displays, app, video wall) while one of its own invoices is open. Expansions are invoiced immediately, and a second open invoice would keep the contract overdue even after payment arrives. Downgrades, reductions, and cancellations stay allowed | 403 | check permission or package |
| `Billing.PaymentWayNotSelfService` | Payment way cannot be self-selected | An organization’s session sets the contract to `invoice` via `PUT /v1/me/billing/payment-way`. Only the operator sets up purchase on invoice. The opposite direction (add a payment method → collection) remains self-service | 403 | check permission or package |
| `Billing.PaymentMethodRemovalBlocked` | Last payment method stays | Removing the only payment method of a contract that is paid by collection, outside the trial period. The way out belongs to the customer: first add a new method, then remove the old one. Allowed during the trial period, where the contract stays on collection | 409 | do not retry, check the operation |
| `Billing.PaymentWayRequiresPaymentMethod` | Collection without a payment method | The operator sets a contract to `stripe` via `PUT /v1/platform/tenants/:tenantId/billing/payment-way` without a default payment method on file with the payment service provider. First the customer adds the payment method, then the contract carries the collection | 409 | do not retry, check the operation |
| `Billing.PaymentWayMissing` | No agreed payment way | An increase (order, add-on booking, upgrade) without a payment method on file and without an approved purchase on invoice. Prepayment: the service starts only once it is settled how it is paid for. Reductions stay allowed | 409 | do not retry, check the operation |
| `Billing.StripeCustomerMissing` | Customer unknown at the provider | The contract carries a customer ID that no longer exists (or never did) at the payment service provider. Not a 502: the third-party service responds correctly. The way out is the operator’s repair route (`POST /v1/platform/tenants/:tenantId/billing/relink-stripe`) | 409 | do not retry, check the operation |
| `Billing.HardwareNotOrderable` | Item not orderable | Order of a catalog item that is not a Player or has been retired (“coming soon”, discontinued). A code of its own next to `Billing.SkuNotFound`: “does not exist” sends the orderer troubleshooting, “not yet orderable” sends them to the waiting list | 409 | do not retry, check the operation |
| `Billing.BillingProfileMissing` | Billing profile missing | Order from the portal before the customer’s address has been entered. Neither money nor an item is missing, but a detail that the customer enters personally | 409 | do not retry, check the operation |
| `HardwareOrder.NotFound` | Order not found | Unknown order number in the operator view | 404 | do not retry, check the operation |
| `Invoice.NotFound` | Invoice not found | Unknown invoice ID | 404 | do not retry, check the operation |
| `Invoice.NotRefundable` | Invoice not refundable | Refund outside `paid` | 409 | do not retry, check the operation |
| `Invoice.PeriodAlreadyBilled` | Period already billed | A second period document of its own for the same period of the same contract: two cycle runs executing at the same time, or an upgrade that re-bills a period that already carries an invoice. A code of its own next to the general key conflict, because here the interface can read something off — not “some key twice” but “this period is billed” | 409 | do not retry, check the operation |
| `Stripe.WebhookSignatureInvalid` | Signature of the payment service provider invalid | Tampered or foreign delivery | 400 | correct the input |
| `Stripe.WebhookPayloadInvalid` | Body of the payment service provider unreadable | The signature was correct, but the body does not match the expected envelope. A code of its own, because the causes are far apart: a wrong secret versus a changed format at the payment service provider — whoever looks for the first when it is the second checks keys for hours | 400 | correct the input |
| `Stripe.AdapterError` | Error in the integration of the payment service provider | Faulty response from the payment service provider | 502 | retry later, report the trace ID if it recurs |
| `Billing.SetupIntentNotFound` | Payment process not found | Lookup of a process that the provider does not know or that belongs to another organization — both are the same code, so that a foreign process cannot be told apart from an invented one | 404 | do not retry, check the operation |
| `Billing.PreviewStale` | Preview outdated | The contract has changed since the preview (second tab, operator intervention, period rollover). The detail carries the freshly calculated preview, so that the page can show it and have it confirmed | 409 | reload, resend |
| `Billing.PreviewExpired` | Preview expired | The preview key has expired or is unknown. Kept apart from the outdated preview because the page reacts differently: a refresh is not a conflict | 409 | reload, resend |
| `Billing.OrderBlocked` | Order blocked | The purchase-readiness guard triggers. The detail names the reasons, and every reason comes with a way forward | 409 | do not retry, check the operation |
| `Billing.OrderUnchanged` | Order without changes | The order repeats the current state of the contract. The purchase page prefills every position with the current value — a second tab or a repeated submission is enough. A code of its own next to the outdated preview, because the page does two different things: there it reloads a fresh preview, here it only disables the button | 409 | do not retry, check the operation |
| `Billing.HardwareNotInCheckout` | Goods not in the purchase flow | The order carries one-off items, but this purchase flow creates no goods order — the delivery address is missing. No silent skipping: an ignored field would be an order that the customer has placed and nobody fulfills | 400 | correct the input |
| `Billing.TermsAcceptanceMissing` | Consent incomplete | The order does not carry all mandatory texts, or carries an outdated version. The detail names the current list, and the page resets the checkbox | 422 | correct the input |
| `Billing.CheckoutDraftNotFound` | Draft not found | Unknown, foreign, or expired draft of the purchase flow | 404 | do not retry, check the operation |
| `Billing.VatIdRequired` | VAT ID required | The tax rule requires a confirmed VAT ID of the recipient — without it there is no reverse charge and no fallback to the domestic rate | 409 | do not retry, check the operation |
| `Billing.TaxRuleNotSupported` | Tax case not supported | The tax rule does not know the case (goods abroad, missing exemption reason) — a conversation helps here, not a form | 409 | do not retry, check the operation |
| `Billing.CreditNoteNotAllowed` | Credit note not possible | Credit note for more than the invoice carries, or on a document that is not an invoice | 409 | do not retry, check the operation |
| `Billing.DunningNotDue` | Dunning level not due | The previous level is missing or its deadline is still running. An overdue notice without a preceding payment reminder cannot be justified to the customer | 409 | do not retry, check the operation |
| `Billing.DunningNoticeNotFound` | Dunning notice not found | There is no notice of this level for this invoice | 404 | do not retry, check the operation |
| `Billing.HardwareInterestNotFound` | Pre-registration not found | Unknown pre-registration or unknown confirmation token | 404 | do not retry, check the operation |
| `Billing.HardwareInterestExpired` | Confirmation link expired | The link from the confirmation message is too old. The pre-registration has to be submitted again | 410 | do not retry, check the operation |
| `Billing.VatIdInvalid` | VAT ID rejected | The European lookup service does not know the number. 422 and not 409: the body carries a detail that is factually wrong — no prerequisite is missing that would have to be created elsewhere | 422 | correct the input |
| `Billing.VatIdCheckUnavailable` | Lookup service unreachable | The European lookup service does not respond. 503 with `Retry-After` and not 502: the outage is at a third-party service that the platform cannot replace. An already confirmed state stays in place, because a disruption in Brussels is no statement about the customer | 503 | retry later, report the trace ID if it recurs |
| `Billing.PriceBackfillPending` | Recalculation still running | The period unit prices of the existing contracts have not been brought up to date yet. 503 with `Retry-After` and not 409: no prerequisite is missing that the caller could create — the platform is briefly not ready to calculate | 503 | retry later, report the trace ID if it recurs |
| `Billing.EInvoiceGuardFailed` | Document not issued | The e-invoice guard rejected the document — a defect on the platform side, not a customer error. The invoice is left untouched, and the detail carries the broken rules | 500 | retry later, report the trace ID if it recurs |
| `Subscription.NotSuspended` | Contract not suspended | Restoring a contract that is not suspended at all — a silent non-action would be a lie about the operation carried out | 409 | do not retry, check the operation |
| `Subscription.NotInTrial` | No trial | Extending the trial on a contract without a trial | 409 | do not retry, check the operation |

## Count

This page lists **51 codes**. Together with the other six error-code pages this gives 493 domain codes (4xx) and 119 server errors (5xx), 612 codes in all — the complete catalog of the platform.

## Related

- [The error format](/api/error-format)
- [Create a webhook endpoint](/webhooks/create-endpoint)
- [Handbook: Billing](https://szenera.com/docs/billing)
