Factuarea APIDevelopers

Ofertes i preu anterior

Posa productes i packs en oferta uns dies, llegeix l'oferta des de la teva web i anuncia la rebaixa amb el preu anterior que exigeix la llei.

Una oferta fixa un preu més baix per a productes o packs entre dues dates, per als documents de l'empresa, per a la seva web o per a tots dos. Aquesta pàgina explica com crear-la, com la llegeix una web, com es calcula el preu anterior i què ha de mostrar una botiga per anunciar una rebaixa. Les ofertes estan disponibles a tots els plans que inclouen productes, des d'Esencial.

Què és una oferta

Una oferta té un nom, un inici i un final a la zona horària de l'empresa (el final és inclusiu), els canals documents i web, i un o més articles. Cada article apunta a un producte, una variant, una presentació, una configuració o un pack, amb un mode:

modeSignificat
percent_offUn percentatge entre 0 i 100, tots dos exclosos, amb 2 decimals
fixedUn preu major que 0 amb 2 decimals, sense IVA o amb IVA al règim de l'empresa

Un article no es pot repetir dins la mateixa oferta. L'estat es deriva de les dates: scheduled, active o ended, a més de cancelled, que és explícit.

  • Abans de començar, tot es pot editar.
  • Una oferta activa només admet una nova data de final i que es cancel·li. Allargar-la la marca amb is_extension: true. Canviar preus o articles respon 422 promotion_started.
  • Una oferta acabada o cancel·lada és de només lectura (422 promotion_read_only) i es pot duplicar.

Si dues ofertes cobreixen el mateix article, canal i dia, s'aplica el preu més baix i mai se sumen. Un client amb tarifa no rep l'oferta per defecte, perquè mana la tarifa. L'oferta es pot marcar perquè també els sigui d'aplicació, i llavors guanya el més baix dels dos.

API

OperacióScope
GET /v1/companies/{company}/promotions i GET …/promotions/{promotion}promotions:read
POST /v1/companies/{company}/promotions i PATCH …/promotions/{promotion}promotions:write
POST …/promotions/{promotion}/cancelpromotions:write
DELETE …/promotions/{promotion}promotions:delete

El llistat filtra per status, channel, starts_at[gte|lte], ends_at[gte|lte] i updated[gte], amb paginació per cursor. L'alta respon 201 amb Location. Els scopes depenen del mòdul de productes, així que estan disponibles allà on hi hagi productes. Errors:

StatuscodeQuan
404promotion_not_foundL'oferta no existeix
422promotion_startedCanvies preus o articles d'una oferta activa, o l'esborres
422promotion_read_onlyEdites, cancel·les o esborres una oferta acabada o cancel·lada
422invalid_promotion_itemL'article no existeix o és d'una altra empresa, o el mode o el valor són fora de rang. param apunta a l'article, per exemple items.0.target_id
422duplicate_promotion_itemEl mateix article dues vegades

Els esdeveniments són promotion.created, promotion.updated, promotion.started, promotion.ended, promotion.cancelled i promotion.deleted (aquest últim només porta {id, object: "promotion", deleted: true}). Quan una oferta comença o acaba, un programador emet a més product.updated dels seus productes i pack.updated dels seus packs, així la teva web refresca els preus sense que ningú editi res. El servidor MCP replica les operacions amb list_promotions, get_promotion, create_promotion, update_promotion, cancel_promotion i delete_promotion.

L'objecte promotion en productes i packs

La lectura d'un producte (també de cada variant, presentació i configuració) o d'un pack, en qualsevol vista, inclou sempre promotion: l'oferta que s'aplica avui al canal web, o a la date que demanis, o null. La forma del recurs mai no canvia. Una oferta només de documents es llegeix com null.

{
  "id": "019f1b77-3e90-7c24-8a1d-5f0b2e6c9d48",
  "name": "Olivo arbequina",
  "price": "39.00",
  "sale_price": { "net": "39.00", "tax": "3.90", "gross": "42.90" },
  "promotion": {
    "id": "019f2c40-8a15-7e63-9b07-4d1c5f2a8e90",
    "name": "Semana del jardín",
    "label": "Oferta",
    "price": { "net": "33.15", "tax": "3.32", "gross": "36.47" },
    "regular_price": { "net": "39.00", "tax": "3.90", "gross": "42.90" },
    "previous_price": { "net": "39.00", "tax": "3.90", "gross": "42.90" },
    "reduction_percent": 14.99,
    "announce_reduction": true,
    "starts_at": "2026-10-26T00:00:00+01:00",
    "ends_at": "2026-11-02T23:59:59+01:00",
    "is_extension": false,
    "history_complete": true
  }
}

price i sale_price segueixen significant el preu habitual, i el preu d'oferta va a promotion.price. El paràmetre date admet una data ISO 8601 i una de mal formada respon 400 parameter_invalid_iso8601. L'updated_at d'un producte canvia quan comença o acaba una oferta de qualsevol dels seus articles. POST …/products/{product}/resolve-selection retorna també la promotion de la combinació que resol.

Ofertes sobre packs

Una oferta sobre un pack substitueix el preu objectiu del pack, igual que un preu negociat: amb fixed, pel seu preu, i amb percent_off, pel percentatge sobre el preu habitual del pack. El preu derivat d'un pack i el seu repartiment fan servir sempre els preus habituals dels components, mentre que l'estalvi «comprant per separat» es mesura contra els seus preus efectius, ofertes incloses. Si els components són en oferta i ja no queda estalvi, savings val null i la web no el mostra.

