PUT
/tenants/{tenantId}/sales/invoices/{id}
tenantSalesPutInvoicesById · Sales
Human Supabase USER only; permissions sales.create. Commercial documents, not fiscal ones: no tax, fiscal numbering, electronic issuance, rounding or currency conversion. An invoice is DRAFT (editable), ISSUED (frozen) or VOID (only when nothing was applied). Its total is the exact sum of its lines and must fit 6 decimals. Balances are never stored: an invoice balance is its total minus applications; a payment has an unapplied remainder; a credit is REQUESTED until a real document recognises it, and only a RECOGNIZED credit has an available balance, reduced by applications and refunds. Applications are immutable and join documents of the same party, legal entity, currency and side; they never exceed either balance. A payment states its method (cash, transfer, card, cheque, other), for a card whether debit or credit, and may name the money account it lands in or leaves from; a PENDING payment is money announced and not confirmed: it carries no applications and settles nothing until it is confirmed. Card numbers and security codes are never accepted. A sales order collected at the register is settled only by that receipt, recorded once as one payment per payment component, so the collection is never counted twice and linking never brings money in again; the POS records are not changed. Credits and physical returns are independent: neither creates the other, and naming a variant or unit moves no inventory. Saving or issuing an invoice moves none either: the devices typed on a bill and the units chosen on a sales invoice are only what its lines carry, until the invoice is confirmed together with its receipt or its delivery (see those operations). A draft may be incomplete. An invoice is posted (issued, confirmed or recognised) only with every unit of every line of a serialized article identified and linked to it, exactly as many as the line bills, and it is never completed afterwards. How an article is tracked is read from its product, whatever the request says; a line that names a physical unit without its SKU is a line of a serialized article too (409 FULFILMENT_INCOMPLETE). Issuing alone therefore works for a bill whose purchase order already received the units its lines name, and for a sales invoice whose order reserved or delivered them, the sales of the register included: the invoice keeps those units from the instant it is issued, and nothing enters or leaves again. An invoice with no order behind it that bills a serialized article is not issued alone, whatever it carries and with or without a price list (409 FULFILMENT_REQUIRED): it is confirmed together with its receipt or its delivery. A line short of units is refused with 409 UNIT_COUNT_MISMATCH. Each place in `errors` says how many units the line bills (`required`) and how many are identified (`identified`): counts, never an identifier. Recognising revenue or expense by decision is refused the same way for an invoice that bills a serialized article. Quantity articles and services need no units and behave as before. A credit is financial unless a supplier credit states COST_CORRECTION and names the receipt lines it corrects: only then does recognising it change what those goods are worth, where they still are, and never by more than they cost. A stated money account is validated against the active accounts of the entity that fit the method (PAYMENT_ACCOUNT_INVALID). Cash refunded to a customer from the cash account of the tills names the open session it leaves (CASH_SESSION_REQUIRED): the refund lowers the expected cash of that session and posts one entry; cash from anywhere else names another cash account and touches no session. When the legal entity keeps books, issuing, paying, applying, recognising and refunding each post their entry in the same transaction or fail with ACCOUNTING_SETUP_REQUIRED, ACCOUNTING_PERIOD_CLOSED, ACCOUNTING_CURRENCY_UNSUPPORTED or ACCOUNTING_AMOUNT_PRECISION; voiding posts the mirror entry. An invoice never recognises revenue by itself: revenue is earned on delivery of its order, or by an explicit recognition when it has no order. Writes are idempotent and tenant scoped; state changes carry expectedVersion.
- Autenticación
- SupabaseBearer · http bearer
Ejemplo
Los valores entre <> y {} son marcadores: sustitúyelos
por los tuyos antes de ejecutarlo.
curl --request PUT \
--url 'https://api.marky.ec/v1/tenants/{tenantId}/sales/invoices/{id}' \
--header 'Authorization: Bearer <SupabaseBearer>' \
--header 'Idempotency-Key: <Idempotency-Key>' \
--header 'Content-Type: application/json' \
--data @body.json
Parámetros
| Nombre | En | Tipo | Descripción |
|---|---|---|---|
tenantIdobligatorio
|
path | stringformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ |
|
idobligatorio
|
path | stringformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ |
|
Idempotency-Keyobligatorio
|
header | stringformato uuid |
UUIDv4/v7. Fresh user/membership/permissions before replay. |
Cuerpo (obligatorio)
application/jsonInvoiceUpdateInput
objectsin otras propiedades
-
numberobligatoriostringpatrón ^[A-Za-z0-9][A-Za-z0-9_./-]{0,63}$ -
legalEntityIdobligatoriostringformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ -
partyIdobligatoriostringformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$Customer for sales documents, supplier for purchase documents.
-
currencyCodestringpatrón ^[A-Z]{3}$ -
issueDateobligatoriostringformato dateCalendar day.
-
dueDatestring | nullformato dateCalendar day in UTC, inclusive. Null means no expiry.
-
notesstring | nulllongitud máx. 2000 -
warehouseIdstring | nullformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$Active warehouse of the legal entity where the goods of a direct purchase arrive or those of a direct sale leave. Omitted for an invoice of an order: the order has its own.
-
priceListIdstring | nullformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$Sales invoices without an order: the list a direct sale is priced by; saving one needs pricing.read. Each line with an article the list prices is the list price or an agreed price recorded with authorization, and its delivery carries those prices to the order it writes.
-
itemsarrayelementos mín. 1elementos máx. 100Cada elementoobjectsin otras propiedades-
descriptionobligatoriostringlongitud máx. 500 -
quantityobligatoriostringpatrón ^(0|[1-9][0-9]{0,11})(\.[0-9]{1,6})?$Exact amount: at most 12 integer digits and 6 decimals. No rounding, tax or FX.
-
unitPricestringpatrón ^(0|[1-9][0-9]{0,11})(\.[0-9]{1,6})?$Price of one unit. Required unless the line states discountPercent. On a sales invoice that names a price list, for an article the list prices: a value other than the list price is an agreed price and needs sales.price.override (403 PRICE_OVERRIDE_DENIED) and priceReason (400 PRICE_REASON_REQUIRED); the same value the draft already had agreed, with the same quantity, is kept without deciding again.
-
discountPercentstringpatrón ^(100(\.0{1,4})?|[0-9]{1,2}(\.[0-9]{1,4})?)$Sales invoices that name a price list, on a line with an article: a discount on the list price in force, instead of unitPrice and never with it. The service applies it once and stores the agreed unit price; a result with more than six decimals is refused (409 PRICE_DISCOUNT_NOT_EXACT). Needs sales.price.override and priceReason.
-
priceReasonstringlongitud mín. 1longitud máx. 500Sales invoices that name a price list, on a line with an article: why its price is not the list price.
-
variantIdstring | nullformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$Article of the line. Saving an invoice moves no inventory.
-
inventoryUnitIdstring | nullformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$Unit (IMEI) reference only.
-
devicesarrayelementos máx. 100Supplier bills without a purchase order: the devices of a serialized line, typed by their identifiers. They are not units until the bill is confirmed with its receipt. At most as many as the line bills, 100 in the invoice, and no identifier twice.
Cada elementoobjectsin otras propiedades-
serialNumberstring | nullpatrón ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,99}$Stored in capitals.
-
imei1string | nullpatrón ^[0-9]{15}$15 digits with a valid check digit.
-
imei2string | nullpatrón ^[0-9]{15}$Second IMEI of the same phone: one unit, never two. Different from imei1.
-
conditionstring | nulluno de "NEW", "USED", "REFURBISHED", "OPEN_BOX", "AS_IS", nullCondition the unit will be received with. Its SKU proposes it: left out, the one the SKU states is saved; where the SKU states none it must be given (409 UNIT_CONDITION_REQUIRED), because nothing is assumed to be new. A value other than the one the SKU states is refused (409 UNIT_CONDITION_MISMATCH). Read back: null only for a device saved before conditions were asked.
-
gradestring | nulluno de "A", "B", "C", nullGrade of the unit, optional. The SKU proposes its own; a value other than the one the SKU states is refused (409 UNIT_CONDITION_MISMATCH).
-
-
unitIdsarrayelementos máx. 100Units that exist. On a supplier bill with a purchase order: units that order received and no other bill names. On a sales invoice without an order: units of the article, available in the invoice warehouse, that the direct sale will deliver. Saving them reserves and moves nothing.
Cada elementostringformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
-
-
salesOrderIdstring | nullformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ -
purchaseOrderIdstring | nullformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ -
expectedVersionobligatoriointegermín. 1
Respuestas
200 Success
application/jsonInvoiceReceipt
objectsin otras propiedades
-
idobligatoriostringformato uuidpatrón ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ -
statusobligatoriouno de "DRAFT", "ISSUED", "VOID" -
versionobligatoriointegermín. 1 -
createdAtobligatoriostringformato date-time -
updatedAtobligatoriostringformato date-time -
posReceiptLinkedbooleanA register receipt of the invoiced order was recorded as its payment.
400 Invalid request/idempotency key
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-
401 Missing/invalid Supabase JWT
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-
403 Wrong identity family or permissions
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-
404 Unknown tenant resource
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-
409 Version, state, insufficient balance, mismatched party/entity/currency, duplicate number, register receipt rule, or a specific block: PAYMENT_ACCOUNT_INVALID, CASH_SESSION_REQUIRED, CASH_INSUFFICIENT, COST_SOURCE_NOT_VALUED, COST_ADJUSTMENT_EXCEEDS_COST
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-
429 Rate/quota exceeded
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-
503 Runtime/auth/governance unavailable
application/problem+jsonProblemDetails
objectsin otras propiedades
-
typeobligatoriovalor fijo "about:blank" -
statusobligatoriointeger -
codeobligatoriostring -
titleobligatoriostring -
detailobligatoriostring -
requestIdobligatoriostringformato uuid -
errorsarrayelementos máx. 200Where each problem is, for the codes that can say it: a JSON pointer into the request or the record (`/items/0/devices/1/imei1`) and the reason. A line of a serialized article that is short of units also says how many it bills and how many are identified. Never a value typed by the user, and never an identifier of a unit.
Cada elementoobjectsin otras propiedades-
pointerobligatoriostring -
codeobligatoriostring -
requiredintegermín. 0máx. 1000For a line short of units (UNITS_DIFFER_FROM_QUANTITY, RECEIPT_REQUIRED, DELIVERY_REQUIRED): how many units the line bills.
-
identifiedintegermín. 0máx. 1000For the same line: how many units are identified and linked to it. Given to every reader of the document; no IMEI or serial number is.
-