> Source: https://fiscal.link/integrators/docs/reference/errors/cloud
> Statusurile API-ului, stările unei comenzi și codurile rezultatului ei.

Referință API

# Erori · API Cloud

Statusurile API-ului, stările unei comenzi și codurile rezultatului ei.

## API Cloud

Mesajele de eroare sunt text simplu: `text/plain` fără antet `Accept`, sau un șir JSON cu `Accept: application/json`. O cerere care nu se poate citi deloc răspunde `application/problem+json`, cu o hartă `errors`.

| Status | Descriere |
| --- | --- |
| 202 | Comanda e în coadă. |
| 400 | Validarea a eșuat; corpul e mesajul. |
| 401 | Fără cheie, sau cheie necunoscută, revocată ori expirată. Corp gol. |
| 403 | Cheie de alt tip sau a altei organizații. Corp gol. |
| 404 | Nu există în organizația ta; corpul e mesajul. |
| 409 | Conflict cu date existente, de exemplu un nume de client deja folosit. |
| 500 | Eșec neașteptat. Corpul poate fi gol. |

## Rezultatul unei comenzi

O comandă răspunde `202` imediat; rezultatul casei îl citești apoi cu „Starea unei comenzi”: codul în `statusCode`, textul în `message`. Un rezultat reușit e `statusCode` 200 cu răspunsul în `data`; o eroare a casei e un obiect cu `statusCode` și `message`.

| `statusCode` | Descriere |
| --- | --- |
| 200 | Succes. |
| 400 | Casa a refuzat, sau corpul încalcă o regulă a aplicației FiscalLink. Majoritatea regulilor se verifică înainte de deschiderea bonului; un bon care eșuează după deschidere e anulat, iar mesajul se termină cu `| Receipt cancelled successfully`. |
| 404 | `unknown_command`: aplicația FiscalLink de pe casă e prea veche pentru această comandă. |
| 409 | La citirea cotelor TVA: verificarea cotelor e oprită pe casă. |
| 424 | Transport: imprimanta nu e conectată sau n-a răspuns la timp. |
| 499 | `client_cancelled`: comanda a fost anulată în timp ce rula. |
| 500 | Eroare neașteptată în aplicație; mesajul numește excepția. Un bon fiscal deja deschis e anulat. |

Erorile pe care aplicația le dă înainte să ajungă la casă au corpuri fixe:

```json
{ "error": "unknown_command", "commandType": "cashRegister.printFiscalReceipt" }
```

```json
{ "error": "invalid_payload", "detail": "<detail>" }
```

```json
{ "error": "internal_error" }
```

```json
{ "error": "client_cancelled" }
```

## Câmpurile răspunsului

Obiectele unui răspuns, cu toate câmpurile lor:

