FOX - WooCommerce Currency Switcher Professional

Moneda no admitida por PayPal en WooCommerce: cómo seguir vendiendo

"La moneda no es compatible con PayPal en WooCommerce" se presenta de varias formas: el botón de PayPal desaparece cuando un visitante cambia a su moneda local, el pago falla con CURRENCY_NOT_SUPPORTED o con el error 10605, o PayPal Payments responde 422 UNPROCESSABLE_ENTITY. En todos los casos se pidió a PayPal que cobrara en una moneda que no acepta para tu cuenta. Un selector de moneda puede mostrar cualquier moneda, pero no puede cambiar lo que PayPal acepta, así que la solución es decidir qué moneda llega a PayPal. A continuación tienes las comprobaciones que conviene hacer primero, tres formas de seguir vendiendo y el error independiente CANNOT_MIX_CURRENCIES.

Por qué PayPal rechaza una moneda

PayPal trabaja con una lista fija de monedas, más corta que la lista que puedes añadir a WooCommerce. Algunas monedas de esa lista son solo nacionales: MYR, por ejemplo, solo la aceptan las cuentas de PayPal registradas en Malasia. Que una moneda funcione depende, por tanto, de la moneda y del país de la cuenta receptora. La lista está en códigos de moneda de PayPal, con notas en monedas aceptadas por PayPal.

Por parte de la tienda, un pedido de WooCommerce tiene una moneda, y a la pasarela se le pide cobrar el total del pedido en esa moneda. FOX decide qué moneda está activa cuando se crea el pedido. No convierte el importe de camino a PayPal y no tiene ningún ajuste para "mostrar MYR, cobrar USD" dentro de un mismo pedido; la regla general se explica en mostrar precios en moneda local y cobrar en la moneda base. Por eso, toda configuración que funciona hace que el propio proceso de finalizar compra se ejecute en una moneda que PayPal acepta.

Comprueba esto antes de cambiar nada

  • El código de moneda es un código ISO real. PayPal compara exactamente el código de tres letras: EUR, no EURO. Un código incorrecto en la fila de moneda de FOX oculta el botón de PayPal para esa moneda. Un código de moneda personalizado nunca puede ser cobrado por PayPal. Si PayPal falla incluso con USD o EUR, borra el campo del código en la fila de FOX, vuelve a escribirlo a mano y guarda: un código pegado puede llevar caracteres invisibles.
  • El error también ocurre con una moneda admitida. Entonces la causa no es la moneda. Prueba sin sesión iniciada y con la caché y la optimización de JavaScript desactivadas; las páginas servidas desde una caché y los scripts retrasados están detrás de muchos errores de "moneda", consulta el selector de moneda se queda cargando tras la optimización de JS.
  • Ningún filtro que "añada" la moneda a PayPal. El código que amplía woocommerce_paypal_supported_currencies solo hace que aparezca el botón. El pedido se sigue creando en esa moneda y PayPal la sigue rechazando en el paso del pago. Elimina ese código.
  • Solo un plugin establece la moneda. Un segundo módulo multimoneda (en un plugin de herramientas o de pagos) cambia la moneda en el momento del pago a espaldas de FOX. FOX muestra un aviso en las pantallas de ajustes de WooCommerce cuando WooPayments tiene activada su propia opción multimoneda. Quédate con uno solo.

Tres formas de seguir vendiendo cuando PayPal no puede aceptar una moneda

1. Ofrecer PayPal solo en las monedas que puede cobrar

No hace falta código. En la pestaña Avanzado (Advanced) de los ajustes de FOX activa Reglas de pagos (Payments rules) y guarda; aparece una pestaña Pagos (Payments). En la fila de tu pasarela de PayPal selecciona las monedas que PayPal no puede aceptar, con Comportamiento de pagos (Payments behavior) establecido en Está oculto (Is hidden) (o selecciona las que sí puede aceptar con Se muestra (Is shown)). FOX aplica la regla en la página de finalizar compra y en la página de pago de un pedido existente. Los visitantes siguen viendo su moneda local en todas partes y pagan con otra pasarela, o cambian ellos mismos a una moneda de PayPal. Más sobre las reglas en cómo ocultar una pasarela de pago según la moneda.

2. Cambiar a una moneda de PayPal en la página de finalizar compra

