Cálculo de envíos internacionales

En este tutorial vamos a ver cómo agregar la posibilidad de calcular envío para otros países sin necesidad de cambiar de moneda o idioma.

Vale la pena explicar que en las tiendas existen dos tipos de entidades por cada país configurado desde la pantalla de Configuraciones > Idiomas y Monedas. 

  • storefront_country: Es el país que define el idioma y la moneda. 
  • shipping_country: Es el país al cual se envía la compra (se puede elegir desde un desplegable en el paso 1 del checkout)

En todas las tiendas storefront_country es igual a shipping_country, por ende si el usuario cambia de idioma en una tienda, por ejemplo a Brasil, el país de envío también será Brasil.

En los siguientes pasos vamos a ver como hacer que el shipping_country sea independiente del storefront_country, por ende el usuario va a poder comprar mirando la tienda en su versión Argentina pero enviando a otro país sin necesidad de cambiar el storefront_country.

HTML

1. Lo primero que vamos a hacer es agregar el siguiente código para el texto que dice “Medios de envío para [País de envío]” en el snipplet shipping-calculator.tpl dentro de la carpeta snipplets/shipping. Debemos reemplazar el el texto que dice “Medios de envío”  por lo siguiente: 

{% if languages | length > 1 %}
    {{ ' para ' | translate }}
    {% for language in languages %}
        {% if (shipping_country_id and language.id == shipping_country_id) or (not shipping_country_id and language.active) %}
            <a href="#" data-toggle="#{% if product_detail %}product{% else %}cart{% endif %}-shipping-country" class="js-modal-open js-shipping-country-label btn-link btn-link-primary text-capitalize">
                {{ language.country_name }}
            </a>
        {% endif %}
    {% endfor %}
{% endif %}

Y luego al final de este archivo vamos a agregar el modal que permite el cambio de país:

