FOX - Currency Switcher for WooCommerce

Cambiar moneda por dirección de facturación en lugar de geolocalización

Si estás experimentando problemas de geolocalización donde los clientes están siendo cobrados en la moneda incorrecta, esta guía te ayudará a cambiar a la detección de moneda basada en la dirección de facturación.

El Problema

Síntomas comunes (ejemplo):
  • Clientes canadienses siendo cobrados en USD en lugar de CAD (o viceversa)
  • Clientes cerca de fronteras obteniendo moneda incorrecta
  • 5-10% de tasa de fallo con geolocalización basada en IP
  • La moneda no coincide con la ubicación real del cliente
Escenario de ejemplo: Un cliente canadiense visita tu tienda. La geolocalización detecta su IP como EE.UU. (común cerca de fronteras o con VPN), por lo que ven precios en USD. Al finalizar la compra, seleccionan Canadá como país de facturación, pero aún así se les cobra en USD. Causa raíz: La geolocalización basada en IP nunca es 100% precisa, especialmente:
  • Cerca de fronteras (EE.UU./Canadá, países de la UE)
  • Usando servicios VPN o proxy
  • Redes corporativas con IPs centralizadas
  • Redes móviles enrutando a través de diferentes países

Entendiendo el Problema

Por qué falla la geolocalización

Causas comunes:
  1. Inexactitud de la base de datos MaxMind - La base de datos gratuita GeoLite2 tiene precisión limitada
  2. Proximidad de fronteras - Las IPs cerca de fronteras a menudo se identifican incorrectamente
  3. Uso de VPN/Proxy - La ubicación real del cliente oculta
  4. Conflictos de caché - Página en caché con moneda predeterminada
  5. Problemas de proxy del servidor - El proveedor de alojamiento envía la IP del servidor en lugar de la IP del visitante

Geolocalización vs. País de facturación

Método Precisión Control del usuario Fiabilidad
Geolocalización (IP) 85-95% Ninguno Inconsistente
Dirección de facturación 100% Completo Siempre preciso
Recomendación: Usar dirección de facturación para la detección de moneda - los clientes eligen explícitamente su país al finalizar la compra.

Pasos de diagnóstico (antes de solucionar)

Paso 1: Probar la geolocalización actual

Añade este shortcode a cualquier página:
[woocs_geo_hello]
Salida esperada:
Your country is: Canada (defined by WooCommerce GeoIP functionality)
Lo que esto te dice:
  • Si el país es correcto → WOOCS está bien, el problema es con la geolocalización de WooCommerce
  • Si el país es incorrecto → Necesitas arreglar la integración de MaxMind en WooCommerce
  • Si no hay salida → La geolocalización no funciona en absoluto

Paso 2: Verificar el estado de geolocalización de WooCommerce

  1. Ve a WooCommerce → Estado
  2. Desplázate a la sección "Información de depuración de geolocalización"
  3. Revisa si hay errores o advertencias

Paso 3: Verificar la licencia de MaxMind

  1. Ve a WooCommerce → Ajustes → Integración → Geolocalización MaxMind
  2. Verifica si la clave de licencia está presente y es válida
  3. Verifica la fecha de actualización de la base de datos (debería ser reciente)
Si falta la licencia:

Solución 1: Solucionar problemas de geolocalización (si quieres seguir usándola)

Solución n.º 1: Clave de licencia de MaxMind

Problema: WooCommerce 3.9+ requiere licencia de MaxMind Solución:
  1. Regístrate en https://www.maxmind.com/en/geolite2/signup
  2. Genera la clave de licencia
  3. Añádela en WooCommerce → Ajustes → Integración → Geolocalización MaxMind
  4. La base de datos se descarga automáticamente

Solución n.º 2: Conflictos de caché

Problema: Las páginas en caché muestran la moneda predeterminada antes de que se ejecute la geolocalización Solución: En WooCommerce:
  • Ve a WooCommerce → Ajustes → General
  • Establece "Ubicación predeterminada del cliente" en "Geolocalizar (con soporte de caché de página)"