-   [GetCommandStatusResponse](https://fiscal.link/integrators/docs/reference/objects/cloud-command-status): Starea unei comenzi și răspunsul casei.
-   [IntegratorCommandListItemResponse](https://fiscal.link/integrators/docs/reference/objects/cloud-command-list-item): Un rând din lista de comenzi.
-   [CommandResult](https://fiscal.link/integrators/docs/reference/objects/cloud-command-result-envelope): Plicul din `body` al unei comenzi terminate.
-   [CommandFramingError](https://fiscal.link/integrators/docs/reference/objects/cloud-framing-error): Corpul din `body` când comanda nu a ajuns să ruleze pe casă.

## Stările unei comenzi

Câmpul `status` al unei comenzi. Pe `Failed` și `TimedOut` citește rezultatul:

| Status | Mesaj |
| --- | --- |
| `Pending` | În coadă. |
| `Processing` | Casa o execută. |
| `Sent` | Stare veche; nu se mai scrie. |
| `Failed` | A eșuat. |
| `Cancelled` | Anulată. |
| `Succeeded` | A reușit. |
| `TimedOut` | A expirat fără răspuns. |

## Răspunsurile aplicației înainte de comandă

Corpuri fixe, în \`body\`, cu statusul din tabel:

| Status | `error` | Mesaj |
| --- | --- | --- |
| 404 | `unknown_command` | Aplicația de pe casă nu cunoaște acest tip de comandă. |
| 400 | `invalid_payload` | Corpul comenzii nu se poate citi; `detail` spune de ce. |
| 500 | `internal_error` | Eroare neașteptată în aplicație. |
| 499 | `client_cancelled` | Comanda a fost anulată în timp ce rula. |

## `resultCode` și `code`

Motivul aplicației, pentru programe: `code` în corpul rezultatului, `resultCode` pe rândul din listă. E `null` în rest și nu se completează pe sandbox.

| `code` | Mesaj |
| --- | --- |
| `receipt_outcome_unknown` | Nu se știe dacă bonul s-a tipărit. O astfel de comandă nu se retrimite; doar verificarea pe casă lămurește. |
| `receipt_close_unconfirmed` | Încercarea s-a încheiat fără confirmarea închiderii; bonul poate fi pe hârtie. |
| `idempotency_key_reused` | Cheia a fost folosită pentru alt bon. Trimite o cheie nouă. |

## `unreadFigures`

Pe un raport reușit, numele cifrelor care nu s-au putut citi: `reportNumber`, `taxGroups`, `payments`. O cifră listată aici lipsește, nu e 0,00. Doar Tremol îl completează.

Mesajele din rezultatul unei comenzi sunt cele ale API-ului local: [Erori · API local](https://fiscal.link/integrators/docs/reference/errors/local)

## Refuzurile API-ului

Mesajele de mai jos vin din codul aplicației și al API-ului. Coloana „Cheie în surse” numește mesajul în cod; pe fir ajung doar statusul, `message` și, unde scrie, `code`. Un `…` ține locul unei valori din cerere sau din casă. Textele de validare sunt doar în engleză.

### Idempotency-Key

`400`: trimite un GUID. `409`: o comandă nouă are nevoie de o cheie nouă.

| Status | `code` | Mesaj | Cheie în surse |
| --- | --- | --- | --- |
| 400 | — | The Idempotency-Key header must be one GUID, e.g. 3f2c1a9e-7b4d-4e8a-9c21-5d6f7a8b9c0d. | `COMMAND_IDEMPOTENCY_KEY_INVALID` |
| 409 | — | This Idempotency-Key was already used for a different request. Send a new key for a new command. | `COMMAND_IDEMPOTENCY_KEY_REUSED` |

### Clienți, case și comenzi

`400`: corectează cererea. `404`: verifică id-ul. `409`: există deja. `500`: nu ține de cerere.

| Status | `code` | Mesaj | Cheie în surse |
| --- | --- | --- | --- |
| 400 | — | One of the client fields exceeds its maximum length. | `INTEGRATOR_CLIENT_FIELD_TOO_LONG` |
| 400 | — | The client still has register slots; release or move them first. | `INTEGRATOR_CLIENT_HAS_SLOTS` |
| 400 | — | Client name is required. | `INTEGRATOR_CLIENT_NAME_REQUIRED` |
| 400 | — | Client name must be at most 200 characters. | `INTEGRATOR_CLIENT_NAME_TOO_LONG` |
| 400 | — | This command needs a JSON object body. | `INTEGRATOR_COMMAND_BODY_REQUIRED` |
| 400 | — | Select at least one register to send the command to. | `INTEGRATOR_COMMAND_NO_TARGETS` |
| 400 | — | Cash in, cash out and opening the drawer go to one register at a time. | `INTEGRATOR_COMMAND_ONE_REGISTER_ONLY` |
| 400 | — | Unknown command status filter. | `INTEGRATOR_COMMAND_STATUS_INVALID` |
| 400 | — | Too many registers selected for a single command. | `INTEGRATOR_COMMAND_TOO_MANY_TARGETS` |
| 400 | — | This command type cannot be sent by an integrator organization. | `INTEGRATOR_COMMAND_TYPE_NOT_ALLOWED` |
| 400 | — | The organization's integrator subscription is not active. | `INTEGRATOR_PLAN_NOT_ACTIVE` |
| 400 | — | The slot already has a register serial bound. | `INTEGRATOR_REGISTER_ALREADY_HAS_SERIAL` |
| 400 | — | The register has already been removed. | `INTEGRATOR_REGISTER_ALREADY_REMOVED` |
| 400 | — | Registers no longer carry their own activation code. Use the client's activation code instead. | `INTEGRATOR_REGISTER_CODE_IS_PER_CLIENT` |
| 400 | — | The slot has no register serial bound. | `INTEGRATOR_REGISTER_HAS_NO_SERIAL` |
| 400 | — | The slot is not active. | `INTEGRATOR_REGISTER_NOT_ACTIVE` |
| 400 | — | Remove the register first; only a removed registration can be erased from the fleet. | `INTEGRATOR_REGISTER_NOT_REMOVED` |
| 400 | — | A register cannot be detached from a slot. Release the slot to stop paying for it; a different register needs a slot of its own. | `INTEGRATOR_REGISTER_SERIAL_IS_PERMANENT` |
| 400 | — | The register still has a paid month running. It can be erased once that month has ended. | `INTEGRATOR_REGISTER_STILL_COVERED` |
| 400 | — | The billing period must be a yyyy-MM month. | `INTEGRATOR_USAGE_PERIOD_INVALID` |
| 400 | — | createdFrom must be on or before createdTo. | `INTEGRATOR_CLIENT_CREATED_RANGE_INVALID` |
| 400 | — | Client sort must be one of: name, createdAt, registerCount. | `INTEGRATOR_CLIENT_SORT_INVALID` |
| 400 | — | Register sort must be one of: activatedAt, serialNumber, clientName. | `INTEGRATOR_REGISTER_SORT_INVALID` |
| 400 | — | Register status must be one of: AwaitingSerial, Active, Suspended, Removed. | `INTEGRATOR_REGISTER_STATUS_INVALID` |
| 400 | — | Sort direction must be one of: asc, desc. | `SORT_DIRECTION_INVALID` |
| 400 | — | The Idempotency-Key header must be one GUID, e.g. 3f2c1a9e-7b4d-4e8a-9c21-5d6f7a8b9c0d. | `COMMAND_IDEMPOTENCY_KEY_INVALID` |
| 404 | — | Client does not exist. | `INTEGRATOR_CLIENT_DOES_NOT_EXIST` |
| 404 | — | Command does not exist. | `INTEGRATOR_COMMAND_DOES_NOT_EXIST` |
| 404 | — | Register slot does not exist. | `INTEGRATOR_REGISTER_DOES_NOT_EXIST` |
| 404 | — | No register with this serial on an active slot of this organization. | `INTEGRATOR_REGISTER_NOT_COMMANDABLE` |
| 404 | — | Tenant does not exist. | `TENANT_DOES_NOT_EXIST` |
| 409 | — | A client with this name already exists. | `INTEGRATOR_CLIENT_ALREADY_EXISTS` |
| 409 | — | This Idempotency-Key was already used for a different request. Send a new key for a new command. | `COMMAND_IDEMPOTENCY_KEY_REUSED` |
| 500 | — | Generating the client activation code failed. | `INTEGRATOR_ACTIVATION_CODE_MINT_FAILED` |
| 500 | — | Client creation failed. | `INTEGRATOR_CLIENT_CREATE_FAILED` |
| 500 | — | Client deletion failed. | `INTEGRATOR_CLIENT_DELETE_FAILED` |
| 500 | — | Client update failed. | `INTEGRATOR_CLIENT_UPDATE_FAILED` |
| 500 | — | Adding the register failed. | `INTEGRATOR_REGISTER_ADD_FAILED` |
| 500 | — | Binding the register serial failed. | `INTEGRATOR_REGISTER_BIND_FAILED` |
| 500 | — | Erasing the register from the fleet failed. | `INTEGRATOR_REGISTER_FORGET_FAILED` |
| 500 | — | Moving the slot failed. | `INTEGRATOR_REGISTER_MOVE_FAILED` |
| 500 | — | Removing the register failed. | `INTEGRATOR_REGISTER_REMOVE_FAILED` |

### Sandbox

La fel ca mai sus, pe casele de test.

| Status | `code` | Mesaj | Cheie în surse |
| --- | --- | --- | --- |
| 400 | — | Client does not exist. | `SANDBOX_CLIENT_DOES_NOT_EXIST` |
| 400 | — | The client still has mock registers; release or move them first. | `SANDBOX_CLIENT_HAS_REGISTERS` |
| 400 | — | Unknown command origin filter. | `SANDBOX_COMMAND_ORIGIN_INVALID` |
| 400 | — | Operator password must be between 1 and 32 characters. | `SANDBOX_REGISTER_OPERATOR_PASSWORD_INVALID` |
| 400 | — | Register serial is invalid. | `SANDBOX_REGISTER_SERIAL_INVALID` |
| 404 | — | Command does not exist. | `SANDBOX_COMMAND_DOES_NOT_EXIST` |
| 404 | — | Command could not be enqueued. | `SANDBOX_COMMAND_ENQUEUE_FAILED` |
| 404 | — | Mock register does not exist. | `SANDBOX_REGISTER_DOES_NOT_EXIST` |
| 404 | — | No register with this serial on an active slot of this organization. | `SANDBOX_REGISTER_NOT_COMMANDABLE` |
| 409 | — | A client with this name already exists. | `SANDBOX_CLIENT_ALREADY_EXISTS` |
| 409 | — | This serial is already on an active mock register of the sandbox. | `SANDBOX_REGISTER_SERIAL_ALREADY_ACTIVE` |
| 500 | — | Client creation failed. | `SANDBOX_CLIENT_CREATE_FAILED` |
| 500 | — | Client deletion failed. | `SANDBOX_CLIENT_DELETE_FAILED` |
| 500 | — | Client update failed. | `SANDBOX_CLIENT_UPDATE_FAILED` |
| 500 | — | Mock register creation failed. | `SANDBOX_REGISTER_CREATE_FAILED` |
| 500 | — | Mock register deletion failed. | `SANDBOX_REGISTER_DELETE_FAILED` |
| 500 | — | Mock register update failed. | `SANDBOX_REGISTER_UPDATE_FAILED` |

### Facturare

Doar pe rutele Cloud Dashboard, nu cu o cheie API: `400` cu `{ code, message }`.

| Status | `code` | Mesaj | Cheie în surse |
| --- | --- | --- | --- |
| 400 | `already-active` | The tenant already has an active subscription. Manage it from the billing portal. | `BILLING_TENANT_HAS_ACTIVE_SUBSCRIPTION` |
| 400 | `plan-invalid` | Tenant plan type is invalid. | `TENANT_PLAN_TYPE_INVALID` |
| 400 | `plan-not-customer` | The selected plan is not available. Choose a paid plan. | `TENANT_PLAN_TYPE_NOT_CUSTOMER` |
| 400 | `interval-invalid` | Billing interval is invalid. | `BILLING_INTERVAL_INVALID` |
| 400 | `plan-not-allowed-for-kind` | The selected plan is not available for this organization kind. | `TENANT_PLAN_NOT_ALLOWED_FOR_KIND` |
| 400 | `integrator-plan-annual-only` | The integrator plan is billed annually. | `TENANT_INTEGRATOR_PLAN_ANNUAL_ONLY` |
| 400 | `no-billing-account` | No Stripe customer exists for this tenant yet. Start a subscription first. | `BILLING_TENANT_HAS_NO_STRIPE_CUSTOMER` |
| 400 | `not-billable` | This organization cannot be given a billing account. | `BILLING_TENANT_NOT_BILLABLE` |
| 400 | `details-incomplete` | Add the organization's legal name and CUI in the organization settings before setting up billing. | `BILLING_TENANT_DETAILS_INCOMPLETE` |
| 400 | `no-owner-contact` | The organization has no owner with an email address to bill. | `BILLING_TENANT_HAS_NO_OWNER_CONTACT` |
| 400 | `tax-id-rejected` | Stripe rejected the organization's CUI. Correct it in the organization settings and try again. | `BILLING_TENANT_TAX_ID_REJECTED` |
| 400 | `checkout-session-mismatch` | Stripe checkout session does not belong to this tenant. | `BILLING_CHECKOUT_SESSION_TENANT_MISMATCH` |
| 400 | `invoice-status-invalid` | Invoice status is invalid. Use draft, open, paid, uncollectible or void. | `BILLING_INVOICE_STATUS_INVALID` |
| 400 | `invalid-request` | Un refuz pe care tabelul de coduri nu îl cunoaște încă. | — |

### Licențe

Doar pe rutele Cloud Dashboard, nu cu o cheie API. Unde statusul lipsește, nu l-am putut stabili din cod.

| Status | `code` | Mesaj | Cheie în surse |
| --- | --- | --- | --- |
| 400 | — | This licensing session has no register serial yet. | `HANDSHAKE_SESSION_HAS_NO_SERIAL` |
| 400 | — | This licensing session is not in a state that allows this action. | `HANDSHAKE_SESSION_INVALID_STATE` |
| 400 | — | This license is already linked to a register. | `LICENSE_ALREADY_LINKED` |
| 400 | — | The number of licenses requested is invalid. | `LICENSE_COUNT_INVALID` |
| 400 | — | Once a license is activated on a register it can't be deactivated or moved. Eliminate the license to free the seat, or contact support to change the register it's on. | `LICENSE_DEACTIVATION_NOT_SUPPORTED` |
| 400 | — | This license is not scheduled to downgrade, so there is nothing to cancel. | `LICENSE_DOWNGRADE_NOT_PENDING` |
| 400 | — | This license is scheduled to migrate to a tenant and cannot be downgraded. | `LICENSE_DOWNGRADE_PENDING_MIGRATION` |
| 400 | — | This license is scheduled for removal and cannot be downgraded. | `LICENSE_DOWNGRADE_PENDING_REMOVAL` |
| 400 | — | The license subscription is not active, so it cannot be downgraded right now. | `LICENSE_DOWNGRADE_SUBSCRIPTION_NOT_ACTIVE` |
| 400 | — | A gifted license must have an expiry date in the future. | `LICENSE_GIFT_EXPIRY_INVALID` |
| 400 | — | Failed to link the license to the register. | `LICENSE_LINK_FAILED` |
| 400 | — | This license's register has been paired into the organization, so the migration can no longer be canceled. | `LICENSE_MIGRATE_CANCEL_LINKED_TO_REGISTER` |
| 400 | — | A selected license has no pending migration to cancel. | `LICENSE_MIGRATE_CANCEL_NOT_PENDING` |
| 400 | — | Select at least one license to cancel the migration for. | `LICENSE_MIGRATE_CANCEL_NO_LICENSES` |
| 400 | — | Failed to schedule the license migration. | `LICENSE_MIGRATE_FAILED` |
| 400 | — | Select at least one license to migrate. | `LICENSE_MIGRATE_NO_LICENSES` |
| 400 | — | A selected license has a plan change this period and cannot be migrated until it settles or is canceled. | `LICENSE_MIGRATE_PENDING_DOWNGRADE` |
| 400 | — | A selected license is already scheduled for removal and cannot be migrated. | `LICENSE_MIGRATE_PENDING_REMOVAL` |
| 400 | — | A register in this subscription is paired to a different tenant than the migration target. | `LICENSE_MIGRATE_REGISTER_TENANT_MISMATCH` |
| 400 | — | Only personal license subscriptions can be migrated to a tenant. | `LICENSE_MIGRATE_SOURCE_NOT_PERSONAL` |
| 400 | — | You do not manage the target tenant, so licenses cannot be migrated to it. | `LICENSE_MIGRATE_TARGET_NOT_MANAGED` |
| 400 | — | The organization has no billing account yet, so it could not be charged for the license when the current period ends. Set up its billing first. | `LICENSE_MIGRATE_TARGET_TENANT_HAS_NO_BILLING` |
| 400 | — | The organization has no saved payment method, so it could not be charged for the license when the current period ends. Add a card to its billing account first. | `LICENSE_MIGRATE_TARGET_TENANT_HAS_NO_PAYMENT_METHOD` |
| 400 | — | This license is linked to a register and cannot be used for this action. | `LICENSE_NOT_FREE` |
| 400 | — | The license subscription is not active. The license cannot be used right now. | `LICENSE_NOT_GRANTING_ACCESS` |
| 400 | — | This license is not linked to a register. | `LICENSE_NOT_LINKED` |
| 400 | — | This license is not scheduled for removal, so there is nothing to cancel. | `LICENSE_REMOVAL_CANCEL_NOT_PENDING` |
| 400 | — | This license is scheduled to downgrade. Cancel the downgrade before removing it. | `LICENSE_REMOVE_PENDING_DOWNGRADE` |
| 400 | — | Failed to revoke the license from the register. | `LICENSE_REVOKE_FAILED` |
| 400 | — | No license subscription exists yet. Purchase a license first. | `LICENSE_SUBSCRIPTION_DOES_NOT_EXIST` |
| 400 | — | No Stripe customer exists for your license subscription yet. Purchase a license first. | `LICENSE_SUBSCRIPTION_HAS_NO_STRIPE_CUSTOMER` |
| 400 | — | This license already has a plan change this period. Cancel it before making another. | `LICENSE_TIER_CHANGE_HAS_PENDING_SWITCH` |
| 400 | — | The requested license type and billing interval combination is not supported. | `LICENSE_TYPE_INTERVAL_INVALID` |
| 400 | — | Failed to unlink the license from the register. | `LICENSE_UNLINK_FAILED` |
| 400 | — | This license was not upgraded this period, so there is no upgrade to cancel. | `LICENSE_UPGRADE_CANCEL_NOT_PENDING` |
| 400 | — | This license is scheduled to migrate to a tenant and cannot be upgraded. | `LICENSE_UPGRADE_PENDING_MIGRATION` |
| 400 | — | This license is scheduled for removal and cannot be upgraded. | `LICENSE_UPGRADE_PENDING_REMOVAL` |
| 400 | — | The license subscription is not active, so it cannot be upgraded right now. | `LICENSE_UPGRADE_SUBSCRIPTION_NOT_ACTIVE` |
| 400 | — | This register is already paired to a tenant. Unpair it first. | `REGISTER_ALREADY_PAIRED` |
| 400 | — | This register has no license to authorize this device against. | `REGISTER_NOT_LICENSED_FOR_REAUTH` |
| 400 | — | This register is connected through an integrator and does not take its own license. Ask the integrator to release it first, or license a different register. | `REGISTER_SERIAL_MANAGED_BY_INTEGRATOR` |
| 404 | — | Licensing session not found. | `HANDSHAKE_SESSION_DOES_NOT_EXIST` |
| 404 | — | License not found. | `LICENSE_DOES_NOT_EXIST` |
| 409 | — | This licensing session was already claimed by another user. | `HANDSHAKE_SESSION_CLAIMED_BY_ANOTHER_USER` |
| 409 | — | This license is already on the Commerce plan. | `LICENSE_ALREADY_COMMERCE` |
| 409 | — | This license is already on the Essential plan. | `LICENSE_ALREADY_ESSENTIAL` |
| 409 | — | This license is already scheduled for removal at the end of the current period. | `LICENSE_ALREADY_PENDING_REMOVAL` |
| 409 | — | This license is already scheduled to downgrade at the end of the current period. | `LICENSE_DOWNGRADE_ALREADY_PENDING` |
| 409 | — | Cannot release this license; the subscription would drop below the number of linked licenses. | `LICENSE_RELEASE_BELOW_LINKED` |
| 409 | — | This register is already assigned to a tenant. | `REGISTER_SERIAL_ALREADY_ASSIGNED` |
| 500 | — | Failed to start license activation. | `LICENSE_ACTIVATION_FAILED` |
| 500 | — | Failed to create a Stripe checkout session for the license subscription. | `LICENSE_CHECKOUT_SESSION_FAILED` |
| 500 | — | Failed to fetch invoices from Stripe. | `LICENSE_INVOICES_FETCH_FAILED` |
| 500 | — | Failed to cancel the scheduled license migration. | `LICENSE_MIGRATE_CANCEL_FAILED` |
| 500 | — | Failed to execute the scheduled license migration. | `LICENSE_MIGRATE_EXECUTION_FAILED` |
| 500 | — | Failed to create a Stripe customer portal session for the license subscription. | `LICENSE_PORTAL_SESSION_FAILED` |
| 500 | — | Failed to cancel the scheduled license removal. | `LICENSE_REMOVAL_CANCEL_FAILED` |
| 500 | — | Failed to update the license quantity on the subscription. | `LICENSE_UPDATE_FAILED` |
| 500 | — | Failed to process the Stripe webhook event. | `LICENSE_WEBHOOK_PROCESSING_FAILED` |
| — | — | This licensing session has expired. | `HANDSHAKE_SESSION_EXPIRED` |
| — | — | Failed to cancel the scheduled license downgrade. | `LICENSE_DOWNGRADE_CANCEL_FAILED` |
| — | — | Failed to downgrade the license. | `LICENSE_DOWNGRADE_FAILED` |
| — | — | This migration would exceed the number of register licenses allowed by the target tenant's plan. Upgrade the plan or migrate fewer licenses. | `LICENSE_MIGRATE_EXCEEDS_TENANT_CAP` |
| — | — | Failed to cancel the license upgrade. | `LICENSE_UPGRADE_CANCEL_FAILED` |
| — | — | Failed to upgrade the license. | `LICENSE_UPGRADE_FAILED` |
| — | — | This purchase would exceed the number of register licenses allowed by the tenant's plan. Upgrade the plan or buy fewer licenses. | `TENANT_LICENSE_LIMIT_REACHED_FOR_PLAN` |