Los visitantes navegan en su propia moneda y, cuando abren la página de finalizar compra, FOX cambia las monedas que PayPal no puede aceptar a una que sí puede. El pedido se crea en esa moneda, así que PayPal lo acepta. Esto requiere Es múltiple permitido (Is multiple allowed) = Sí (Yes) en la pestaña Avanzado (Advanced), y Pago por reglas de GeoIP (Checkout by GeoIP rules) desactivado, porque esa opción establece la moneda de finalizar compra según el país y anularía el cambio. Además, cada moneda de destino debe estar en tu lista de monedas de FOX; set_currency() recurre a la moneda base cuando recibe un código que la tienda no tiene.

/*
 * FOX + PayPal: on the checkout page, switch currencies PayPal cannot
 * charge to one it can. Child theme functions.php or a code snippets plugin.
 */
function myshop_paypal_currency_map() {
    return array(
        // currency PayPal cannot charge => currency to charge instead
        'AED' => 'USD',
        'MAD' => 'EUR',
    );
}

function myshop_switch_to_paypal_currency() {
    global $WOOCS;
    if ( ! is_object( $WOOCS ) ) {
        return false;
    }
    $map = myshop_paypal_currency_map();
    if ( ! isset( $map[ $WOOCS->current_currency ] ) ) {
        return false;
    }
    $WOOCS->set_currency( $map[ $WOOCS->current_currency ] );
    return true;
}

// Checkout page load; the payment page of an existing order keeps its currency
add_action( 'template_redirect', function () {
    if ( ! function_exists( 'is_checkout' ) || ! is_checkout()
        || is_checkout_pay_page() || is_order_received_page() ) {
        return;
    }
    if ( myshop_switch_to_paypal_currency() && WC()->cart ) {
        WC()->cart->calculate_totals();
    }
}, 1 );

// Checkout refreshes after address or shipping changes, after FOX's own handler
add_action( 'woocommerce_checkout_update_order_review', 'myshop_switch_to_paypal_currency', 10000 );

Conoce los efectos secundarios antes de usarlo. El cambio se aplica a todas las pasarelas de la página de finalizar compra, no solo a PayPal. El cliente ve cómo los totales cambian de moneda al abrirse la página de finalizar compra, así que indícalo en una línea de texto en esa página. Y el visitante se queda en la nueva moneda después de salir de la página de finalizar compra; el snippet más largo del artículo sobre mostrar precios locales y cobrar en la moneda base, enlazado más arriba, restaura la moneda anterior si lo necesitas.

3. Cobrar todo en una moneda base compatible con PayPal

Si la moneda base de tu WooCommerce es una que PayPal acepta, establece Es múltiple permitido (Is multiple allowed) en No. Los visitantes ven precios convertidos, y la página de finalizar compra, el pedido y el pago van en la moneda base. Mostrar monto aproximado (Show approximate amount) en la pestaña Opciones (Options) añade el equivalente local, en la moneda del país del visitante según las reglas GeoIP, a los totales del carrito y de finalizar compra. Si la propia moneda base no está en la lista de PayPal, esta opción no puede funcionar: usa la opción 2 con Sí (Yes), o la opción 1.

Particularidades de PayPal Payments

  • Los botones conservan la moneda de la carga de la página. El script de PayPal se carga con la moneda activa cuando se construyó la página. Si la moneda cambia después en la misma página, por ejemplo por país al finalizar la compra, los botones siguen funcionando con la antigua y fallan con un error como "Expected currency from order api call to be USD, got EUR". Evita cambiar la moneda en la página de finalizar compra una vez cargada, o asegúrate de que la página se recargue.
  • Con Es múltiple permitido (Is multiple allowed) = No, FOX entrega al script de PayPal Payments la moneda base, de modo que los botones coinciden con una página de finalizar compra en moneda base.
  • Botones fuera de la página de finalizar compra. Los botones inteligentes de las páginas de producto, el carrito y el minicarrito crean el pedido de PayPal antes de que el cliente llegue a finalizar la compra. El cambio en la página de finalizar compra de la opción 2 no se aplica a ellos, así que siguen enviando la moneda no admitida, y con la opción 3 provocan el error de monedas mezcladas descrito más abajo. Con cualquiera de las dos opciones, muestra los botones de PayPal solo en la página de finalizar compra, en los ajustes de ubicación de botones de PayPal Payments.
  • Pay Later solo se ofrece para ciertos países y sus monedas. Con otras monedas, el propio script de PayPal informa de errores en la consola del navegador; desactiva los mensajes de Pay Later si la mayoría de tus clientes paga en otras monedas.
  • Los reembolsos desde la pantalla del pedido se hacen en la moneda del pedido, y FOX no interviene en esa solicitud. La excepción es una tienda con la extensión Professional de PDF Invoices & Packing Slips, Smart Coupons o Advanced Coupons activa; ahí add_filter( 'woocs_disable_backend_refund_calculation', '__return_true' ); mantiene a FOX al margen. FOX lee este filtro mientras se carga, antes que el tema, así que pon la línea en un plugin de uso obligatorio (un archivo PHP en wp-content/mu-plugins que empiece por <?php), no en functions.php.