Para WP Rocket:
  • Ve a Cache → Caché de usuario
  • Activa "Deshabilitar caché para usuarios conectados"
  • Considera excluir las páginas de tienda/finalizar compra de la caché
Para LiteSpeed Cache:
  • Excluye /shop/, /product/, /checkout/ de la caché
  • Activa ESI para contenido dinámico
Nota: WOOCS puede funcionar con caché redibujando los precios mediante AJAX después de cargar la página.

Solución n.º 3: Problemas de IP del servidor/proxy

Problema: El servidor envía su propia IP en lugar de la IP del visitante Alojamientos afectados: Bluehost, servidores con Varnish, Cloudflare Solución:
  • Pide al soporte de alojamiento que configure las cabeceras HTTP_X_REAL_IP o HTTP_X_FORWARDED_FOR
  • Para Cloudflare: Panel → Caché → Configuración → establece "TTL de caché del navegador" en "Respetar cabeceras existentes"

Solución n.º 4: Caché del navegador

Problema: La geolocalización solo funciona en la primera visita, luego recuerda la elección Solución de prueba:
  • Usa modo incógnito/privado para probar
  • Borra las cookies entre pruebas
  • Usa VPN o https://www.locabrowser.com para probar diferentes ubicaciones

Solución 2: Cambiar al método de dirección de facturación (Recomendado)

Esta solución cambia la moneda automáticamente cuando el cliente selecciona su país de facturación al finalizar la compra.

Implementación básica (todos los países)

Añade este código al functions.php de tu tema hijo o al plugin Code Snippets:
/**
 * Switch currency based on billing country selection
 * Works during checkout when customer selects billing address
 */
add_action('woocommerce_checkout_update_order_review', function ($post_data) {
    global $WOOCS;

    parse_str($post_data, $data);

    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);

        // Map billing country to currency
        $currency_map = array(
            'US' => 'USD',
            'CA' => 'CAD',
            'GB' => 'GBP',
            'AU' => 'AUD',
            'EU' => 'EUR', // For Euro zone countries
            'DE' => 'EUR',
            'FR' => 'EUR',
            'ES' => 'EUR',
            'IT' => 'EUR',
        );

        // Get currency for selected country
        if (isset($currency_map[$country])) {
            $new_currency = $currency_map[$country];

            // Switch currency if different from current
            if ($WOOCS->current_currency !== $new_currency) {
                $WOOCS->set_currency($new_currency);
            }
        }
    }
}, 10);
  Cómo funciona:
  • El cliente llega a la página de finalizar compra
  • Selecciona el país de facturación del desplegable
  • WooCommerce activa AJAX para recalcular el pedido
  • El código detecta la selección del país y cambia la moneda
  • Los totales del pedido se actualizan inmediatamente con la moneda correcta
Añadir más países: Simplemente añade líneas al array $currency_map:
'MX' => 'MXN', // Mexico
'JP' => 'JPY', // Japan
'BR' => 'BRL', // Brazil
 

Implementación específica para Canadá

Caso de uso: Solo Canadá usa CAD, todos los demás países usan USD
/**
 * Canada = CAD, all other countries = USD
 */
