FOX - WooCommerce Currency Switcher Professional

Afficher les prix en devise locale, facturer en devise de base dans WooCommerce

De nombreuses boutiques veulent afficher les prix en devise locale mais facturer en devise de base : les visiteurs naviguent en euros, en roupies ou en dollars, tandis que chaque paiement passe par un seul compte de passerelle dans une seule devise. WooCommerce sait le faire, avec une règle qui façonne toutes les configurations ci-dessous : la devise affichée sur la page de paiement est la devise dans laquelle le client est facturé. Ce guide présente les trois façons de l'organiser avec FOX, les effets secondaires de chacune, ainsi que le cas inverse, où les clients paient dans la devise qu'ils ont sélectionnée.

Une commande, une devise

Une commande WooCommerce n'enregistre qu'une seule devise. Quelle que soit la devise active au moment de la création de la commande, elle y est inscrite, et la passerelle de paiement reçoit le total sous la forme d'un nombre dans cette devise. FOX convertit les prix pour l'affichage et décide quelle devise est active au paiement ; il ne convertit pas le montant en route vers la banque. C'est pourquoi « afficher des USD, facturer discrètement des INR » ne peut pas fonctionner : la passerelle prendrait 30 USD pour 30 INR. Il faut au contraire que la page de paiement elle-même passe à la devise dans laquelle vous facturez, et le client voit le montant réel avant de payer, ce qui évite aussi les litiges sur une devise inattendue sur le relevé de carte.

Le basculement est contrôlé par Plusieurs devises autorisées (Is multiple allowed) dans l'onglet Avancé (Advanced) des réglages de FOX (WooCommerce → Réglages → Devise).

Afficher les prix en devise locale mais facturer en devise de base

Lorsque la devise dans laquelle vous facturez est la devise de base de WooCommerce, aucun code n'est nécessaire. Réglez Plusieurs devises autorisées (Is multiple allowed) sur Non (No) et enregistrez ; une installation neuve de FOX démarre sur Oui (Yes). Ensuite :

  • la boutique, les pages produit et le panier affichent la devise du visiteur, choisie par le sélecteur ou par vos règles GeoIP ;
  • sur la page de paiement, FOX remet la devise sur la devise de base, de sorte que les totaux, la commande et le paiement sont tous dans la devise de base ;
  • chaque commande est enregistrée dans la devise de base, ce qui garde les rapports et la comptabilité dans une seule devise.

Les clients méritent de le savoir avant d'arriver à l'étape du paiement. Deux options intégrées de l'onglet Options affichent le montant local à côté du montant réel : Afficher le montant approximatif (Show approximate amount) ajoute une valeur (Approx. ...) aux totaux du panier et de la page de paiement, et Afficher le prix approximatif (Show approx. price) fait de même sur les pages de la boutique et des produits. Les deux utilisent la devise du pays du visiteur définie dans l'onglet GeoIP, elles exigent donc des règles GeoIP, et toutes deux sont calculées à partir des taux de change, non des prix fixes. Le texte peut être modifié avec le filtre woocs_get_approximate_amount_text. Un simple avis sur la page du panier classique aide aussi :

/*
 * Cart notice when the shop is shown in a currency that is not charged.
 * Child theme functions.php or a code snippets plugin.
 */
add_action('woocommerce_before_cart', function () {
    global $WOOCS;
    if (!isset($WOOCS) || $WOOCS->current_currency === $WOOCS->default_currency) {
        return;
    }
    wc_print_notice(
        sprintf(
            'Prices in %s are shown for information. Your order will be charged in %s.',
            esc_html($WOOCS->current_currency),
            esc_html($WOOCS->default_currency)
        ),
        'notice'
    );
});

L'effet secondaire : la boutique reste dans la devise de base après le paiement

FOX mémorise la dernière devise de chaque visiteur, et la réinitialisation sur la page de paiement est un changement de devise comme un autre. Un visiteur qui ouvre la page de paiement puis retourne à la boutique voit la devise de base, et les règles GeoIP ne ramènent pas la devise locale, car elles ne s'appliquent que lors de la première visite. L'extrait de la section suivante mémorise la devise du visiteur avant le paiement et la rétablit ensuite. Avec Plusieurs devises autorisées (Is multiple allowed) = Non (No), utilisez-le avec votre devise de base dans les deux lignes de réglage : le paiement se comporte comme avant, et le visiteur retrouve sa devise en le quittant.

Imposer une devise de paiement qui n'est pas la devise de base

