Cupom de desconto no carrinho

Permita que seus clientes apliquem um cupom de desconto pelo carrinho e substitua o resumo de totais pelo componente que já inclui o desconto do cupom.


São dois componentes que se integram juntos:

  • coupon-input: o campo para inserir o código, com os botões de aplicar e remover.
  • cart-totals: o resumo do carrinho (subtotal, promoções, desconto do cupom, custo de frete, total, desconto por meio de pagamento e parcelas).

Importante: a linha do desconto do cupom é renderizada pelo cart-totals. Se você integrar apenas o coupon-input, o cupom será aplicado, mas o cliente não verá o desconto refletido no resumo. Os dois componentes andam juntos.

HTML

1. Adicione o campo de cupom

O resumo do carrinho fica em snipplets/cart-totals.tpl e é usado tanto pela página do carrinho (templates/cart.tpl) quanto pelo carrinho de compras rápidas (snipplets/cart-panel.tpl).

Verifique a partir de quais arquivos ele é incluído:

{# templates/cart.tpl #}
{% include "snipplets/cart-totals.tpl" with {'cart_page': true} %}

{# snipplets/cart-panel.tpl #}
{% include "snipplets/cart-totals.tpl" %}

Ao integrar os componentes nesse único arquivo, ambos os contextos ficam cobertos.

Dentro do contêiner do resumo, antes dos totais, adicione o componente coupon-input:

{# Coupon input #}

{% if settings.cart_coupon %}
  <div class="js-visible-on-cart-filled" {% if cart.items_count == 0 %}style="display:none;"{% endif %}>
    {{ component('coupon-input', {
      svg_sprites: false,
      label_custom_icon: include('snipplets/svg/tag.tpl', {svg_custom_class: 'icon-inline icon-w-18 icon-lg svg-icon-text mr-2 align-text-bottom'}),
      toggle_inactive_custom_icon: include('snipplets/svg/chevron-down.tpl', {svg_custom_class: 'icon-inline svg-icon-text'}),
      toggle_active_custom_icon: include('snipplets/svg/chevron-up.tpl', {svg_custom_class: 'icon-inline svg-icon-text'}),
      container_classes: {
        container: 'mb-3',
        content: 'pt-2',
        toggle: 'd-flex align-items-center justify-content-between',
        toggle_label: 'd-flex align-items-center',
        applied_row: 'd-flex align-items-center justify-content-between mt-2',
        applied_code: cart_page ? 'mr-4' : 'mr-4 font-weight-bold',
        remove_button: 'btn btn-secondary btn-small float-right py-1 px-2 px-sm-3',
        form: 'form-group mb-0 mt-2',
        input_wrapper: 'd-flex form-group-inline align-items-center',
        input: 'form-control col-6 col-lg-7 pr-0',
        apply_button: 'btn btn-default btn-block',
        error: 'alert alert-danger mb-0 mt-2',
      }
    }) }}

    {# Divider between coupon input and subtotal #}
    <div class="divider"></div>
  </div>
{% endif %}

Considerações:

  • O {% if settings.cart_coupon %} é ativado no Administrador Nuvem, na seção de Personalizar seu layout atual dentro de Carrinho de compras.
  • O contêiner com js-visible-on-cart-filled faz com que o bloco seja ocultado quando o carrinho fica vazio. O divisor vai dentro do contêiner para que seja ocultado junto com o campo.
  • Os ícones são passados de acordo com o padrão do seu layout. Antes de criar um novo, verifique se ele já existe no seu layout (busque em snipplets/svg/): a etiqueta e as setas costumam estar disponíveis.
  • Se o seu layout tiver um arquivo por ícone (como o Base), passe svg_sprites: false e os ícones com include(...), como no exemplo.
  • Se o seu layout usar um sprite (um único arquivo com <symbol>), passe os IDs em vez dos includes:
label_svg_id: 'tag',
toggle_inactive_svg_id: 'chevron-down',
toggle_active_svg_id: 'chevron-up',
  • Se quiser mostrar um spinner nos botões enquanto o cupom é aplicado, passe spinner_svg_id ou spinner_custom_icon. Se não os passar, o spinner não será exibido e os botões apenas mudarão o texto para "Aplicando" / "Removendo".

2. Substituímos o resumo de totais

Substitua o HTML do subtotal, promoções, custo de frete, total e parcelas pelo componente cart-totals:

{# Cart totals: subtotal, promos, coupon discount, shipping cost, total, payment/installments #}

{% set discount_accent = 'text-accent font-weight-bold' %}
{% set free_shipping_accent = cart.free_shipping.cart_has_free_shipping ? discount_accent : 'opacity-40' %}
{% set summary_weight = cart_page ? 'font-weight-normal' %}

{{ component('cart-totals', {
  shipping_enabled: show_cart_fulfillment,
  payment_discount_price_enabled: settings.payment_discount_price,
  installments_enabled: not settings.payment_discount_price,
  totals_divider: true,
  container_classes: {
    subtotals: 'd-grid',
    totals: 'mb-3',
    totals_divider: 'divider',
  },
  text_classes: {
    subtotal: 'h5 justify-content-between d-flex my-1 ' ~ summary_weight,
    subtotals_prices: 'text-right',
    price_without_taxes: 'd-flex justify-content-between mb-2 font-small opacity-60',
    price_without_taxes_price: 'text-right',
    discounts_row: 'd-flex flex-wrap justify-content-between mb-1',
    discounts_price: discount_accent,
    shipping_costs: 'd-flex justify-content-between h5 ' ~ summary_weight,
    shipping_costs_price: free_shipping_accent,
    shipping_costs_calculating: 'opacity-40',
    shipping_costs_empty: 'opacity-40',
    total: 'd-flex justify-content-between h2 text-primary',
    total_price: 'text-right',
    payment_discount_and_installments: 'text-right mt-1',
    payment_discount_price: 'text-accent font-small font-weight-normal mt-1',
    installments: 'text-accent font-small font-weight-normal',
  },
}) }}

Considerações: Não apague os elementos ocultos que o JS da plataforma usa para calcular os totais, pois o componente já os inclui:

<div class="js-subtotal-price subtotal-price hidden" data-priceraw="{{ cart.total }}"></div>
<div id="store-curr" class="hidden">{{ cart.currency }}</div>
<div class='total-price hidden'>{{ "Total" | translate }}: {{ cart.total | money }}</div>

shipping_enabled controla a linha do custo de frete. No Base, é passada a mesma condição que o calculador de frete do carrinho usa:

{% set show_cart_fulfillment = settings.shipping_calculator_cart_page and (store.has_shipping or store.branches) %}

3. Parâmetros disponíveis

Você pode ver todos os parâmetros e classes de ambos os componentes, com exemplos, em Componentes privados.


CSS

Requisito: Ter as classes helpers adicionadas ao seu layout. Você pode seguir este pequeno tutorial para fazer isso (basicamente, é copiar e colar algumas classes, não leva mais de 1 minuto).

1. Adicione o helper .d-grid

Adicionar display: grid para o contêiner de subtotais.

/* // Display */
.d-grid{display:grid!important}

2. Apague o CSS antigo das promoções

Os layouts antigos estilizavam as linhas de promoções com porcentagens e floats, pensados para um HTML que não é mais usado. No Base, era preciso apagar isso de static/css/style-async.scss.tpl:

.cart-promotion-detail{
  float: left;
  width: 65%;
  text-align: left;
}
.cart-promotion-number{
  position: absolute;
  right: 0;
  bottom: 0;
  width: 35%;
  float: right;
  text-align: right;
}
.total-promotions-row{
  float: right;
  width: 100%;
  margin-bottom: 10px;
  position: relative;
}
.cart-total{
  clear: both;
  margin: 10px 0;
  font-weight: bold;
}

Se você não apagar o width: 65%, a linha da promoção ficará estreita e o valor aparecerá no meio do contêiner, em vez de à direita.

3. Estilize a linha de promoções renderizada pelo JS

Quando o cliente altera as quantidades ou adiciona produtos, a plataforma desenha novamente as linhas de promoções via JavaScript, com classes fixas que não podem ser passadas por parâmetros. Para que essa versão fique igual à renderizada ao recarregar a página, adicione em static/css/style-async.scss.tpl:

.total-promotions-row{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  width: 100%;
  margin: 0 0 5px 0;
}
.cart-promotion-detail{
  text-align: left;
}
.cart-promotion-number{
  margin-left: auto;
  text-align: right;
  font-weight: bold;
}
.total-promotions-row .cart-promotion-number {
  color: $accent-color;
}

JS

O cupom não precisa de JavaScript próprio: ele é inicializado com o JS da plataforma. A única coisa a adicionar é a atualização do custo de frete, porque o cart-totals soma essa linha ao resumo. Sem isso, a linha fica sempre em "Calcule para ver".

⚠️ Se o seu layout tiver store.js.tpl e store-v2.js.tpl, faça a alteração apenas em store-v2.js.tpl.

1. Em store.js.tpl (ou onde você tiver suas funções de JS), adicione:

{% set shipping_calculator_enabled = settings.shipping_calculator_cart_page %}

{% if shipping_calculator_enabled %}

    var $selectedShipping = jQueryNuvem('.js-selected-shipping-method');
    if ($selectedShipping.length) {
        LS.ShippingDiscountRow.apply($selectedShipping[0], { containerSelector: '#cart-shipping-container' });
        jQueryNuvem("#shipping-cost").removeClass('opacity-40');
    }

{% endif %}

2. Dentro da função que gerencia a seleção de frete, adicione:

selectShippingOption = function(elem, save_option) {
    jQueryNuvem(".js-shipping-method, .js-branch-method").removeClass('js-selected-shipping-method');
    jQueryNuvem(elem).addClass('js-selected-shipping-method');

    {% if shipping_calculator_enabled %}

        LS.ShippingDiscountRow.apply(elem, { containerSelector: '#cart-shipping-container' });
        jQueryNuvem("#shipping-cost").removeClass('opacity-40');

    {% endif %}

    if (save_option) {
        LS.saveCalculatedShipping(true);
    }
    ...
};

Traduções

A única coisa que precisa de tradução é o texto da nova opção do painel. Adicione em config/translations.txt:

es "Cupones de descuento"
pt "Cupons de desconto"
en "Discount coupons"
es_mx "Cupones de descuento"

es "Permitir que tus clientes apliquen un cupón de descuento en el carrito"
pt "Permitir que seus clientes apliquem um cupom de desconto no carrinho"
en "Allow your customers to apply a discount coupon in the cart"
es_mx "Permitir que tus clientes apliquen un cupón de descuento en el carrito"

es "<a target='_blank' href='https://ayuda.tiendanube.com/es_AR/123465-cupones-y-promociones/que-son-los-cupones-de-descuento' class='js-checkbox-help-link'>Más sobre cupones de descuento</a>"
pt "<a target='_blank' href='https://atendimento.nuvemshop.com.br/cupons/como-criar-cupons-de-desconto' class='js-checkbox-help-link'>Mais sobre cupons de desconto</a>"
en "<a target='_blank' href='https://ayuda.tiendanube.com/es_AR/123465-cupones-y-promociones/que-son-los-cupones-de-descuento' class='js-checkbox-help-link'>More about discount coupons</a>"
es_mx "<a target='_blank' href='https://ayuda.tiendanube.com/es_AR/123465-cupones-y-promociones/que-son-los-cupones-de-descuento' class='js-checkbox-help-link'>Más sobre cupones de descuento</a>"

Ativação

1. Adicione a opção ao painel de design

Em config/settings.txt, no final da seção Carrinho de compras, adicione o checkbox:

    title
        title = Cupons de desconto
    checkbox
        name = cart_coupon
        description = Permitir que seus clientes apliquem um cupom de desconto no carrinho
    subtitle
        subtitle = <a target='_blank' href='https://atendimento.nuvemshop.com.br/cupons/como-criar-cupons-de-desconto' class='js-checkbox-help-link'>Mais sobre cupons de desconto</a>

2. Ative a opção na loja

No painel de administração, vá para Minha Nuvemshop → Layout → Personalizar seu layout atual → Carrinho de compras e ative "Permitir que seus clientes apliquem um cupom de desconto no carrinho".