Después de modelar correctamente nuestro catálogo, necesitamos entender una de las partes más importantes de cualquier sistema de comercio electrónico: cómo se calcula el precio que finalmente paga el cliente.
A primera vista podría parecer sencillo:
Producto
↓
Precio
↓
TotalPero en un sistema real pueden intervenir muchos factores:
- Precio base
- Tipo de cliente
- Store
- Moneda
- Cantidad
- Promociones
- Cupones
- Impuestos
- Shipping
- Fees
Por eso Drupal Commerce separa diferentes conceptos relacionados con pricing.
Comprender estas diferencias es fundamental antes de comenzar a configurar promociones, impuestos o reglas de precios.
1. El precio no es necesariamente un valor fijo
En el modelo más sencillo podemos tener:
Product Variation
SKU: SHIRT-BLACK-M
Price: 25.00 EUREl producto cuesta 25 EUR y no existe ninguna otra regla.
Pero podemos encontrar escenarios más complejos:
Precio base
↓
Cliente B2B
↓
Descuento por volumen
↓
Promoción
↓
Impuestos
↓
Shipping
↓
Total finalPor tanto debemos distinguir claramente entre:
- El precio almacenado
- El precio resuelto
- El precio unitario del Order Item
- Los Adjustments
- El total del pedido
2. Price: precio de la Product Variation
Las Product Variations tienen un campo de precio.
Por ejemplo:
Product
Classic T-Shirt
Variation
Black / Medium
SKU
TS-BLK-M
Price
25.00 EUREste precio representa el valor comercial inicial de la entidad comprable.
Podemos pensar inicialmente:
Product Variation
↓
Price
↓
25.00 EUREn una tienda sencilla este valor puede ser suficiente.
Pero Commerce permite que el precio utilizado durante la compra sea determinado dinámicamente.
3. Price es cantidad y moneda
Un precio no es simplemente un número.
Conceptualmente contiene al menos:
Number
+
CurrencyPor ejemplo:
25.00 EUR
99.90 USD
120.00 CHFPor este motivo no deberíamos tratar los precios como campos numéricos genéricos.
La moneda forma parte del significado del precio.
100 EUR ≠ 100 USD ≠ 100 CHF4. List Price
Además del Price principal, una Product Variation puede disponer de un List Price.
Podemos utilizarlo conceptualmente para representar un precio de referencia.
Por ejemplo:
List price
100 EUR
Price
79 EURLa presentación podría mostrar:
Antes: 100 EUR
Ahora: 79 EUREs importante entender que el List Price es principalmente información de presentación.
No debemos confundirlo con el sistema de promociones.
Una promoción representa una regla comercial aplicada durante el cálculo de la compra.
Por tanto:
List Price
= precio de referencia para mostrar
Promotion
= regla que modifica económicamente una compra5. El precio almacenado no siempre es el precio utilizado
Drupal Commerce permite resolver dinámicamente el precio de una entidad comprable.
Esto significa que aunque tengamos:
Variation Price
100 EURel precio utilizado para un determinado cliente podría ser:
Customer A
→ 100 EUR
Customer B
→ 90 EUR
Distributor
→ 75 EURO podría depender de otras condiciones:
Store
Customer
Quantity
Date
Currency
Price listAquí aparece un concepto fundamental de Commerce:
Price Resolver.
6. Price Resolver
Un Price Resolver determina qué precio debe utilizarse para una entidad comprable dentro de un contexto determinado.
En el caso sencillo:
Product Variation
↓
Price Resolver
↓
Price field
↓
25 EUREl resolver por defecto puede simplemente utilizar el precio almacenado en la Variation.
Pero podemos introducir otras fuentes.
Por ejemplo:
Product Variation
↓
Price Resolver
↓
Price List
↓
Customer Group
↓
Resolved PriceSupongamos:
SKU: PRODUCT-001
Retail price:
100 EUR
Distributor price:
80 EURDependiendo del comprador:
Regular Customer
↓
100 EUR
Distributor
↓
80 EURNo necesitamos necesariamente modificar el Product Variation cada vez.
El precio puede resolverse dinámicamente.
7. Price Resolver frente a Promotion
Esta diferencia es especialmente importante.
Supongamos que un distribuidor tiene permanentemente un precio especial.
Retail
100 EUR
Distributor
80 EURPodríamos interpretar 80 EUR como el precio real de ese producto para ese cliente.
Esto encaja conceptualmente con:
Price Resolver
↓
Resolved Price
80 EUREn cambio, supongamos que durante una semana tenemos:
Summer Sale
20 % discountAhora podríamos tener:
Resolved Price
100 EUR
↓
Promotion
-20 EUR
↓
Final contribution
80 EURPodemos utilizar esta distinción:
¿Cuál es el precio real
para este cliente/contexto?
↓
Price Resolver
¿Qué descuento o recargo
aplicamos sobre la compra?
↓
Adjustment8. Order Item Unit Price
Cuando añadimos una Product Variation al carrito, Commerce crea un Order Item.
Ese Order Item tiene un Unit Price.
Por ejemplo:
Product Variation
SKU: TS-BLK-M
Resolved Price:
25 EUR
↓
Add to cart
↓
Order Item
Quantity: 2
Unit Price: 25 EURPodemos pensar:
Product Variation Price
↓
Price Resolution
↓
Order Item Unit PriceEl Order Item representa la compra concreta, por lo que su precio participa posteriormente en el cálculo del pedido.
9. Quantity y Total Price
El siguiente cálculo es sencillo:
Unit Price × Quantity
↓
Order Item TotalPor ejemplo:
Unit Price
25 EUR
Quantity
3
Subtotal
75 EURSin embargo, todavía pueden aparecer promociones, impuestos y otros Adjustments.
10. Adjustments
Los Adjustments son uno de los conceptos centrales del sistema de pricing de Drupal Commerce.
Un Adjustment representa una modificación económica aplicada a un Order o a un Order Item.
Por ejemplo:
Promotion
-10 EUR
Tax
+19 EUR
Shipping
+8 EUR
Fee
+2 EURPodemos visualizarlo así:
Subtotal
100 EUR
Promotion
-10 EUR
Tax
+17.10 EUR
Shipping
+8 EUR
────────────────
Total
115.10 EURLos Adjustments permiten mantener separados los diferentes conceptos que contribuyen al total.
11. Un Adjustment puede ser positivo o negativo
Podemos pensar en dos grandes grupos.
Adjustment negativo
Reduce el total.
Promotion
-20 EURAdjustment positivo
Incrementa el total.
Tax
+19 EUR
Shipping
+8 EUR
Special fee
+3 EURConceptualmente:
Base amount
+
Adjustments
=
Final amount12. Tipos habituales de Adjustment
Commerce puede trabajar con diferentes tipos de Adjustment.
Entre los más importantes encontramos:
Promotion
Tax
Fee
CustomOtros módulos pueden introducir tipos adicionales.
Por ejemplo, Commerce Shipping puede incorporar:
Shipping
Shipping PromotionEsto crea una arquitectura extensible.
Order / Order Item
│
├── Promotion adjustment
├── Tax adjustment
├── Shipping adjustment
└── Custom adjustment13. Order Item Adjustments frente a Order Adjustments
Los Adjustments pueden aplicarse en diferentes niveles.
Podemos tener un descuento específico sobre un producto:
Order Item
Laptop
1000 EUR
Promotion
-100 EUR
Adjusted item
900 EURO un descuento sobre el pedido completo:
Order
Subtotal
1000 EUR
Order promotion
-100 EUR
Adjusted subtotal
900 EURLa diferencia puede ser importante para:
- Presentación
- Impuestos
- Reembolsos
- Reporting
- Integraciones
14. Promotions
Una Promotion define una estrategia comercial de descuento.
Podemos tener promociones como:
10 % off all products
20 EUR off orders over 200 EUR
15 % off laptops
Free shipping over 100 EUR
10 % discount for distributorsConceptualmente una promoción responde a tres preguntas:
¿Cuándo se aplica?
↓
Conditions
¿Qué beneficio obtiene?
↓
Offer
¿Durante qué periodo existe?
↓
Availability15. Conditions y Offers
Supongamos:
Aplicar 10 % de descuento cuando el pedido supere 100 EUR.
Podemos separar:
Condition
Order total ≥ 100 EUR
Offer
10 % discountOtro ejemplo:
Aplicar 20 % de descuento a productos de la categoría Shoes.
Condition
Product category = Shoes
Offer
20 % discountEsta separación permite construir promociones reutilizables y comprensibles.
16. Promoción sobre el pedido
Una promoción puede afectar al Order completo.
Por ejemplo:
Subtotal
200 EUR
Promotion
10 % off order
Adjustment
-20 EUR
Result
180 EUREste tipo de promoción tiene sentido cuando el beneficio depende del pedido global.
17. Promoción sobre productos
También podemos aplicar promociones solamente a determinados Order Items.
Por ejemplo:
Order
Laptop
1000 EUR
Promotion -100 EUR
Mouse
50 EUR
No promotionEl descuento está asociado al producto correspondiente y no al Order completo.
18. Coupons
Un Coupon permite que el cliente active una promoción mediante un código.
Por ejemplo:
Promotion
Summer Sale
Coupon
SUMMER2026El cliente introduce:
SUMMER2026y, si se cumplen las condiciones, se aplica la promoción correspondiente.
Es importante separar los conceptos:
Promotion
= regla comercial
Coupon
= código que puede activar
una promociónNo todas las promociones necesitan Coupons.
Por ejemplo:
All orders over 100 EUR
→ Free shippingpuede aplicarse automáticamente.
19. Promotions no deberían reemplazar todas las reglas de pricing
Puede resultar tentador representar cualquier diferencia de precio mediante descuentos.
Por ejemplo:
Retail customer
100 EUR
Distributor
20 % promotion
→ 80 EUREsto puede ser apropiado en determinados negocios.
Pero si 80 EUR es realmente el precio contractual permanente para distribuidores, quizá sea más correcto modelarlo como pricing contextual.
Retail Price List
100 EUR
Distributor Price List
80 EURLa pregunta debe ser:
¿Estamos cambiando el precio base para este contexto o estamos aplicando una promoción comercial?
Son conceptos relacionados, pero diferentes.
20. Impuestos como Adjustments
Los impuestos también participan en el sistema de Adjustments.
Supongamos:
Price
100 EUR
VAT
19 %
Tax adjustment
+19 EUR
Total
119 EURConceptualmente:
Tax rule
↓
Tax calculation
↓
Tax Adjustment
↓
Order / Order ItemEsto permite identificar cuánto del total corresponde a impuestos.
21. Tax Type
Drupal Commerce organiza la configuración fiscal alrededor de Tax Types.
Podemos tener, por ejemplo:
Tax Type
European VAT
Rates
├── Standard
├── Reduced
└── ZeroLa implementación concreta dependerá del país y de los requisitos fiscales del negocio.
Antes de configurarlos necesitamos tener claro:
- En qué países se vende
- Desde dónde vende la empresa
- Qué productos tienen tasas diferentes
- Qué clientes pueden estar exentos
- Si los precios se muestran con o sin impuestos
22. Impuestos incluidos y no incluidos
Existen dos formas conceptuales frecuentes de presentar impuestos.
Precio sin impuestos incluidos
Product
100 EUR
VAT
+19 EUR
Total
119 EURPrecio con impuestos incluidos
Displayed price
119 EUR
Included VAT
19 EUREn ambos casos necesitamos conocer el componente fiscal, aunque la presentación y el cálculo sean diferentes.
Esta decisión debe definirse durante el Discovery del negocio y no cuando estamos construyendo la página del producto.
23. Diferentes productos pueden tener tasas diferentes
No todos los productos tienen necesariamente la misma tasa fiscal.
Por ejemplo:
Physical Product
→ Standard VAT
Book
→ Reduced VAT
Exempt service
→ Zero / exempt rateEsto significa que el sistema necesita saber qué tratamiento fiscal corresponde a cada producto o variación.
Esta información puede formar parte del modelado de la Product Variation cuando el negocio lo requiera.
24. Precio visible frente a precio final del pedido
Una distinción especialmente importante es que el precio mostrado en la página de producto no siempre puede representar exactamente el total final.
En una página podemos conocer:
Product
Variation
Customer
Store
QuantityPero todavía podemos desconocer:
Shipping address
Billing address
Shipping method
Coupon
Complete order contentsPor tanto algunos cálculos solamente pueden determinarse correctamente cuando existe suficiente contexto dentro del Order.
Podemos pensar:
Product page
↓
Estimated / calculated price
Cart
↓
More context
Checkout
↓
Full commercial context
Order
↓
Final calculated totals25. Calculated Price
Commerce puede mostrar un precio calculado que tenga en cuenta el proceso de resolución y determinados Adjustments.
Conceptualmente:
Stored Price
↓
Price Resolution
↓
Applicable Adjustments
↓
Calculated PriceEsto resulta útil para mostrar al cliente un precio más cercano al que realmente pagará.
Sin embargo, debemos recordar que determinados datos solamente estarán disponibles cuando el comprador avance en el proceso de compra.
26. Order Processors
Hasta ahora hemos visto que un Order puede recibir:
- Promotions
- Taxes
- Fees
- Otros Adjustments
Commerce utiliza un proceso de actualización del Order para recalcular su información comercial.
Conceptualmente:
Order
↓
Refresh
↓
Order Processors
├── Pricing
├── Promotions
├── Taxes
└── Other business logic
↓
Updated OrderLos Order Processors permiten que diferentes componentes participen en la actualización del pedido sin concentrar toda la lógica en un único lugar.
27. Por qué Commerce recalcula el pedido
Supongamos que el cliente añade un producto al carrito:
Monday
Product
100 EURy regresa posteriormente cuando:
Tuesday
Product
90 EURO una promoción:
20 % weekend discountha expirado.
Commerce necesita decidir si la información del carrito todavía representa las condiciones comerciales actuales.
Por eso el Order puede pasar por procesos de refresh donde se vuelven a resolver precios y aplicar reglas.
Esta arquitectura es especialmente importante en tiendas con:
- Precios dinámicos
- Promociones frecuentes
- Price Lists
- Pricing B2B
- Integraciones ERP
28. El precio histórico del pedido
Una vez que un pedido representa una transacción comercial real, necesitamos conservar correctamente cuánto pagó el cliente.
No podemos simplemente consultar siempre el precio actual del Product Variation.
Por ejemplo:
January
Variation Price
100 EUR
Order #1001
Unit Price
100 EURMeses después:
September
Variation Price
120 EUREl pedido histórico continúa representando:
Order #1001
Purchased price
100 EUREsta separación entre catálogo actual y transacción histórica es fundamental para reporting, facturación y atención al cliente.
29. Ejemplo completo de cálculo
Supongamos la siguiente compra:
Laptop
Unit Price
1000 EUR
Quantity
1
Mouse
Unit Price
50 EUR
Quantity
2Subtotal:
Laptop
1000 EUR
Mouse
2 × 50 EUR
100 EUR
──────────
Subtotal
1100 EURExiste una promoción:
10 % discount on Laptop
Adjustment
-100 EURNuevo subtotal efectivo:
1000 EURPosteriormente aplicamos impuestos, de forma simplificada para este ejemplo:
VAT
+190 EURY shipping:
Shipping
+10 EURPodemos obtener:
Products
1100 EUR
Promotion
-100 EUR
Tax
+190 EUR
Shipping
+10 EUR
────────────────
Order Total
1200 EURLa ventaja de utilizar Adjustments es que podemos identificar claramente cómo se formó el total.
30. Ejemplo B2B
Supongamos ahora que tenemos precios diferentes según el cliente.
SKU
TOOL-001
Retail Price
100 EUR
Distributor Price
75 EURUn distribuidor inicia sesión.
El proceso conceptual podría ser:
Product Variation
↓
Price Resolver
↓
Customer = Distributor
↓
Price List
↓
Resolved Price
75 EUR
↓
Order Item Unit Price
75 EURPosteriormente podría existir además una promoción:
Buy 10+
Additional 5 % discountEntonces:
Resolved Unit Price
75 EUR
Quantity
10
Subtotal
750 EUR
Promotion
-37.50 EUR
Taxes
...
Total
...Esta arquitectura separa correctamente:
Contractual / contextual price
↓
Price Resolver
Temporary commercial incentive
↓
Promotion Adjustment31. Ejemplo multimoneda
También podemos tener diferentes precios dependiendo de la Store o moneda.
Product Variation
SKU: PRODUCT-001
Germany
→ 100 EUR
Switzerland
→ 110 CHF
United States
→ 115 USDEl precio utilizado puede depender del contexto comercial.
Store
+
Currency
+
Purchasable Entity
↓
Price Resolution
↓
Resolved PriceEsto es diferente de simplemente convertir visualmente 100 EUR a otra moneda.
En muchos negocios cada mercado tiene su propia estrategia de precios.
32. Price Lists
Cuando el negocio necesita múltiples precios por producto podemos introducir el concepto de Price Lists.
Por ejemplo:
Retail Price List
SKU-001 → 100 EUR
SKU-002 → 200 EUR
Distributor Price List
SKU-001 → 80 EUR
SKU-002 → 160 EURTambién pueden existir precios relacionados con:
Store
Customer
Role
Date
QuantityEste tipo de modelo es especialmente habitual en B2B.
Commerce dispone de módulos contribuidos, como Commerce Pricelist, para implementar escenarios de este tipo.
33. Quantity Pricing
Otro requisito habitual es cambiar el precio dependiendo de la cantidad.
Por ejemplo:
1 - 9 units
10 EUR / unit
10 - 49 units
9 EUR / unit
50+ units
8 EUR / unitTenemos que decidir conceptualmente si esto representa:
Different unit price
↓
Price resolutiono:
Base price
+
Volume discount
↓
Promotion / AdjustmentAmbos modelos pueden producir un resultado parecido para el cliente, pero representan conceptos comerciales diferentes.
La elección debería reflejar cómo entiende el negocio sus precios.
34. Fees
No todos los Adjustments son descuentos o impuestos.
También podemos tener recargos.
Por ejemplo:
Handling Fee
+5 EUR
Small Order Fee
+10 EUR
Special Packaging
+8 EUREstos conceptos pueden representarse mediante Adjustments positivos.
De esta forma permanecen separados del precio del producto.
35. Shipping y pricing
Shipping también termina influyendo en el total de la compra.
Por ejemplo:
Products
100 EUR
Shipping
+8 EUR
Tax
+20 EUR
Total
128 EURSin embargo, Shipping merece su propio modelo.
El coste puede depender de:
- Dirección
- Zona
- Peso
- Dimensiones
- Transportista
- Método seleccionado
- Valor del pedido
Por eso estudiaremos Shipping separadamente más adelante.
36. El orden del cálculo importa
Cuando existen varias reglas comerciales necesitamos comprender sobre qué valor se calcula cada una.
Por ejemplo:
Base price
100 EUR
Promotion
-20 %
Tax
+19 %¿Calculamos el impuesto sobre:
100 EURo sobre:
80 EUR?La respuesta depende de las reglas fiscales y comerciales aplicables.
Lo mismo puede ocurrir con múltiples promociones.
Promotion A
-10 %
Promotion B
-10 EUREl orden y las condiciones pueden modificar el resultado.
Por eso debemos recopilar estas reglas claramente durante el Discovery.
37. Evitar lógica de precios en campos arbitrarios
Supongamos que añadimos a Product:
field_discount
field_special_price
field_wholesale_price
field_sale_price
field_vip_priceInicialmente puede parecer una solución sencilla.
Pero rápidamente podemos terminar con:
Regular Price
Sale Price
VIP Price
Distributor Price
German Price
Swiss Price
Summer Price
Quantity Price
...Antes de añadir un nuevo field debemos preguntarnos:
¿Estamos almacenando un dato del producto o intentando implementar una regla comercial?
Si estamos implementando reglas comerciales, probablemente debemos estudiar:
- Price Resolvers
- Price Lists
- Promotions
- Adjustments
en lugar de continuar añadiendo campos.
38. Separar los conceptos comerciales
Podemos utilizar esta matriz mental:
Precio normal de la Variation
↓
Price
Precio dependiendo del contexto
↓
Price Resolver
Precio de referencia visual
↓
List Price
Descuento comercial
↓
Promotion Adjustment
Impuesto
↓
Tax Adjustment
Recargo
↓
Fee Adjustment
Costo de entrega
↓
Shipping AdjustmentEsta separación hace que el sistema sea mucho más fácil de comprender y mantener.
39. Preguntas para el Discovery de pricing
Antes de configurar precios deberíamos poder responder:
Precio base
- ¿Cada Variation tiene un precio propio?
- ¿De dónde procede ese precio?
- ¿Drupal es Source of Truth?
- ¿El precio proviene del ERP?
Clientes
- ¿Existen precios diferentes por cliente?
- ¿Existen precios B2B?
- ¿Existen grupos de clientes?
Mercados
- ¿Existen precios diferentes por país?
- ¿Existen diferentes monedas?
- ¿Cada Store tiene sus propios precios?
Cantidades
- ¿Existen precios por volumen?
- ¿Son precios reales diferentes o descuentos?
Promociones
- ¿Qué promociones existen?
- ¿A qué productos se aplican?
- ¿Se aplican automáticamente?
- ¿Necesitan Coupon?
- ¿Pueden combinarse?
Impuestos
- ¿Qué Tax Types necesitamos?
- ¿Qué tasas existen?
- ¿Los precios incluyen impuestos?
- ¿Existen clientes exentos?
Recargos
- ¿Existen fees adicionales?
- ¿Cuándo se aplican?
40. Un modelo mental completo
Podemos visualizar el pricing de Commerce de esta forma:
PRODUCT VARIATION
│
▼
Stored Price
│
▼
Price Resolver
│
▼
Resolved Price
│
▼
ORDER ITEM
│
├── Quantity
│
├── Promotion Adjustments
│
└── Tax Adjustments
│
▼
Adjusted Item Total
│
▼
ORDER
│
├── Order Promotions
├── Taxes
├── Shipping
├── Fees
└── Other Adjustments
│
▼
ORDER TOTALNo todos los proyectos utilizarán todas estas capas.
Una tienda sencilla puede necesitar solamente:
Variation Price
↓
Order Item
↓
Order TotalMientras que un proyecto B2B internacional podría necesitar:
Variation
↓
Store
↓
Customer group
↓
Price List
↓
Quantity tier
↓
Resolved Price
↓
Promotion
↓
Tax
↓
Shipping
↓
Final TotalLa arquitectura debe ser tan sencilla como permita el negocio, pero suficientemente flexible para representar sus reglas reales.
41. Una regla práctica para tomar decisiones
Podemos utilizar cuatro preguntas fundamentales:
1. ¿Cuál es el precio de esta Variation?
↓
Price
2. ¿Cuál es el precio correcto
para este contexto?
↓
Price Resolver
3. ¿Qué descuentos o recargos
se aplican a esta compra?
↓
Adjustments
4. ¿Cuánto termina pagando
el cliente?
↓
Order TotalEstas preguntas ayudan a separar conceptos que inicialmente pueden parecer iguales.
Conclusión
El sistema de precios de Drupal Commerce no se limita a almacenar un número dentro de una Product Variation.
Commerce separa diferentes responsabilidades:
Price
= precio de la entidad comprable
List Price
= precio de referencia visual
Price Resolver
= determina el precio apropiado
para un contexto
Order Item Unit Price
= precio utilizado en la línea
concreta del pedido
Adjustment
= modificación económica
Promotion
= descuento comercial
Tax
= obligación fiscal
Order Total
= resultado final de la transacciónEsta separación permite construir desde tiendas muy sencillas hasta sistemas complejos con múltiples Stores, monedas, grupos de clientes, Price Lists, promociones e impuestos.
La idea principal es evitar pensar:
¿Qué campo necesito para guardar este nuevo precio?
y comenzar preguntando:
¿Este dato representa un precio, una regla de pricing o un Adjustment sobre la transacción?
Responder correctamente esa pregunta puede evitar gran parte de la complejidad futura de un proyecto Commerce.
En el siguiente artículo profundizaremos en otro elemento fundamental del proceso comercial: Orders, Order Items y Workflows, entendiendo el ciclo de vida de un carrito desde que se crea hasta que el pedido es completado, cancelado o reembolsado.