Moneda de pago en WooCommerce según el país del cliente, no la IP
Que la moneda de pago de WooCommerce dependa del país del cliente significa una sola cosa: un cliente que introduce una dirección de facturación suiza paga en francos suizos, sea cual sea la moneda en la que navegó y desde donde venga su conexión a internet. FOX no hace esto por sí solo a partir de la dirección. Tiene una opción integrada que usa el país de la dirección IP del visitante, y el caso de la dirección se resuelve con un fragmento corto que reutiliza tus reglas de GeoIP. Esta guía explica ambos, la trampa de la facturación frente al envío que está detrás de la mayoría de los fragmentos que fallan, y los límites que conviene conocer antes de confiar en ello.
País de la IP o país de la dirección
Intervienen dos países distintos, y a menudo difieren en el caso de viajeros, usuarios de VPN, personas cerca de una frontera y cualquiera que pida un regalo para alguien en el extranjero.
| País | De dónde procede | Qué hace FOX con él |
|---|---|---|
| País de la IP | Geolocalización de WooCommerce, en la primera visita a una página | Las reglas de GeoIP eligen la primera moneda; la opción Pago por reglas de GeoIP (Checkout by GeoIP rules) puede imponerla al finalizar la compra |
| País de facturación | escrito o elegido por el cliente al finalizar la compra, guardado en su cuenta | nada por defecto; el fragmento de abajo lo usa |
| País de envío | solo cuando el cliente marca ¿Enviar a una dirección diferente? (Ship to a different address?) | nada por defecto; opcional en el fragmento |
Cómo se detecta y se asigna el país de la IP se explica en cambiar la moneda automáticamente según el país. Este artículo trata del momento del pago.
Antes de empezar
- Es múltiple permitido (Is multiple allowed) = Sí (Yes) en la pestaña Avanzado (Advanced) de WooCommerce → Ajustes → moneda (Currency). Con No, FOX restablece finalizar compra a la moneda base, y ninguna lógica por país puede cambiarlo. Las ventajas e inconvenientes de ambos ajustes se explican en mostrar precios en moneda local y cobrar en la moneda base.
- Países asignados en la pestaña GeoIP. Los dos métodos de abajo leen las mismas listas: Suiza en la lista de CHF, los países de la zona euro en la lista de EUR, y así sucesivamente. Mantener un único mapa significa que la primera visita y finalizar compra siempre coinciden.
- Pasarelas de pago que acepten cada moneda. Usa la pestaña Pagos (Payments) para ofrecer cada pasarela solo en las monedas en las que puede cobrar; consulta cómo ocultar una pasarela de pago según la moneda.
La opción integrada: Pago por reglas de GeoIP
Pago por reglas de GeoIP (Checkout by GeoIP rules) está en la pestaña Avanzado (Advanced). Aparece solo cuando Es múltiple permitido (Is multiple allowed) es Sí (Yes) y Reglas de precios fijos individuales para cada producto (Individual fixed prices rules for each product) está activada, porque está pensada para tiendas que fijan su propio precio por moneda: sin ella, un cliente podría elegir la moneda en la que tu precio fijo le resulte más barato.
Cuando está activada, FOX cambia las páginas de finalizar compra y de pago del pedido, y cada actualización del resumen del pedido, a la moneda que la pestaña GeoIP asigna al país de la IP del visitante. Los visitantes de países sin regla conservan la moneda que seleccionaron. Tras cada comprobación, FOX lanza la acción woocs_force_pay_bygeoip_rules con el país, la moneda de GeoIP (vacía para los países que no están en la lista) y la moneda actual, que es el lugar para tu propio comportamiento alternativo.
La opción no sabe nada de la dirección. Un residente suizo que pide desde un hotel en Italia paga en euros. Si eso es un problema para tu tienda, usa el fragmento en su lugar y desactiva esta opción.
Moneda de pago según el país de facturación del cliente
En el finalizar compra clásico, WooCommerce actualiza el resumen del pedido por AJAX cada vez que el cliente cambia el país, la provincia o el código postal, y lanza la acción woocommerce_checkout_update_order_review antes de recalcular los totales. Cambiar la moneda en ese punto hace que los totales, el envío y los métodos de pago aparezcan de inmediato en la nueva moneda.
/*
* FOX: the checkout currency follows the country the customer enters.
* Country-to-currency map: the lists in the FOX GeoIP tab.
* Needs "Is multiple allowed" = Yes. Classic (shortcode) checkout only.
* Child theme functions.php or a code snippets plugin.
*/
add_action('woocommerce_checkout_update_order_review', function ($post_data) {
global $WOOCS;
if (empty($WOOCS)) {
return;
}
parse_str((string) $post_data, $data);
// true: use the shipping country when "Ship to a different address?" is ticked
$use_delivery_country = false;
$country = isset($data['billing_country']) ? wc_clean($data['billing_country']) : '';
if ($use_delivery_country && !empty($data['ship_to_different_address']) && !empty($data['shipping_country'])) {
$country = wc_clean($data['shipping_country']);
}
$currency = $WOOCS->get_currency_by_country($country);
// Optional: countries without a GeoIP rule pay in the base currency
// if (!$currency) { $currency = $WOOCS->default_currency; }
if ($currency && $currency !== $WOOCS->current_currency) {
$WOOCS->set_currency($currency);
}
}, 10000);
$WOOCS->get_currency_by_country() devuelve la moneda cuya lista de GeoIP contiene el país, o una cadena vacía. $WOOCS->set_currency() guarda la moneda para el visitante, de modo que el pedido se crea en ella cuando el cliente lo realiza. La prioridad 10000 ejecuta el código después del propio manejador de FOX en la misma acción. Tal como está escrito, los clientes de países que no figuran en la lista conservan la moneda en la que navegaron; descomenta la línea alternativa para que paguen en la moneda base. Si prefieres mantener la lista de países en el código en lugar de en la pestaña GeoIP, cambiar la moneda según la dirección de facturación en lugar de la geolocalización tiene versiones con un mapa escrito en el código.
Por qué billing_country y no shipping_country
Los fragmentos más antiguos de nuestras FAQ sobre cambiar la moneda según el país de entrega leen shipping_country, y la queja más común sobre ellos es "la moneda está congelada". El motivo está en lo que envía WooCommerce. Con cada actualización envía el formulario de finalizar compra completo, incluidos los campos de envío que permanecen ocultos mientras ¿Enviar a una dirección diferente? (Ship to a different address?) no está marcada. El país de envío oculto contiene lo que estuviera rellenado de antemano, normalmente el país geolocalizado o guardado, y no cambia cuando el cliente edita la dirección de facturación. Así que la moneda sigue a un campo que el cliente nunca ve.
El país de facturación siempre es visible y siempre está actualizado. La casilla marcada llega como ship_to_different_address, y solo entonces el país de envío es la elección real del cliente, que es justo lo que comprueba $use_delivery_country = true. Si WooCommerce → Ajustes → Envío está configurado para forzar el envío a la dirección de facturación, no hay campos de envío en absoluto y el país de facturación es el único que importa.
¿Qué país debe decidir? El país de facturación coincide con la tarjeta o la cuenta que paga, que los proveedores de pago comprueban para el control del fraude. El país de entrega coincide con la aduana, los aranceles y los precios locales. Elige una regla e indícala en la página de finalizar compra.
Restringir monedas por país
El fragmento ya aplica la regla donde importa: sea cual sea la moneda en la que navegó un cliente, un país con una regla de GeoIP paga en su propia moneda. Para ocultar además monedas del selector a los visitantes de un país de IP determinado, de modo que los visitantes españoles nunca vean USD, consulta cómo no permitir una moneda en un país. Ese filtro trabaja con el país de la IP, así que complementa la regla de finalizar compra en lugar de reemplazarla.
Límites que conviene conocer
- Solo el finalizar compra clásico. El fragmento funciona con el finalizar compra del shortcode
[woocommerce_checkout]. El bloque Checkout actualiza la dirección a través de la Store API de WooCommerce y nunca lanzawoocommerce_checkout_update_order_review. Si tu página de finalizar compra muestra el bloque Checkout, sustitúyelo por el finalizar compra con shortcode para esta lógica. - Los botones de pago exprés como Apple Pay o Google Pay toman la dirección del monedero y se saltan el formulario de finalizar compra, así que la moneda se queda como estaba activa cuando se pulsó el botón.
- La página del carrito tiene una calculadora de envío que no ejecuta este hook; la moneda cambia cuando el cliente llega a finalizar compra.
- No lo combines con Pago por reglas de GeoIP (Checkout by GeoIP rules). Esa opción cambia la página de finalizar compra a la moneda de la IP al cargarse, el fragmento cambia el resumen del pedido a la moneda de la dirección un instante después, y la página muestra brevemente dos monedas. Usa una sola regla.
- Las páginas del carrito y de finalizar compra deben excluirse de toda caché de página.
Clientes con sesión iniciada: el país de facturación guardado en cada página
El fragmento de finalizar compra actúa solo en la página de finalizar compra. Para una tienda solo para miembros, o cuando un cliente registrado debe ver su propia moneda desde la primera página, lee el país de facturación guardado en cada visita a una página:
/*
* FOX: logged-in customers always see the currency of their billing country.
* Guests are not affected. Child theme functions.php or a code snippets plugin.
*/
add_action('wp_head', function () {
global $WOOCS;
if (empty($WOOCS) || !is_user_logged_in() || !function_exists('WC') || !WC()->customer) {
return;
}
$currency = $WOOCS->get_currency_by_country(WC()->customer->get_billing_country());
if ($currency && $currency !== $WOOCS->current_currency) {
$WOOCS->set_currency($currency);
}
}, 1000);
Se ejecuta después de que FOX haya terminado su propio trabajo en la página (prioridad 999), así que también se impone a las reglas de GeoIP de la primera visita. Los clientes registrados de un país con una regla de GeoIP no pueden cambiar de moneda mientras esté activo; cuando cambian el país de facturación en su cuenta o al finalizar la compra, la página siguiente sigue al nuevo país.
Pruébalo
- Pon un producto en el carrito y abre finalizar compra en una ventana privada.
- Cambia el país de facturación por uno de cada lista de GeoIP y observa cómo los totales cambian de moneda tras cada actualización.
- Si usas la variante de entrega, marca ¿Enviar a una dirección diferente? (Ship to a different address?), elige otro país y desmárcala de nuevo: la moneda debe volver a la del país de facturación.
- Realiza un pedido de prueba con la pasarela en modo de prueba y comprueba la moneda del pedido en la pantalla del pedido y en el correo electrónico.
Si los totales no cambian, comprueba que la página de finalizar compra usa el shortcode, que Es múltiple permitido (Is multiple allowed) es Sí (Yes), que el país está en una lista de GeoIP y que ningún otro fragmento llama a $WOOCS->set_currency() en finalizar compra. Si sigue fallando con un tema por defecto y solo WooCommerce y FOX activos, abre un tema en el foro de soporte de FOX con el código que usas y un enlace a finalizar compra, y lo revisaremos.