WPCS - WordPress Currency Switcher Professional

GeoIP del selector de monedas de WordPress no funciona: causas y soluciones

Cuando las reglas GeoIP del selector de monedas de WordPress no funcionan, los síntomas varían: todos los visitantes reciben la misma moneda, los visitantes de un país siguen viendo la moneda de bienvenida o el shortcode de prueba muestra un país vacío. En la mayoría de los casos el plugin busca exactamente la dirección que se le entrega. La causa real es la dirección IP que el servidor pasa a PHP, una caché de página que sirve la página de un visitante a todos los demás, o una prueba que no era una primera visita. A continuación verás cómo funciona la detección, cómo averiguar en pocos minutos cuál de estas causas tienes y la solución para cada una.

Cómo elige GeoIP la moneda

En la pestaña Reglas GeoIP (GeoIP rules) de Ajustes → Currency Switcher, cada moneda tiene una lista de países. En la primera visita de un visitante, el plugin determina el país de su dirección IP y, si alguna moneda incluye ese país en su lista, cambia a esa moneda. Los países que no están en ninguna lista reciben la Moneda de bienvenida (Welcome currency) de la pestaña Opciones (Options). Después de esa primera visita, el plugin recuerda la moneda en el Almacenamiento de la moneda (Currency storage) y no vuelve a aplicar las reglas, de modo que una moneda que el visitante eligió a mano se mantiene. La configuración completa se describe en establecer la moneda según el país del visitante; esta página trata de cómo encontrar lo que la rompe.

Dos detalles explican la mayoría de los problemas siguientes:

  • Qué dirección se usa. El plugin lee primero la cabecera de solicitud X-Real-IP, después la primera dirección de X-Forwarded-For y por último REMOTE_ADDR, la dirección de la máquina conectada al servidor web.
  • Qué base de datos se usa. La opción Posición geográfica (Geo position) ofrece Open Geo IP, la base de datos incluida con el plugin (lib/GeoIP.dat), y GeoIP2 (MaxMind API key is required), la base de datos GeoLite2 de MaxMind descargada en tu sitio con una clave gratuita de MaxMind. Con Open Geo IP, cuando una solicitud lleva la cabecera CF-IPCountry de Cloudflare, el plugin toma el código de país de esa cabecera en lugar de hacer su propia consulta.

Diagnostica primero: una página de prueba y una primera visita real

Crea una página con estos dos shortcodes y excluye su URL de todas las cachés de página (plugin de caché, caché del servidor, Cloudflare):

[wpcs_check_country] [wpcs_price value=10]

[wpcs_check_country] imprime Your current country is: Germany, Code: DE. Hace una consulta nueva en cada visualización de página e ignora la moneda recordada, así que responde a una sola pregunta: ¿es correcto el país? El importe de [wpcs_price] muestra qué moneda está activa para ti. Sin la exclusión de la caché, la propia línea del país se guarda en caché y muestra el país de quien cargó la página primero.

Para comprobar también la moneda, cada prueba debe ser una primera visita, y lo que cuenta como visitante nuevo depende del Almacenamiento de la moneda (Currency storage):

Almacenamiento de la monedaEl visitante se recuerda porUna primera visita real para probar
transient (predeterminado)Dirección IP, durante un díaUna conexión distinta (VPN, datos móviles). Una ventana privada en la misma conexión no es nueva.
cookieLa cookie wpcs_guest_id, durante un díaUna ventana privada nueva. Activar una VPN en la misma ventana no es nuevo.
sessionLa cookie de sesión de PHPUna ventana privada nueva. Activar una VPN en la misma ventana no es nuevo.

Activar y desactivar una VPN en un navegador que ya ha visitado el sitio es la falsa alarma más común: la línea del país cambia, la moneda no, y ese es el comportamiento previsto. Un servicio web que cargue tu página desde varios países da el resultado más realista. Ahora compara lo que muestra la página de prueba con esta tabla:

Lo que muestra la página de pruebaCausa
El mismo país en cada prueba, a menudo el país de tu servidor o de la CDNEl servidor pasa una única IP para todos los visitantes
Estados Unidos en cada pruebaPHP ve la dirección de loopback de un proxy local
El país correcto, pero el precio sigue en la moneda de bienvenidaNo es una primera visita, una página en caché o no hay regla para ese país
Nombre y código vacíosNinguna dirección utilizable, o un visitante con IPv6 y Open Geo IP
DB is empty. Please download the database. con el código errorGeoIP2 está seleccionado pero su base de datos nunca se descargó
Europe o Asia/Pacific RegionLa base de datos incluida solo conoce la región de esa dirección