{# Shipping country modal #}

{% if languages | length > 1 %}

    {% if product_detail %}
        {% set country_modal_id = 'product-shipping-country' %}
    {% else %}
        {% set country_modal_id = 'cart-shipping-country' %}
    {% endif %}

    {% embed "snipplets/modal.tpl" with{modal_id: country_modal_id, modal_class: 'bottom modal-centered-small js-modal-shipping-country', modal_position: 'center', modal_transition: 'slide', modal_header: true, modal_footer: true, modal_width: 'centered', modal_zindex_top: true, modal_mobile_full_screen: false} %}
        {% block modal_head %}
            {{ 'País de entrega' | translate }}
        {% endblock %}
        {% block modal_body %}
            {% embed "snipplets/forms/form-select.tpl" with{select_label: true, select_label_name: 'País donde entregaremos tu compra' | translate, select_aria_label: 'País donde entregaremos tu compra' | translate, select_custom_class: 'js-shipping-country-select', select_group_custom_class: 'mt-4' } %}
                {% block select_options %}
                    {% for language in languages %}
                        <option value="{{ language.id }}" data-country-url="{{ language.url }}" {% if (shipping_country_id and language.id == shipping_country_id) or (not shipping_country_id and language.active) %}selected{% endif %}>{{ language.country_name }}</option>
                    {% endfor %}
                {% endblock select_options%}
            {% endembed %}
        {% endblock %}
        {% block modal_foot %}
            <a href="#" class="js-save-shipping-country js-modal-close btn btn-primary float-right">{{ 'Aplicar' | translate }}</a>
        {% endblock %}
    {% endembed %}
{% endif %}

2. En caso que no tengamos un componente modal.tpl para los pop ups, vamos a necesitar crearlo dentro de la carpeta snipplets, usando el siguiente código:

{# /*============================================================================
  #Modal
==============================================================================*/
 
#Properties
    // ID
    // Position - Top, Right, Bottom, Left
    // Transition - Slide and Fade
    // Width - Full and Box
    // modal_form_action - For modals that has a form
 
 
#Head
    // Block - modal_head
#Body
    // Block - modal_body
#Footer
    // Block - modal_footer
 
#}
 
{% set modal_overlay = modal_overlay | default(true) %}
 
<div id="{{ modal_id }}" class="js-modal {% if modal_mobile_full_screen %}js-fullscreen-modal{% endif %} modal modal-{{ modal_class }} modal-{{modal_position}} transition-{{modal_transition}} modal-{{modal_width}} transition-soft" style="display: none;">
    {% if modal_form_action %}
    <form action="{{ modal_form_action }}" method="post" class="{{ modal_form_class }}" {% if modal_form_hook %}data-store="{{ modal_form_hook }}"{% endif %}>
    {% endif %}
    <div class="js-modal-close {% if modal_mobile_full_screen %}js-fullscreen-modal-close{% endif %} modal-header">
        <span class="modal-close">
            {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
        </span>
        {% block modal_head %}{% endblock %}
    </div>
    <div class="modal-body">
        {% block modal_body %}{% endblock %}
    </div>
    {% if modal_footer %}
        <div class="modal-footer d-md-block">
            {% block modal_foot %}{% endblock %}
        </div>
    {% endif %}
    {% if modal_form_action %}
    </form>
    {% endif %}
</div>

3. En caso de no tener un snipplet form-select.tpl para el componente select, vamos a tener que crearlo dentro de la carpeta snipplets/forms ya que lo usamos en shipping-calculator.tpl durante el paso 1. Este snipplet debe tener el siguiente código:

{# /*============================================================================
  #Form select
==============================================================================*/
 
#Properties
 
#Group
    //select_group_custom_class for custom CSS classes
#Label 
    // select_label_name for name
    // select_label_id for ID
    // select_for for label for
    // select_label_custom_class for custom CSS classes
#Select 
    // select_id for id
    // select_name for name
    // select_custom_class for custom CSS classes 
    // input_rows for textarea rows
    // select_options to insert select options
    // select_aria_label for aria-label attribute
 
#}
 
<div class="form-group {{ select_group_custom_class }}">
    {% if select_label %}
        <label {% if select_label_id%}id="{{ select_label_id }}"{% endif %} class="form-label {{ select_label_custom_class }}" {% if select_for %}for="{{ select_for }}"{% endif %}>{{ select_label_name }}</label>
    {% endif %}
    <select 
        {% if select_id %}id="{{ select_id }}"{% endif %}
        class="form-select {{ select_custom_class }} {% if select_inline %}form-control-inline{% endif %}"
        {% if select_data %}data-{{select_data}}="{{select_data_value}}"{% endif %}
        {% if select_name %}name="{{ select_name }}"{% endif %}
        {% if select_aria_label %}aria-label="{{ select_aria_label }}"{% endif %}>
        {% block select_options %}
        {% endblock select_options %}
    </select>
    <div class="form-select-icon">
        {% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "icon-inline icon-w-14 icon-lg svg-icon-text"} %}
    </div>
</div>

4. Por último para la parte de HTML, dentro de la carpeta snipplets/SVG vamos sumar los SVGs que usamos para el select, el icono de filtrado y el modal.

times.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>

chevron-left.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M231.293 473.899l19.799-19.799c4.686-4.686 4.686-12.284 0-16.971L70.393 256 251.092 74.87c4.686-4.686 4.686-12.284 0-16.971L231.293 38.1c-4.686-4.686-12.284-4.686-16.971 0L4.908 247.515c-4.686 4.686-4.686 12.284 0 16.971L214.322 473.9c4.687 4.686 12.285 4.686 16.971-.001z"/></svg>

chevron-down.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M441.9 167.3l-19.8-19.8c-4.7-4.7-12.3-4.7-17 0L224 328.2 42.9 147.5c-4.7-4.7-12.3-4.7-17 0L6.1 167.3c-4.7 4.7-4.7 12.3 0 17l209.4 209.4c4.7 4.7 12.3 4.7 17 0l209.4-209.4c4.7-4.7 4.7-12.3 0-17z"/></svg>


CSS

Requisito:

Tener agregados en tu diseño las clases helpers. Podés seguir este este pequeño tutorial para hacerlo (simplemente es copiar y pegar algunas clases, no toma más de 1 minuto).

1. Agregamos el siguiente SASS de colores en style-colors.scss.tpl (o la hoja de tu diseño que tenga los colores y tipografías de la tienda). Recordá que las variables de colores y tipografías pueden variar respecto a tu diseño:

{# /* // Mixins */ #}
{# This mixin adds browser prefixes to a CSS property #}
@mixin prefix($property, $value, $prefixes: ()) {
  @each $prefix in $prefixes {
      #{'-' + $prefix + '-' + $property}: $value;
  }
    #{$property}: $value;
}
 
{# /* // Links */ #}
 
a {
  color: $main-foreground;
  fill: $main-foreground;
  @include prefix(transition, all 0.4s ease, webkit ms moz o);
  &:hover,
  &:focus{
    color: rgba($main-foreground, .5);
    fill: rgba($main-foreground, .5);
  }
}
.btn-link{
  color: $primary-color;
  fill: $primary-color;
  text-transform: uppercase;
  border-bottom: 1px solid;
  font-weight: bold;
  cursor: pointer;
  &:hover,
  &:focus{
    color: rgba($primary-color, .5);
    fill: rgba($primary-color, .5);
  }
}
 
{# /* // Modals */ #}
 
.modal{
  color: $main-foreground;
  background-color:$main-background;
}
 
{# /* // Forms */ #}
 
input,
textarea {
  font-family: $body-font;
}
 
.form-control {
  display: block;
  padding: 8px;
  width: 100%;
  font-size: 16px; /* Hack to avoid autozoom on IOS */
  border: 0;
  border-bottom: 1px solid rgba($main-foreground, .5);
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  color: $main-foreground;
  background-color: $main-background;
  &:focus{
    outline: 0;
  }
  &-inline{
    display: inline;
  }
}
 
.form-control::-webkit-input-placeholder { 
  color: $main-foreground;
}
.form-control:-moz-placeholder {
  color: $main-foreground;
}
.form-control::-moz-placeholder {
  color: $main-foreground;
}
.form-control:-ms-input-placeholder {
  color: $main-foreground;
}
 
.form-select{
  display: block;
  padding: 10px 0;
  width: 100%;
  font-size: 16px; /* Hack to avoid autozoom on IOS */
  border: 0;
  border-bottom: 1px solid rgba($main-foreground, .5);
  border-radius: 0;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  color: $main-foreground;
  background-color: $main-background;
  @extend %body-font;
  &-icon{
    background: $main-background;
  }
}

2. Agregar los estilos dentro del archivo static/style-critical.tpl 

Si en tu diseño usas una hoja de estilos para el CSS crítico, vamos a necesitar agregar el siguiente código debajo dentro de la misma, pero si no es el caso podés unificar el CSS de los pasos 2 y 3 en un solo archivo.

{# /* // Forms */ #}
 
.form-group {
  position: relative;
  width: 100%;
}
.form-group .form-select-icon{
  position: absolute;
  bottom: 12px;
  right: 0;
  pointer-events: none;
}

3. Agregar los estilos dentro del archivo static/style-async.tpl 

Si en tu diseño usas una hoja de estilos para CSS asíncrono, vamos a necesitar agregar el siguiente código dentro de la misma, pero si no es el caso podés unificar el CSS de los pasos 2 y 3 en un solo archivo.

{# /* // Mixins */ #}
 
{# This mixin adds browser prefixes to a CSS property #}
 
@mixin prefix($property, $value, $prefixes: ()) {
  @each $prefix in $prefixes {
    #{'-' + $prefix + '-' + $property}: $value;
  }
  #{$property}: $value;
}
 
{# /* // Modals */ #}
 
.modal {
  position: fixed;
  top: 0;
  display: block;
  width: 80%;
  height: 100%;
  padding: 10px;
  -webkit-overflow-scrolling: touch;
  overflow-y: auto;
  transition: all .2s cubic-bezier(.16,.68,.43,.99);
  z-index: 20000;
  &-header{
    width: calc(100% + 20px);
    margin: -10px 0 10px -10px;
    padding: 10px 15px;
    font-size: 20px;
  }
  &-footer{
    padding: 10px 0;
    clear: both;
  }
  &-full {
    width: 100%;
  }
  &-docked-md{
    width: 100%;
  }
  &-docked-small{
    width: 80%;
  }
  &-top{
    top: -100%;
    left: 0;
  }
  &-bottom{
    top: 100%;
    left: 0;
  }
  &-left{
    left: -100%;
  }
  &-right{
    right: -100%;
  }
  &-centered{
    height: 100%;
    width: 100%;
    &-small{
      left: 50%;
      width: 80%;
      height: auto;
      @include prefix(transform, translate(-50%, -50%), webkit ms moz o);
      .modal-body{
        min-height: 150px;
        max-height: 400px;
        overflow: auto;
      }
    }
  }
  &-top.modal-show,
  &-bottom.modal-show {
    top: 0;
    &.modal-centered-small{
      top: 50%;
    }
  }
  &-bottom-sheet {
    top: initial;
    bottom: -100%;
    height: auto;
    &.modal-show {
      top: initial;
      bottom: 0;
      height: auto;
    }
  }
  &-left.modal-show {
    left: 0;
  }
  &-right.modal-show {
    right: 0;
  }
  &-close { 
    display: inline-block;
    padding: 1px 5px 5px 0;
    margin-right: 5px;
    vertical-align: middle;
    cursor: pointer;
  }
  .tab-group{
    margin:  0 -10px 20px -10px;
  }
}
 
.modal-overlay{
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #00000047;
  z-index: 10000;
  &.modal-zindex-top{
    z-index: 20000;
  }
}
 
 
{# /* // Forms */ #}
 
.form-group{
  @extend %element-margin;
  .form-label{
    float: left;
    width: 100%;
    margin-bottom: 10px;
  }
  .alert{
    margin: 10px 0 0 0;
  }
}
 
.form-select {
  display: block;
  width: 100%;
  &:focus{
    outline:0;
  }
  &::-ms-expand {
    display: none;
  }
}
 
{#/*============================================================================
  #Media queries
==============================================================================*/ #}
 
{# /* // Min width 768px */ #}
 
@media (min-width: 768px) { 
 
  {# /* //// Components */ #}
 
  {# /* Modals */ #}
 
 .modal{
    &-centered{
      height: 80%;
      width: 80%;
      left: 10%;
      margin: 5% auto;
      &-small{
        left: 50%;
        width: 30%;
        height: auto;
        max-height: 80%;
        margin: 0;
      }
    }
    &-docked-md{
      width: 500px;
      &-centered{
        left: calc(50% - 250px);
        bottom: auto;
        height: auto;
      }
    }
    &-bottom-sheet {
      top: 100%;
      &.modal-show {
        top: 0;
        bottom: auto;
      }
    }
    &-docked-small{
      width: 350px;
    }
  }

JS

1. El JavaScript necesitamos agregarlo en el archivo store.js.tpl (o donde tengas tus funciones de JS). El código que necesitamos es el siguiente:

{#/*============================================================================
  #Shipping calculator
==============================================================================*/ #}
    
{# /* // Change store country: From invalid zipcode message */ #}

$(document).on("click", ".js-save-shipping-country", function(e) {
    e.preventDefault();
    {# Change shipping country #}

    var $selected_country_select = $(this).closest(".js-modal").find(".js-shipping-country-select option:selected");
    var selected_country_val_placeholder = $selected_country_select.text();
    var selected_country_val = $selected_country_select.val();

    // Sync multiple selects on DOM
    $(".js-shipping-country-select ").val(selected_country_val);

    // Update selected country with front end until backend request is ready
    $(".js-shipping-country-label, .js-zipcode-error-country").text(selected_country_val_placeholder);

    // If has selected shipping options, reset results and totals
    $(".js-shipping-calculator-response").hide();
    LS.resetCalculatedShipping();

    {# Save shipping country id #}
    
    LS.saveShippingCountry("/shipping_country/", selected_country_val, function(data){


        {# Update selected wording #}
        $(".js-shipping-country-label, .js-zipcode-error-country").text(data.shipping_country.country_name);
    });
});

{#/*============================================================================
  #Modals
==============================================================================*/ #}
 
{# Full screen mobile modals back events #}
 
if ($(window).width() < 768) {
 
    {# Clean url hash function #}
 
    cleanURLHash = function(){
        const uri = window.location.toString();
        const clean_uri = uri.substring(0, uri.indexOf("#"));
        window.history.replaceState({}, document.title, clean_uri);
    };
 
    {# Go back 1 step on browser history #}
 
    goBackBrowser = function(){
        cleanURLHash();
        history.back();
    };
 
    {# Clean url hash on page load: All modals should be closed on load #}
 
    if(window.location.href.indexOf("modal-fullscreen") > -1) {
        cleanURLHash();
    }
 
    {# Open full screen modal and url hash #}
 
    $(document).on("click", ".js-fullscreen-modal-open", function(e) {
        e.preventDefault();
        var modal_url_hash = $(this).data("modal-url");            
        window.location.hash = modal_url_hash;
    });
 
    {# Close full screen modal: Remove url hash #}
 
    $(document).on("click", ".js-fullscreen-modal-close", function(e) {
        e.preventDefault();
        goBackBrowser();
    });
 
    {# Hide panels or modals on browser backbutton #}
 
    window.onhashchange = function() {
        if(window.location.href.indexOf("modal-fullscreen") <= -1) {
 
            {# Close opened modal #}
 
            if($(".js-fullscreen-modal").hasClass("modal-show")){
 
                var $opened_modal = $(".js-fullscreen-modal.modal-show");
                var $opened_modal_overlay = $opened_modal.prev();
 
                $opened_modal.removeClass("modal-show").delay(500).hide(0);
                $opened_modal_overlay.fadeOut(500);
 
                {% if settings.quick_shop %}
                    restoreQuickshopForm();
                {% endif %}
            }
        }
    }
 
}
 
$(document).on("click", ".js-modal-open", function(e) {
    e.preventDefault(); 
    var $modal_id = $(this).data('toggle');
    $(".js-modal-overlay").fadeToggle();
    if ($($modal_id).hasClass("modal-show")) {
        $($modal_id).removeClass("modal-show").delay(200).hide(0);
    } else {
        $($modal_id).detach().insertAfter(".js-modal-overlay").show(0).addClass("modal-show");
    }             
});
 
closeModal = function(element){
 
    $(element).closest(".js-modal").removeClass("modal-show").delay(200).hide(0); 
    $(".js-modal-overlay").fadeOut(300);
 
    {# Close full screen modal: Remove url hash #}
 
    if (($(window).width() < 768) && ($(element).hasClass(".js-fullscreen-modal-close"))) {
        goBackBrowser();
    }
 
    {% if settings.quick_shop %}
        restoreQuickshopForm();
    {% endif %}
    
};
 
$(document).on("click", ".js-modal-close", function(e) {
    e.preventDefault();  
    closeModal($(this));    
});
 
{# Close modal on ESC keyboard #}
 
$(document).keyup(function(e) {
    if (e.keyCode == 27) {
        closeModal($(".js-modal-close"));    
    }
});
 
$(".js-modal-overlay").click(function (e) {
    e.preventDefault();  
    $(".js-modal.modal-show").removeClass("modal-show").delay(200).hide(0);   
    $(this).fadeOut(300);  
 
    {% if settings.quick_shop %}
        restoreQuickshopForm();
    {% endif %}
 
    if ($(window).width() < 768) {
        cleanURLHash();
    }
});
 
{#/*============================================================================
  #Product grid
==============================================================================*/ #}
 
var $category_controls = $(".js-category-controls");
var mobile_nav_height = $(".js-head-main").outerHeight();
 
{% if template == 'category' %}
 
    {# /* // Fixed category controls */ #}
 
    if ($(window).width() < 768) {
        {% if settings.head_fix %}
            $(".js-category-controls").css("top" , mobile_nav_height);
        {% else %}
            $(".js-category-controls").css("top" , 0);
        {% endif %}
 
        {# Detect if category controls are sticky and add css #}
 
        var observer = new IntersectionObserver(function(entries) {
            if(entries[0].intersectionRatio === 0)
                document.querySelector(".js-category-controls").classList.add("is-sticky");
            else if(entries[0].intersectionRatio === 1)
                document.querySelector(".js-category-controls").classList.remove("is-sticky");
            }, { threshold: [0,1] 
        });
 
        observer.observe(document.querySelector(".js-category-controls-prev"));
    }
 
    {# /* // Filters */ #}
 
    $(document).on("click", ".js-apply-filter, .js-remove-filter", function(e) {
        e.preventDefault();
        var filter_name = $(this).data('filter-name');
        var filter_value = $(this).data('filter-value');
        if($(this).hasClass("js-apply-filter")){
            $(this).find("[type=checkbox]").prop("checked", true);
            LS.urlAddParam(
                filter_name, 
                filter_value, 
                true
            );
        }else{
            $(this).find("[type=checkbox]").prop("checked", false);
            LS.urlRemoveParam(
                filter_name, 
                filter_value
            );   
        }
        {# Toggle class to avoid adding double parameters in case of double click and show applying changes feedback #}
 
        if ($(this).hasClass("js-filter-checkbox")){
            if ($(window).width() < 768) {
                $(".js-filters-overlay").show();
                if($(this).hasClass("js-apply-filter")){
                    $(".js-applying-filter").show();
                }else{
                    $(".js-removing-filter").show();
                }
            }
            $(this).toggleClass("js-apply-filter js-remove-filter");
        }
    });
 
    $(document).on("click", ".js-remove-all-filters", function(e) {
        e.preventDefault();
        LS.urlRemoveAllParams();
    });
 
    {# /* //  Accordions */ #}
 
    $(document).on("click", ".js-accordion-toggle", function(e) {
        e.preventDefault();
        if($(this).hasClass("js-accordion-show-only")){
            $(this).hide();
        }else{
            $(this).find(".js-accordion-toggle-inactive").toggle();
            $(this).find(".js-accordion-toggle-active").toggle();
        }
        $(this).prev(".js-accordion-container").slideToggle();
    });
 
    {# /* // Sort by */ #}
 
    $('.js-sort-by').change(function () {
        var params = LS.urlParams;
        params['sort_by'] = $(this).val();
        var sort_params_array = [];
        for (var key in params) {
            if ($.inArray(key, ['results_only', 'page']) == -1) {
                sort_params_array.push(key + '=' + params[key]);
            }
        }
        var sort_params = sort_params_array.join('&');
        window.location = window.location.pathname + '?' + sort_params;
    });
 
{% endif %}

Traducciones

En este paso agregamos los textos para las traducciones en el archivo config/translations.txt

es "Aplicar"
pt "Aplicar"
en "Apply"
es_mx "Aplicar"

es "Aplicando..."
pt "Aplicando..."
en "Aplying..."
es_mx "Aplicando..."

es "No encontramos este código postal{1}"
pt "Não conseguimos encontrar esse CEP{1}"
en "We couldn&#39;t find this zipcode{1}"
es_mx "No encontramos este código postal{1}"

es " para "
pt " para "
en " for "
es_mx " para "

es ". ¿Está bien escrito?"
pt ". Está bem escrito?"
en ". Is it written right?"
es_mx ". ¿Está bien escrito?"

es ". Podés intentar con otro o"
pt ". Pode tentar outro ou"
en ". You can try another or"
es_mx ". Puedes intentar con otro o"

es "cambiar tu país de entrega"
pt "alterar o país de entrega"
en "change your shipping country"
es_mx "cambiar tu país de entrega"

es "País de entrega"
pt "Pais de entrega"
en "Shipping country"
es_mx "País de entrega"

es "País donde entregaremos tu compra"
pt "País onde entregaremos seu pedido"
en "Country where we will deliver your order"
es_mx "País donde entregaremos tu compra"

es "No encontramos este código postal. ¿Está bien escrito?"
pt "Não conseguimos encontrar esse CEP. Está bem escrito?"
en "We couldn&#39;t find this zipcode. Is it written right?"
es_mx "No encontramos este código postal. ¿Está bien escrito?"

es "No encontramos este código postal para "
pt "Não conseguimos encontrar esse CEP para"
en "We couldn&#39;t find this zipcode for"
es_mx "No encontramos este código postal para"

Activación

Por último recordá que para tener más de un idioma en tu tienda debes hacerlo desde la parte de “Configuraciones/Idiomas y monedas”.