En esta guía, se proporciona la referencia técnica de la API y los esquemas de carga útil para controlar los códigos promocionales y los descuentos en la versión 2026-04-08 del Protocolo de Universal Commerce (UCP).
Antes de compilar tus extremos, asegúrate de haber revisado la descripción general de los códigos promocionales y los descuentos para conocer los conceptos generales, las invariantes matemáticas y las reglas de manejo de errores.
Discovery
Para recibir códigos de descuento de Google, debes anunciar la compatibilidad con descuentos en tu perfil. En la versión 2026-04-08, las plataformas verifican si se extiende la capacidad de finalización de compra antes de enviar los códigos de descuento.
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.discount": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout"],
"spec": "https://ucp.dev/2026-04-08/specification/discount",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/discount.json"
}
]
}
}
}
Impacto en las líneas de pedido y los totales
Los descuentos aplicados se reflejan en los campos principales de finalización de compra con dos tipos de totales distintos. Si un descuento tiene allocations que apunta a líneas de pedido, contribuye a items_discount. Los descuentos sin asignaciones o con asignaciones al envío o las tarifas contribuyen a discount.
| Tipo de descuento | Tipo de total | Dónde se refleja |
|---|---|---|
| Descuento de línea de pedido | items_discount |
line_items[].totals[type=items_discount] |
| Descuento a nivel del pedido | discount |
totals[type=discount] |
Requisito de versión:
Para la versión 2026-04-08, las entradas de descuento en totals[] y
line_items[].totals[] deben usar valores negativos para reflejar su
efecto de resta en el recibo. Los importes dentro de los arrays discounts.applied y allocations siempre siguen siendo números enteros positivos.
Ejemplos de API para promociones aplicadas automáticamente
En los siguientes ejemplos, se muestran los descuentos que se aplican automáticamente. Las cargas útiles de la solicitud
no contienen un discounts.codes array, pero las respuestas incluyen
"automatic": true y omiten el code campo.
Descuento aplicado automáticamente a nivel del artículo
Una oferta del 10% en todo el sitio que se aplica automáticamente a una línea de pedido específica.
Ejemplo de solicitud:
{
"line_items": [
{
"id": "li_1",
"item": { "title": "Sneakers", "price": 10000 },
"quantity": 1
}
]
}
Ejemplo de respuesta:
{
"line_items": [
{
"id": "li_1",
"item": { "title": "Sneakers", "price": 10000 },
"quantity": 1,
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "items_discount", "amount": -1000},
{"type": "total", "amount": 9000}
]
}
],
"discounts": {
"applied": [
{
"title": "10% Off Sitewide Sale",
"amount": 1000,
"automatic": true,
"method": "each",
"allocations": [
{"path": "$.line_items[0]", "amount": 1000}
]
}
]
},
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 10000},
{"type": "items_discount", "display_text": "Item Discounts", "amount": -1000},
{"type": "total", "display_text": "Total", "amount": 9000}
]
}
Descuento aplicado automáticamente a nivel del pedido
Una regla promocional (p.ej., "$10 de descuento en pedidos superiores a $50") que se aplica al pedido en su totalidad sin asignaciones específicas de líneas de pedido.
Ejemplo de solicitud:
{
"line_items": [ ... ]
}
Ejemplo de respuesta:
{
"line_items": [ ... ],
"discounts": {
"applied": [
{
"title": "$10 Off Orders Over $50",
"amount": 1000,
"automatic": true
}
]
},
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 6000},
{"type": "discount", "display_text": "Order Promo", "amount": -1000},
{"type": "total", "display_text": "Total", "amount": 5000}
]
}
Ejemplos de API para promociones aplicadas por el usuario
En los siguientes ejemplos, se muestran los descuentos que se activan cuando un usuario ingresa un código promocional. Las cargas útiles de la solicitud incluyen los códigos solicitados, y las respuestas los repiten mientras asignan los importes aplicados.
Descuento a nivel del pedido
Un descuento fijo aplicado al total del pedido. No se necesitan asignaciones; el
descuento se aplica al pedido en su totalidad y usa type: "discount".
Ejemplo de solicitud:
{
"line_items": [ ... ],
"discounts": {
"codes": ["SAVE10"]
}
}
Ejemplo de respuesta:
{
"line_items": [ ... ],
"discounts": {
"codes": ["SAVE10"],
"applied": [
{
"code": "SAVE10",
"title": "$10 Off Your Order",
"amount": 1000
}
]
},
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 5000},
{"type": "discount", "display_text": "Order Discount", "amount": -1000},
{"type": "total", "display_text": "Total", "amount": 4000}
]
}
Descuentos combinados (a nivel del artículo y del pedido)
En este ejemplo, se muestran ambos tipos de descuento: un descuento por artículo (20% de descuento) asignado a líneas de pedido y un descuento automático en el envío a nivel del pedido.
Ejemplo de solicitud:
{
"line_items": [ ... ],
"discounts": {
"codes": ["SUMMER20"]
}
}
Ejemplo de respuesta:
{
"line_items": [
{
"id": "li_1",
"item": { "title": "T-Shirt", "price": 2000 },
"quantity": 2,
"totals": [
{"type": "subtotal", "amount": 4000},
{"type": "items_discount", "amount": -800},
{"type": "total", "amount": 3200}
]
}
],
"discounts": {
"codes": ["SUMMER20"],
"applied": [
{
"code": "SUMMER20",
"title": "Summer Sale 20% Off",
"amount": 800,
"allocations": [
{"path": "$.line_items[0]", "amount": 800}
]
},
{
"title": "Free shipping on orders over $30",
"amount": 599,
"automatic": true
}
]
},
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 4000},
{"type": "items_discount", "display_text": "Item Discounts", "amount": -800},
{"type": "discount", "display_text": "Order Discounts", "amount": -599},
{"type": "fulfillment", "display_text": "Shipping", "amount": 0},
{"type": "total", "display_text": "Total", "amount": 2601}
]
}
Código de descuento rechazado
Cuando un código no es válido, se repite en codes, pero se omite en applied. El rechazo se comunica con una warning en el array messages[].
Ejemplo de solicitud:
{
"line_items": [ ... ],
"discounts": {
"codes": ["SAVE10", "EXPIRED50"]
}
}
Ejemplo de respuesta:
{
"line_items": [ ... ],
"discounts": {
"codes": ["SAVE10", "EXPIRED50"],
"applied": [
{
"code": "SAVE10",
"title": "$10 Off Your Order",
"amount": 1000
}
]
},
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 5000},
{"type": "discount", "display_text": "Order Discount", "amount": -1000},
{"type": "total", "display_text": "Total", "amount": 4000}
],
"messages": [
{
"type": "warning",
"code": "discount_code_expired",
"path": "$.discounts.codes[1]",
"content": "Code 'EXPIRED50' expired on December 1st"
}
]
}
Descuentos acumulados con asignaciones
Se aplican varios descuentos con desgloses de asignación completos.
Ejemplo de solicitud:
{
"line_items": [ ... ],
"discounts": {
"codes": ["SUMMER20", "EXTRA5"]
}
}
Ejemplo de respuesta:
{
"line_items": [
{
"id": "li_1",
"item": { "title": "T-Shirt", "price": 6000 },
"quantity": 1,
"totals": [
{"type": "subtotal", "amount": 6000},
{"type": "items_discount", "amount": -1500},
{"type": "total", "amount": 4500}
]
},
{
"id": "li_2",
"item": { "title": "Socks", "price": 4000 },
"quantity": 1,
"totals": [
{"type": "subtotal", "amount": 4000},
{"type": "items_discount", "amount": -1000},
{"type": "total", "amount": 3000}
]
}
],
"discounts": {
"codes": ["SUMMER20", "EXTRA5"],
"applied": [
{
"code": "SUMMER20",
"title": "Summer Sale 20% Off",
"amount": 2000,
"method": "each",
"priority": 1,
"allocations": [
{"path": "$.line_items[0]", "amount": 1200},
{"path": "$.line_items[1]", "amount": 800}
]
},
{
"code": "EXTRA5",
"title": "Extra $5 Off",
"amount": 500,
"method": "across",
"priority": 2,
"allocations": [
{"path": "$.line_items[0]", "amount": 300},
{"path": "$.line_items[1]", "amount": 200}
]
}
]
},
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 10000},
{"type": "items_discount", "display_text": "Item Discounts", "amount": -2500},
{"type": "total", "display_text": "Total", "amount": 7500}
]
}