Lorsque la passerelle accepte une devise autre que la devise de base, ou seulement certaines de vos devises, réglez Plusieurs devises autorisées (Is multiple allowed) sur Oui (Yes) et imposez la devise de paiement par du code. Avec Non (No), la réinitialisation sur la devise de base l'emporterait sur le code. L'extrait ci-dessous n'impose la devise de paiement que pour les devises que la passerelle ne peut pas facturer, et rend au visiteur sa propre devise sur la page suivante hors paiement :

/*
 * Charge only in currencies the payment gateway accepts.
 * Requires FOX: Advanced tab, Is multiple allowed = Yes.
 * Child theme functions.php or a code snippets plugin.
 */
add_action('template_redirect', function () {
    if (!class_exists('WOOCS') || !function_exists('WC')) {
        return;
    }
    global $WOOCS;

    $accepted = array('USD', 'EUR'); // currencies the gateway can charge
    $fallback = 'USD';               // checkout currency for all other currencies

    // Custom checkout page: is_checkout() || is_page('your-checkout-slug')
    if (is_checkout()) {
        if (!in_array($WOOCS->current_currency, $accepted, true)) {
            $WOOCS->storage->set_val('woocs_before_checkout', $WOOCS->current_currency);
            $WOOCS->set_currency($fallback);
            if (WC()->cart) {
                WC()->cart->calculate_totals();
            }
        }
        return;
    }

    // Outside checkout: restore the currency the visitor had before
    $previous = $WOOCS->storage->get_val('woocs_before_checkout');
    if (!empty($previous)) {
        $WOOCS->storage->set_val('woocs_before_checkout', '');
        $WOOCS->set_currency($previous);
    }
}, 1);

Pour imposer une seule devise à tout le monde, ne listez que cette devise dans $accepted et utilisez-la comme $fallback. Points à vérifier :

  • Pages de paiement personnalisées. is_checkout() est vrai sur la page définie comme page de paiement dans WooCommerce → Réglages → Avancé et sur les pages qui contiennent le shortcode de paiement. Un paiement construit par un plugin d'entonnoir ou de paiement peut n'être ni l'un ni l'autre ; ajoutez la condition is_page() du commentaire.
  • Paiement selon les règles GeoIP (Checkout by GeoIP rules) doit être désactivé. Cette option de l'onglet Avancé (Advanced) fait passer le paiement à la devise du pays du visiteur et l'emporte sur la devise imposée.
  • Pages de la boutique en cache. Le rétablissement s'exécute lorsque WordPress construit une page ; derrière un cache de pages, il a donc lieu sur la première page qui n'est pas servie depuis le cache.

Les versions plus simples, en une ligne, de ce code dans notre FAQ imposer une devise sur la page de paiement imposent la devise sans la rétablir.

Changer de devise selon le moyen de paiement

FOX ne peut pas réagir de lui-même à un clic sur un moyen de paiement : sur le paiement classique, choisir un moyen ne recharge rien. Les deux extraits ci-dessous font actualiser à WooCommerce le récapitulatif de commande lorsque le moyen change, et changent la devise lors de cette actualisation. Ils fonctionnent avec le paiement par shortcode [woocommerce_checkout], pas avec le bloc Paiement (Checkout), et exigent Plusieurs devises autorisées (Is multiple allowed) = Oui (Yes). L'identifiant d'un moyen de paiement est la valeur de son bouton radio sur la page de paiement, par exemple bacs pour le virement bancaire direct.

/*
 * Classic checkout: change currency when a payment method is chosen.
 * Child theme functions.php.
 */
add_action('woocommerce_checkout_update_order_review', function ($post_data) {
    if (!class_exists('WOOCS')) {
        return;
    }
    global $WOOCS;
    parse_str($post_data, $data);

    $currency_by_method = array(
        'bacs'   => 'EUR', // payment method ID => currency it charges in
        'stripe' => 'USD',
    );

    $method = isset($data['payment_method']) ? $data['payment_method'] : '';
    if (isset($currency_by_method[$method]) && $WOOCS->current_currency !== $currency_by_method[$method]) {
        if (!$WOOCS->storage->get_val('woocs_before_checkout')) {
            $WOOCS->storage->set_val('woocs_before_checkout', $WOOCS->current_currency);
        }
        $WOOCS->set_currency($currency_by_method[$method]);
    }
});

add_action('wp_footer', function () {
    if (!is_checkout()) {
        return;
    }
    ?>
    <script>
    jQuery(function ($) {
        $(document.body).on('payment_method_selected', function () {
            $(document.body).trigger('update_checkout');
        });
    });
    </script>
    <?php
});

L'inverse est intégré et ne demande aucun code : l'onglet Paiements (Payments) masque ou affiche chaque passerelle pour les devises choisies (Règles de paiement (Payments rules) et Comportement des paiements (Payments behavior)), de sorte qu'une passerelle n'est proposée que dans les devises qu'elle peut facturer. Voir comment masquer une passerelle de paiement selon la devise.