Resoldre un preu per a una data i un canal

POST /v1/companies/{company}/price-lists/resolve i …/resolve-many admeten date (la data del document, sold_on o avui) i channel (documents o web). Sense ells fan servir avui i documents. Les tools MCP resolve_catalog_price i resolve_many_catalog_prices reben els mateixos dos paràmetres i retornen el mateix resultat. L'oferta és una capa que s'aplica després de la precedència del catàleg, sobre el preu habitual d'aquell nivell, i el desglossament del preview mostra el preu habitual, l'oferta aplicada i el seu origen. Per a l'olivera el 28 d'octubre de 2026 al canal web, la resposta és 33,15 € amb «Semana del jardín −15 %» sobre un preu habitual de 39,00 €.

El preu anterior

Per anunciar una rebaixa amb la llei a la mà, la botiga ha de mostrar com a preu anterior el més baix aplicat en els 30 dies previs a l'inici (art. 20 de la Llei 7/1996, en la redacció del RDL 24/2021, i art. 6 bis de la Directiva 98/6/CE). Factuarea guarda l'historial del preu públic de cada article i canal, sense tarifes, i el calcula per tu:

  • El preu anterior és el menor preu amb IVA en aquell canal durant els 30 dies previs a l'inici, sense comptar els intervals de les ofertes marcades com a producte perible a prop de caducar.
  • Es manté igual durant tota l'oferta i les seves pròrrogues.
  • Si l'article es posa a la venda per primera vegada, el preu anterior és null.
  • Durant els 30 dies següents a l'omplert de l'historial, history_complete és false: el preu anterior pot no contemplar rebaixes més antigues.

Si el preu d'oferta amb IVA no és menor que el preu anterior, o no hi ha preu anterior, l'oferta s'aplica igualment als documents i a la web però no es pot anunciar: l'API retorna announce_reduction: false i reduction_percent: null. Passa sobretot en repetir una oferta abans de 30 dies, perquè el preu de l'anterior passa a ser el preu anterior. Per exemple, l'olivera va estar a 36,47 € fins al 2 de novembre de 2026 i una oferta nova del −10 % (38,61 €) comença el 20 de novembre: el preu anterior és 36,47 € i la rebaixa no es pot anunciar. L'aplicació proposa el descompte mínim (−16 %) o la primera data d'inici que ho permet (3 de desembre de 2026).

És una guia tècnica, no assessorament jurídic. Aquestes són les regles que les dades de l'API et permeten complir:

  1. Mostra la paraula correcta. L'art. 18.2 de la LOCM reserva termes com «Oferta» o «Rebaixes», per això l'empresa tria el text de cada oferta. Mostra promotion.label, no un text propi.
  2. Anuncia només quan announce_reduction és true. Llavors mostra promotion.previous_price com a preu anterior, ratllat, al costat de promotion.price. Quan és false, mostra el preu sense «abans» i sense ratllar. L'oferta continua aplicant-se en cobrar.
  3. Prefereix l'import estalviat. Recomanem anunciar la rebaixa amb l'import estalviat (6,43 € a l'olivera), que és exacte. És previous_price.gross menys price.gross.
  4. Arrodoneix el percentatge cap avall. reduction_percent porta 2 decimals i es calcula sobre els imports amb IVA ja arrodonits: l'olivera baixa de 42,90 € a 36,47 €, que és un 14,99 % i no un 15 %. Si la teva web mostra un enter, arrodoneix cap avall (14 %) per no anunciar més rebaixa de la real.
  5. Indica la data de final. ends_at és l'últim instant inclòs. Fes servir la seva data com a priceValidUntil a schema.org (2026-11-02).
  6. B2B i peribles. El preu anterior es calcula sempre i la teva web decideix si el mostra. Les rebaixes de productes peribles a prop de caducar no abaixen el preu anterior de les ofertes futures.
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Olivo arbequina",
  "offers": {
    "@type": "Offer",
    "price": "36.47",
    "priceCurrency": "EUR",
    "priceValidUntil": "2026-11-02",
    "availability": "https://schema.org/InStock"
  }
}

Factura una venda web amb oferta

Les línies de les operacions v1 i MCP que creen o editen pressupostos, factures proforma, albarans, factures i factures recurrents admeten dos camps:

  • sold_on: la data de la comanda, amb la qual es resol l'oferta vigent. Una web que factura el 3 de novembre una comanda del 2 de novembre envia sold_on: "2026-11-02" i la línia aplica «Semana del jardín».
  • channel: documents (per defecte) o web. Una web que factura les seves comandes envia web, així una oferta només web s'aplica a la factura. Qualsevol altre valor respon 422 amb param a la línia.

Un unit_price enviat a la línia guanya sempre a l'oferta, perquè és el preu que va cobrar una integració, i la línia queda sense fotografia d'oferta. Hi ha una excepció: si el unit_price coincideix amb el preu d'oferta del seu canal i la seva data, la línia guarda la fotografia de l'oferta i compta com a venuda amb ella. Si no coincideix, és un preu cobrat sense oferta.

Sense unit_price, la línia pren el preu de l'oferta amb price_source: promotion i guarda l'oferta, el seu nom i el preu unitari habitual. Canviar la data d'un esborrany revalora les seves línies en oferta i avisa una sola vegada. En una factura recurrent, la factura generada després del final de l'oferta torna al preu habitual. Els pressupostos convertits després de l'oferta conserven el preu que tenien.

En aquesta pàgina

Et donem un cop de mà?Contactar amb suport