add_action('woocommerce_checkout_update_order_review', function ($post_data) {
    global $WOOCS;

    parse_str($post_data, $data);

    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);

        // Canada = CAD, everything else = USD
        $new_currency = ($country === 'CA') ? 'CAD' : 'USD';

        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
  Resultado:
  • País de facturación = Canadá → CAD
  • País de facturación = Estados Unidos → USD
  • País de facturación = Reino Unido → USD
  • País de facturación = Alemania → USD
  • Cualquier otro país → USD

Implementación para la zona euro

Caso de uso: Varios países de la zona euro
/**
 * Euro zone countries = EUR, others = USD
 */
add_action('woocommerce_checkout_update_order_review', function($post_data) {
    global $WOOCS;
    
    parse_str($post_data, $data);
    
    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);
        
        // Define Euro zone countries
        $euro_countries = ['AT', 'BE', 'CY', 'EE', 'FI', 'FR', 'DE', 'GR', 
                          'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PT', 
                          'SK', 'SI', 'ES'];
        
        // Determine currency
        if (in_array($country, $euro_countries)) {
            $new_currency = 'EUR';
        } else {
            $new_currency = 'USD';
        }
        
        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
 

Con registro de depuración (para solucionar problemas)

Si necesitas depurar problemas de cambio de moneda, usa esta versión con registro:
/**
 * Billing address currency switching with debug logging
 */
add_action('woocommerce_checkout_update_order_review', function($post_data) {
    global $WOOCS;
    
    parse_str($post_data, $data);
    
    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);
        
        // Canada = CAD, all others = USD
        $new_currency = ($country === 'CA') ? 'CAD' : 'USD';
        
        // Debug logging
        error_log('WOOCS billing country received: ' . $country . ' → currency: ' . $new_currency);
        error_log('WOOCS current currency: ' . $WOOCS->current_currency . ' → switching to: ' . $new_currency);
        
        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
  Para ver los registros:
  1. Activa el registro de depuración de WordPress en wp-config.php:
    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
    define('WP_DEBUG_DISPLAY', false);
  2. Los registros se guardan en /wp-content/debug.log
  3. Descárgalos mediante FTP para revisarlos
Elimina el registro tras la depuración: Simplemente borra las dos líneas error_log() del código.

Solución 3: Deshabilitar completamente la geolocalización

Si la geolocalización causa demasiados problemas, deshabilítala por completo y confía solo en la selección manual de moneda + dirección de facturación.

Paso 1: Deshabilitar la geolocalización de WooCommerce

  1. Ve a WooCommerce → Ajustes → General
  2. Busca "Ubicación predeterminada del cliente"
  3. Selecciona "Dirección base de la tienda" o "Sin ubicación por defecto"
Qué hace esto:
  • ✅ El selector de moneda sigue funcionando - los clientes pueden cambiar manualmente
  • ✅ Todas las monedas permanecen activas
  • ✅ El código de dirección de facturación (Solución 2) sigue funcionando
  • ❌ No hay detección automática de moneda en la primera visita

Paso 2: Eliminar las reglas GeoIP de WOOCS

  1. Ve a Ajustes de WOOCS → pestaña GeoIP
  2. Elimina todas las reglas de geolocalización
  3. Guarda los ajustes

Paso 3: Establecer la moneda predeterminada

  1. En Ajustes de WOOCS → Opciones
  2. Establece la moneda de tu mercado principal como predeterminada
  3. Ejemplo: si el mercado principal es EE.UU., establece USD como predeterminado
Resultado:
  • Todos los visitantes ven la moneda predeterminada al llegar
  • Los clientes pueden cambiar manualmente usando el selector de moneda
  • Al finalizar la compra, la moneda cambia automáticamente según el país de facturación (si añadiste el código de la Solución 2)

Dónde añadir el código

Opción 1: functions.php del tema hijo (Recomendado)

  1. Ve a Apariencia → Editor de temas
  2. Selecciona Tema hijo (¡importante!)
  3. Abre functions.php
  4. Añade el código al final del archivo
  5. Haz clic en Actualizar archivo
Por qué un tema hijo:
  • Las actualizaciones del tema padre no borrarán tu código
  • Más seguro y mantenible

Opción 2: Plugin Code Snippets (Más fácil)

  1. Instala el plugin Code Snippets: https://wordpress.org/plugins/code-snippets/
  2. Ve a Snippets → Añadir nuevo
  3. Pega el código
  4. Establece en "Ejecutar en todas partes"
  5. Activa el snippet
Ventajas:
  • No requiere editar archivos del tema
  • Fácil de activar/desactivar
  • Sobrevive a cambios de tema
  • Más seguro para no desarrolladores
Importante para Code Snippets: Code Snippets se carga mediante el hook plugins_loaded, lo cual debería funcionar bien para el AJAX de finalizar compra. Sin embargo, si por alguna razón el código no se activa (muy raro), usa functions.php para una fiabilidad del 100%.

Solución de problemas

La moneda sigue siendo incorrecta después de seleccionar el país de facturación

Problema: El cliente selecciona Canadá, pero aún ve USD Posibles causas:
  1. La geolocalización anula la dirección de facturación
    • Solución: Deshabilita la geolocalización por completo (Solución 3)
    • La geolocalización se ejecuta primero y puede "fijar" la moneda incorrecta
  2. El código no se está ejecutando
    • Verifica si el código está en la ubicación correcta
    • Comprueba que no haya errores PHP (revisa el registro de errores)
    • Prueba cambiando de Code Snippets a functions.php
  3. Método de almacenamiento de moneda
    • Ve a WOOCS → Opciones → Almacenamiento de moneda
    • Prueba cambiando al modo de almacenamiento "transient"
    • Esto puede ayudar a evitar conflictos con la caché
  4. Interferencia de la caché
    • Limpia todas las cachés (WordPress, servidor, navegador)
    • Excluye la página de finalizar compra de la caché
    • Prueba en modo incógnito

Conflictos de geolocalización con dirección de facturación

Problema: Incluso con el código de dirección de facturación, la geolocalización lo anula Diagnóstico:
// Add debug code
error_log('Geo detected: ' . $WOOCS->current_currency);
error_log('Billing country: ' . $country);
  Solución: Si los registros muestran que la moneda de geolocalización aparece DESPUÉS del cambio de país de facturación, necesitas:
  1. Deshabilitar la geolocalización por completo
  2. O aumentar la prioridad del hook de dirección de facturación:
    add_action('woocommerce_checkout_update_order_review', function($post_data) {
        // ... your code ...
    }, 999); // Higher priority = runs later

El código causa pantalla blanca / errores

Problema: Añadir el código rompe el sitio Causas:
  • Error de sintaxis PHP (falta un corchete, punto y coma)
  • Archivo incorrecto editado (editó el tema padre en lugar del hijo)
  • Conflicto de plugins
Solución:
  1. Accede al sitio mediante FTP
  2. Renombra functions.php a functions.php.backup
  3. El sitio se recupera
  4. Revisa el código en busca de errores de sintaxis
  5. Prueba añadiendo el código en secciones más pequeñas

Mapa de Moneda No Funciona

Problema: Algunos países muestran moneda incorrecta Verificar:
  1. El código de país es correcto (código ISO de 2 letras)
  2. El código de moneda existe en WOOCS
  3. Sensibilidad a mayúsculas: Usa 'CA' no 'ca'
Encontrar códigos de país:
  • WooCommerce utiliza códigos ISO 3166-1 alfa-2
  • Lista completa: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2

La Dirección de Facturación Muestra "United States (US)" Pero el Código Espera "US"

Problema: La cadena del país es "United States (US)" pero el código verifica "US" Solución: El código ya usa trim() pero WooCommerce envía solo "US", por lo que esto no debería ser un problema. Si lo es:
// Extract country code
$country = trim($data['billing_country']);
if (strlen($country) > 2) {
    $country = substr($country, -2); // Get last 2 characters
}
 

Mejores Prácticas

  1. Siempre usa un tema hijo - Evita la pérdida de código en las actualizaciones del tema
  2. Prueba a fondo - Usa varios países en las pruebas
  3. Monitorea los registros de errores - Verifica problemas después de la implementación
  4. Limpia todas las cachés - WordPress, servidor, navegador, CDN
  5. Documenta tu configuración - Anota qué solución implementaste
  6. Mantén WOOCS actualizado - La última versión tiene correcciones de errores
  7. Haz una copia de seguridad antes de los cambios - Siempre respalda functions.php antes de editar

Consideraciones de Rendimiento

Impacto de AJAX

Qué sucede al finalizar la compra:
  • El cliente cambia el país de facturación
  • WooCommerce activa una llamada AJAX
  • Tu código se ejecuta y cambia la moneda
  • Los totales del pedido se recalculan
  • La página se actualiza con la nueva moneda
Rendimiento: Impacto mínimo - la llamada AJAX ya ocurre, el código solo añade el cambio de moneda.

Geolocalización vs. Dirección de Facturación

Aspecto Geolocalización Dirección de Facturación
Carga del Servidor Mayor (consulta IP) Menor (sin consulta)
Precisión 85-95% 100%
Velocidad Más lenta (API externa) Instantánea
Amigable con Caché No
Recomendación: La dirección de facturación es más rápida y más amigable con la caché.

Ejemplos del Mundo Real

Ejemplo 1: Tienda EE.UU./Canadá (Más Común)

add_action('woocommerce_checkout_update_order_review', function($post_data) {
    global $WOOCS;
    parse_str($post_data, $data);
    
    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);
        $new_currency = ($country === 'CA') ? 'CAD' : 'USD';
        
        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
  Configuración:
  • Moneda predeterminada: USD
  • Geolocalización: Deshabilitada
  • Selector manual: Habilitado para elección del cliente

Ejemplo 2: Tienda Global con Múltiples Monedas

add_action('woocommerce_checkout_update_order_review', function($post_data) {
    global $WOOCS;
    parse_str($post_data, $data);
    
    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);
        
        $currency_map = [
            'US' => 'USD',
            'CA' => 'CAD',
            'GB' => 'GBP',
            'AU' => 'AUD',
            'NZ' => 'NZD',
            'JP' => 'JPY',
            'CN' => 'CNY',
            // Euro zone
            'DE' => 'EUR', 'FR' => 'EUR', 'ES' => 'EUR', 'IT' => 'EUR',
            'NL' => 'EUR', 'BE' => 'EUR', 'AT' => 'EUR', 'PT' => 'EUR',
        ];
        
        // Default to USD if country not mapped
        $new_currency = isset($currency_map[$country]) ? $currency_map[$country] : 'USD';
        
        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
 

Ejemplo 3: Agrupación Regional

add_action('woocommerce_checkout_update_order_review', function($post_data) {
    global $WOOCS;
    parse_str($post_data, $data);
    
    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);
        
        // Define regional currencies
        $euro_zone = ['AT', 'BE', 'CY', 'EE', 'FI', 'FR', 'DE', 'GR', 'IE', 
                      'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PT', 'SK', 'SI', 'ES'];
        $gbp_zone = ['GB', 'UK'];
        $aud_zone = ['AU', 'NZ'];
        
        // Determine currency
        if (in_array($country, $euro_zone)) {
            $new_currency = 'EUR';
        } elseif (in_array($country, $gbp_zone)) {
            $new_currency = 'GBP';
        } elseif (in_array($country, $aud_zone)) {
            $new_currency = 'AUD';
        } elseif ($country === 'CA') {
            $new_currency = 'CAD';
        } else {
            $new_currency = 'USD'; // Default
        }
        
        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
 

Resumen

El Problema: La geolocalización por IP tiene una precisión del 85-95%, lo que provoca cargos de moneda incorrectos Mejor Solución: Usa la dirección de facturación para una detección de moneda 100% precisa Implementación:
  1. Agrega el código de dirección de facturación a functions.php o Code Snippets
  2. Opcionalmente deshabilita la geolocalización por completo
  3. Mantén el selector manual de moneda habilitado para flexibilidad
Código Clave (ejemplo Canadá/EE.UU.):
add_action('woocommerce_checkout_update_order_review', function($post_data) {
    global $WOOCS;
    parse_str($post_data, $data);
    
    if (isset($data['billing_country']) AND !empty($data['billing_country'])) {
        $country = trim($data['billing_country']);
        $new_currency = ($country === 'CA') ? 'CAD' : 'USD';
        
        if ($WOOCS->current_currency !== $new_currency) {
            $WOOCS->set_currency($new_currency);
        }
    }
}, 10);
  Beneficios:
  • ✅ Detección de moneda 100% precisa
  • ✅ Sin llamadas a API de geolocalización
  • ✅ Mejor rendimiento
  • ✅ Amigable con la caché
  • ✅ El cliente controla su moneda
  • ✅ Sin problemas de proximidad fronteriza
  • ✅ Funciona con VPNs
Este enfoque elimina la incertidumbre de la geolocalización y da a los clientes control total sobre su moneda al finalizar la compra.
Fuente: https://pluginus.net/support/topic/geotagging-issues