Laisser les clients payer dans la devise qu'ils ont sélectionnée

La configuration inverse est Plusieurs devises autorisées (Is multiple allowed) = Oui (Yes) sans aucun code d'imposition. La page de paiement garde la devise du visiteur, la commande y est enregistrée avec le taux de change de ce moment, et la passerelle reçoit la demande de facturer cette devise. Votre code peut lire le réglage sous la forme $WOOCS->is_multiple_allowed.

Le paiement ou le panier retombe sur la devise de base

  • Plusieurs devises autorisées (Is multiple allowed) est toujours sur Non (No). C'est la cause dans la plupart des cas ; la devise repasse à la devise par défaut après le paiement explique ce comportement par défaut.
  • Paiement selon les règles GeoIP (Checkout by GeoIP rules) est activé et le pays du visiteur appartient à une autre devise.
  • Du code dans le thème ou un extrait appelle $WOOCS->set_currency() sur la page de paiement. Cherchez-le, y compris les anciennes versions des extraits ci-dessus.
  • Désactiver sur les pages (Disable on pages) dans l'onglet Options désactive FOX pour la racine du site. WooCommerce envoie les actualisations du paiement à l'adresse racine (/?wc-ajax=update_order_review) : le récapitulatif de commande est donc recalculé sans FOX et affiche la devise de base un instant après le chargement de la page.
  • La page du panier ou du paiement est en cache, elle affiche donc la devise de celui qui l'a chargée en premier. Excluez les deux de tout cache.

La passerelle doit accepter chaque devise de paiement

FOX transmet à la passerelle la devise de la commande ; la réussite du paiement dépend du compte de la passerelle. PayPal et Stripe acceptent de nombreuses devises de présentation, mais chacun a sa propre liste, et un versement dans une autre devise est converti par le prestataire à son propre taux et avec ses frais. Vérifiez les listes, pour PayPal dans devises acceptées par PayPal, et utilisez l'onglet Paiements (Payments) pour qu'une devise n'atteigne jamais une passerelle qui ne peut pas la facturer. Une passerelle à devise unique, fréquente chez les prestataires locaux, doit utiliser l'une des configurations d'imposition ci-dessus.

Tester un paiement en devise étrangère en toute sécurité

FOX n'a pas de mode de test de paiement propre ; utilisez le bac à sable ou le mode test de la passerelle. Passez une commande de test dans chaque devise que vous acceptez, puis comparez trois endroits : la Devise de la commande (Order currency) dans le bloc FOX de l'écran de la commande, le montant sur le tableau de bord de test de la passerelle et l'e-mail de commande. Les trois doivent indiquer la même devise et le même montant.

Ce que les commandes multidevises impliquent pour le back-office

Les commandes, les remboursements et les e-mails de commande sont dans la devise du client, et les rapports WooCommerce ne les convertissent pas d'eux-mêmes dans une seule devise. Chaque commande conserve son Taux de la devise de la commande (Order currency rate), sur lequel s'appuient les guides sur les analyses multidevises et où la devise de la commande est enregistrée. Modifier plus tard Plusieurs devises autorisées (Is multiple allowed) ne convertit pas les commandes existantes ; une commande peut être convertie individuellement avec Changer la devise de la commande (Change order currency) et Recalculer la commande (Recalculate order) dans le bloc FOX de l'écran de la commande, ce qui modifie l'enregistrement de la commande, et non le paiement déjà encaissé.

Quelle configuration choisir

Votre situationConfiguration
La passerelle ne facture que dans la devise de basePlusieurs devises autorisées (Is multiple allowed) = Non (No), montants approximatifs activés, extrait de rétablissement facultatif
La passerelle facture une seule devise qui n'est pas la devise de baseOui (Yes) + extrait d'imposition avec une seule devise acceptée
La passerelle accepte certaines de vos devisesOui (Yes) + extrait d'imposition avec la liste des devises acceptées
Des passerelles différentes pour des devises différentesOui (Yes) + règles de l'onglet Paiements (Payments), ou l'extrait par moyen de paiement
Toutes les devises peuvent être facturéesOui (Yes), sans code

Si la page de paiement affiche toujours une devise inattendue, testez avec un thème par défaut et seulement WooCommerce et FOX actifs, puis ouvrez un sujet sur le forum de support de FOX avec votre réglage Plusieurs devises autorisées (Is multiple allowed), le type de paiement (shortcode ou bloc) et tout code de devise que vous utilisez, et nous l'examinerons.