Listar e simular promoções
Lista as promoções públicas ativas da loja e simula quais promoções e quanto desconto um conjunto de itens receberia.
Estas duas rotas públicas servem para mostrar as ofertas da loja, não para aplicá-las. Ambas dependem do módulo de promoções: com o módulo desligado, respondem 403 {"error":"module_disabled","module":"promotions"}. O desconto de verdade só existe no carrinho e no checkout.
Listar promoções públicas
/api/v1/storefront/promotionsPúblicaLista as promoções públicas ativas
Devolve as promoções que estão ativas agora e podem ser mostradas a qualquer visitante. Por segurança, não aparecem promoções que exigem um código de cupom ou que valem só para clientes ou grupos específicos. Dessas, o visitante nunca fica sabendo. Cada promoção sai só com campos de apresentação: não há condições, código, lista de clientes nem contagem de uso. Se a loja desligou cupons, promoções com código também são omitidas.
Parâmetros de consulta
pageintegerpadrão: 1per_pageintegerpadrão: 20Exemplo de requisição
curl "$BASE_URL/api/v1/storefront/promotions?page=1&per_page=20"Resposta
{
"page": 1,
"per_page": 20,
"total": 76,
"total_pages": 4,
"promotions": [
{
"id": "79077750-c988-4a47-9e57-5e7fd521d1ec",
"name": "10% no carrinho inteiro",
"description": "",
"type": "percentage",
"discount": 1000,
"valid_from": "2026-09-09T20:53:20.38412Z",
"valid_until": null,
"zone": "cart",
"priority": 0,
"stackable": false
},
{
"id": "1610f8c4-5e31-43dd-a2f3-d1e38a1d868e",
"name": "Frete Grátis – São Paulo",
"description": "",
"type": "free_shipping",
"discount": 0,
"valid_from": "2026-09-09T17:13:29.224227Z",
"valid_until": null,
"zone": "cart",
"priority": 0,
"stackable": true
}
]
}Campos da resposta
promotionsarraypromotions[].iduuidpromotions[].namestringpromotions[].descriptionstringpromotions[].typestringpercentagefixedfree_shippingbuy_x_get_ypromotions[].discountintegerpercentage (1000 = 10%), centavos quando fixed. 0 nos demais tipos.promotions[].max_discountintegerpromotions[].valid_fromstringnull se sem início.promotions[].valid_untilstringnull se sem fim.promotions[].zonestringcatalogcartpromotions[].priorityintegerpromotions[].stackablebooleantrue quando pode somar com outras promoções.totalintegerpageintegerper_pageintegertotal_pagesintegertotal.Erros
| Status | Quando | Corpo |
|---|---|---|
| 403 | Módulo de promoções desligado | {"error":"module_disabled","module":"promotions"} |
| 500 | Falha ao consultar | {"error":"failed to list active promotions","detail":"..."} |
Simular promoções
/api/v1/storefront/promotions/evaluateAutenticadaSimula quais promoções um conjunto de itens do carrinho receberia
Roda o motor de promoções com os dados que você manda e devolve as promoções que se aplicariam, o desconto total e se há frete grátis. A simulação não cria pedido, não baixa o uso de nenhuma promoção e não lê nem altera o carrinho do cliente. Se a requisição vier com login, os grupos de cliente dele entram na avaliação (promoções exclusivas de um grupo passam a valer); sem login, só valem as promoções abertas a todos.
Se a loja usa "cupom único" (use_single_coupon), só o primeiro cupom válido de coupon_codes conta.
Corpo da requisição
zonestringpadrão: cartcartcatalogcart_subtotalintegercart_totalintegertotal_weightintegeritemsarrayItens do carrinho.
product_iduuidobrigatóriocategory_idsarrayvendor_iduuidbrand_iduuidunit_priceintegerpriceintegerunit_price (também em centavos). Envie um dos dois.quantityintegerweightintegerfeaturesobjectchave: valor) para condições por característica.coupon_codesarrayshipping_countrystringBR).shipping_statestringSP).shipping_zipstringpayment_method_idstringshipping_method_iduuidExemplo de requisição
curl -X POST "$BASE_URL/api/v1/storefront/promotions/evaluate" \
-H "Content-Type: application/json" \
-d '{
"zone": "cart",
"cart_subtotal": 30000,
"cart_total": 30000,
"shipping_state": "SP",
"items": [
{
"product_id": "22fbd12a-1b6e-41ea-a84f-4d9cf06c8766",
"category_ids": ["8fcaf422-1631-4282-b503-85cc57380649"],
"vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
"unit_price": 30000,
"quantity": 1
}
]
}'Resposta
{
"applied_promotions": [
{
"id": "c19df8c2-279f-46c3-81e4-d1e52aec733c",
"name": "Progressiva 5% acima de R$ 100",
"discount_type": "percentage",
"discount": 1500,
"free_shipping": false
},
{
"id": "1610f8c4-5e31-43dd-a2f3-d1e38a1d868e",
"name": "Frete Grátis – São Paulo",
"discount_type": "multi",
"discount": 0,
"free_shipping": true,
"bonus_type": "multi"
}
],
"total_discount": 1500,
"free_shipping": true,
"item_discounts": {}
}Campos da resposta
applied_promotionsarrayapplied_promotions[].iduuidapplied_promotions[].namestringapplied_promotions[].codestringapplied_promotions[].discount_typestringpercentage, fixed, free_shipping, multi...).applied_promotions[].discountintegerapplied_promotions[].free_shippingbooleantrue se esta promoção zera o frete.applied_promotions[].bonus_typestringtotal_discountintegerfree_shippingbooleantrue se alguma promoção concede frete grátis.free_shipping_method_iduuiditem_discountsobjectproduct_id para centavos. Vazio quando o desconto não é por item.free_productsarray{product_id, quantity}. Ausente quando não há.budget_skippedarrayA resposta pode trazer também chaves de bônus que só são executados depois do pedido pago (give_coupons, give_cashback, give_usergroup_ids, assign_rep_ids). Elas descrevem o que o cliente ganharia depois da compra; nada é entregue pela simulação.
Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo que não é JSON | {"error":"invalid request body","detail":"invalid character 'x' looking for beginning of value"} |
| 403 | Módulo de promoções desligado | {"error":"module_disabled","module":"promotions"} |
| 500 | Falha ao avaliar | {"error":"failed to evaluate promotions","detail":"..."} |