Todos obtienen el mismo país: corrige el reenvío de IP

Cuando una CDN, un proxy inverso, un balanceador de carga o un servidor de caché (Cloudflare, Nginx delante de Apache, Varnish, un proxy del hosting) está delante de WordPress, la conexión que ve PHP procede de esa máquina, no del visitante. A menos que se indique al servidor que restaure la dirección original, todos los visitantes reciben la dirección del proxy y, por tanto, su país. Una variante frecuente: Nginx está configurado para enviar X-Real-IP con su propio $remote_addr, que detrás de Cloudflare es la dirección del servidor de Cloudflare. El plugin lee esa cabecera primero, así que todos se detectan en el país del centro de datos de Cloudflare.

La solución está en el servidor. Con Nginx, el módulo real IP sustituye la dirección del proxy por la del visitante antes de que PHP la vea:

# nginx.conf, inside the http {} or server {} block.
# Add one set_real_ip_from line for every range listed at https://www.cloudflare.com/ips/
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 2400:cb00::/32;
real_ip_header CF-Connecting-IP;

En Apache, mod_remoteip hace lo mismo con RemoteIPHeader CF-Connecting-IP y una línea RemoteIPTrustedProxy para los rangos de Cloudflare. La guía de Cloudflare Restoring original visitor IPs incluye ambas configuraciones. Sin Cloudflare, la cabecera suele ser X-Forwarded-For, y la dirección de confianza es la de tu propio proxy. En un hosting gestionado no puedes editar estos archivos: pide al proveedor que ponga a disposición de PHP la IP real del visitante en REMOTE_ADDR o en X-Real-IP. Recarga la página de prueba desde dos redes distintas; debería mostrar dos países distintos.

Cloudflare: usa su cabecera de país

Si el sitio está detrás de Cloudflare, activa IP Geolocation en la sección Network del panel de Cloudflare (consulta Cloudflare IP Geolocation). Cloudflare añade entonces una cabecera CF-IPCountry a cada solicitud y, con Posición geográfica (Geo position) establecida en Open Geo IP, el plugin la usa automáticamente. En la página de prueba, el código procede entonces de Cloudflare mientras que el nombre del país sigue procediendo de la consulta de IP; si ambos discrepan, el código es lo que usan las reglas. Con GeoIP2 la cabecera no se lee, pero puedes pasarla a las reglas con el filtro wpcs_geo_position:

/*
 * WPCS: take the visitor country from Cloudflare's CF-IPCountry header.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter('wpcs_geo_position', function ($country) {
    if (!empty($_SERVER['HTTP_CF_IPCOUNTRY'])) {
        $cf = strtoupper(sanitize_text_field(wp_unslash($_SERVER['HTTP_CF_IPCOUNTRY'])));
        // two-letter country codes only; XX means unknown
        if (preg_match('/^[A-Z]{2}$/', $cf) && $cf !== 'XX') {
            return $cf;
        }
    }
    return $country;
});

El filtro cambia el país usado para elegir la moneda. [wpcs_check_country] sigue imprimiendo la consulta propia del plugin, así que comprueba el resultado con el shortcode de precio y una primera visita.

Todos los visitantes se detectan en Estados Unidos

Cuando Nginx o Varnish se ejecutan en la misma máquina y pasan las solicitudes a Apache, PHP ve la propia dirección de loopback del servidor. El plugin trata esa dirección como una copia de desarrollo que se ejecuta en un ordenador y la sustituye por una dirección pública de prueba fija ubicada en Estados Unidos, sin leer ninguna cabecera. Apache debe restaurar la dirección del visitante con mod_remoteip:

# Apache 2.4 configuration, mod_remoteip enabled.
# Use the header your front proxy sends (X-Real-IP or X-Forwarded-For).
RemoteIPHeader X-Real-IP
RemoteIPInternalProxy 127.0.0.0/8

Efecto secundario: una única moneda recordada para todos

El almacenamiento transient predeterminado organiza su memoria por dirección IP. Mientras todos los visitantes llegan con una sola dirección, comparten una sola memoria: el primer visitante del día decide la moneda de todos, y un visitante que cambia de moneda la cambia también para los demás. Corregir el reenvío lo soluciona. Establecer Almacenamiento de la moneda (Currency storage) en cookie también ayuda, porque recuerda cada navegador por separado, sea cual sea su IP.

El país es correcto, pero la moneda no cambia

  • No es una primera visita. Prueba de nuevo siguiendo la tabla de almacenamiento anterior.
  • Una página en caché. Una caché de página sirve HTML almacenado, y el paso de GeoIP nunca se ejecuta para el siguiente visitante. En la pestaña Opciones (Options), establece Uso un plugin de caché en mi sitio (I am using cache plugin on my site) en Sí (Yes). Los precios impresos por [wpcs_price] se vuelven a dibujar entonces tras cargar la página mediante una solicitud AJAX (wpcs_get_prices_html) que se ejecuta para el visitante actual, reglas GeoIP incluidas, y el selector se ajusta a la moneda devuelta. Vacía todas las capas de caché tras cambiar la opción; si los precios siguen sin actualizarse, consulta el selector de monedas no funciona con un plugin de caché.
  • No hay regla para ese país. Las reglas contienen solo países; no existe una entrada Europe, así que añade cada país a su moneda. Un país incluido en dos monedas va a la primera.
  • Precios fijos. [wpcs_price type="fixed" value="USD:15,GBP:45"] muestra none para una moneda que falta en value. Las comillas tipográficas (”) pegadas desde un procesador de textos también rompen los atributos; escribe comillas rectas.
  • Importes incorrectos tras el cambio. La moneda base de la pestaña Monedas (Currencies) debe tener el tipo de cambio 1; las conversiones se calculan a partir de ella.

País vacío o incorrecto para algunos visitantes

  • Vacío para algunos visitantes. La consulta de Open Geo IP solo gestiona direcciones IPv4. Los visitantes que llegan al servidor por IPv6, habitual en las redes móviles, no obtienen país. GeoIP2 gestiona ambas. Vacío para todos significa que la dirección que recibe PHP falta o pertenece a una red privada (un contenedor o un balanceador de carga): corrige el reenvío como se explicó antes.
  • Europe o Asia/Pacific Region. Ninguna regla de país puede coincidir con estos valores. Cambia a GeoIP2.
  • País incorrecto. Los rangos de direcciones cambian de manos, y las actualizaciones del plugin traen una copia más reciente de la base de datos incluida, así que actualiza primero el plugin. Para mayor precisión, selecciona GeoIP2 (MaxMind API key is required) en Posición geográfica (Geo position), pega una clave gratuita de tu cuenta de MaxMind GeoLite2 en Clave de licencia de MaxMind (MaxMind license key) y haz clic en Guardar cambios (Save options). El botón Actualizar/descargar base de datos (Update/Download DB) aparece solo después de guardar la clave; haz clic en él y espera a Database downloaded successfully. El archivo se guarda como wp-content/uploads/currency-switcher/GeoLite2-Country.mmdb y no se actualiza automáticamente, así que vuelve a hacer clic en el botón cada pocos meses.
  • GeoIP2 peor que Open Geo IP. Falta el archivo de la base de datos o está desactualizado. Vuelve a descargarlo, o regresa a Open Geo IP.
  • Pruebas con VPN. El servidor de salida de una VPN puede estar registrado en un país distinto del que muestra la aplicación de la VPN. Compara con una segunda fuente de prueba antes de cambiar ajustes.

Si el servidor no puede pasar la dirección del visitante y el sitio no está detrás de Cloudflare, GeoIP no puede funcionar. En ese caso, elimina las reglas, establece la Moneda de bienvenida (Welcome currency) en la moneda que usa la mayoría de tus visitantes y deja que elijan con el selector [wpcs].

Lista de comprobación

  • La página de prueba está excluida de todas las cachés y muestra países distintos y correctos desde dos redes.
  • El servidor pasa la IP real del visitante, o IP Geolocation de Cloudflare está activada con Open Geo IP.
  • Con GeoIP2: la clave está guardada y la base de datos se descargó.
  • Cada prueba fue una primera visita real para el Almacenamiento de la moneda (Currency storage) seleccionado.
  • Uso un plugin de caché en mi sitio (I am using cache plugin on my site) está en Sí (Yes) en un sitio con caché, y se vaciaron todas las cachés.
  • Cada país figura bajo su moneda, y el tipo de cambio de la moneda base es 1.

Si todo esto se cumple y los visitantes siguen recibiendo la moneda equivocada, abre un tema en el foro de soporte de WPCS con el enlace a tu página de prueba, tus ajustes de Posición geográfica (Geo position) y Almacenamiento de la moneda (Currency storage), y la caché o CDN que usas.