CANNOT_MIX_CURRENCIES: los pedidos fallan tras un cambio de moneda

PayPal Payments informa 422 UNPROCESSABLE_ENTITY con CANNOT_MIX_CURRENCIES cuando un pago se construye con dos monedas: el pedido de PayPal se creó en una, y la tienda envía después importes o confirma el pago en otra. Suele aparecer solo para los clientes que cambiaron de moneda, y solo a veces. Hay tres causas.

Las páginas en caché llevan otra moneda

Una página con botones de PayPal carga el script de PayPal con la moneda de esa página. Si la página vino de una caché de página, esa es la moneda de quien se guardó primero, mientras que el carrito del visitante está en la suya. Excluye de todas las cachés la página de finalizar compra, el carrito y cualquier página de producto que muestre botones de PayPal, y mantén activo el tratamiento de caché de FOX para el resto de la tienda, como se describe en por qué un selector de moneda y una caché de página se enfrentan.

La solicitud de pago parece de un visitante nuevo

Los botones de PayPal se comunican con tu sitio mediante solicitudes en segundo plano. FOX encuentra la moneda del visitante en su almacenamiento: una cookie con Sesión PHP (PHP Session) y Sesión FOX (FOX Session), la dirección IP con Transitorio (Transient), o una clave del navegador con Transitorio (Transient) y la opción de caché activada. Una solicitud que llega sin esa identidad se trata como una primera visita, de modo que la moneda de bienvenida o las reglas GeoIP deciden su moneda, y el pedido de PayPal puede construirse en una moneda que el carrito no usa. Eso ocurre cuando:

  • la clave del navegador no se adjunta porque un optimizador retrasa front.js de FOX, que añade la clave a las solicitudes de los botones de PayPal (corrige las exclusiones según el artículo enlazado en las comprobaciones anteriores);
  • la dirección IP del visitante cambia entre la carga de la página y el pago, algo que hacen las redes móviles, mientras Almacenamiento de moneda (Currency storage) es Transitorio (Transient) sin la opción de caché. Sesión FOX (FOX Session) guarda en cambio la moneda en la propia cookie del visitante.

Es múltiple permitido (Is multiple allowed) = No con botones fuera de la página de finalizar compra

En este modo el script de PayPal recibe la moneda base, mientras que un botón de una página de producto o del carrito construye el pedido a partir de un carrito mostrado en la moneda del visitante. Muestra los botones solo en la página de finalizar compra, o cambia a Sí (Yes) y resuelve la moneda de pago con la opción 2.

Lista de verificación

  • Cada código de moneda de FOX es un código ISO válido, vuelto a escribir si hay dudas.
  • Tu cuenta de PayPal puede recibir cada moneda que llega a PayPal, incluidas las monedas nacionales.
  • Ningún código añade monedas mediante woocommerce_paypal_supported_currencies, y no hay un segundo módulo multimoneda activo.
  • Elegida una de las tres configuraciones: Reglas de pagos (Payments rules), una moneda forzada al finalizar la compra o una moneda base compatible.
  • Página de finalizar compra, carrito y páginas con botones de PayPal excluidos de la caché de página; scripts de FOX sin retrasar.

Si PayPal sigue rechazando una moneda que admite para tu cuenta, abre un tema en el foro de soporte de FOX con el error exacto de PayPal, tus ajustes de Es múltiple permitido (Is multiple allowed) y Almacenamiento de moneda (Currency storage) y el plugin de PayPal que usas, y lo revisaremos.