PRO - Charge in USD at checkout while displaying customer's local currency
The support doesn work on Saturdays and Sundays, so some Friday requests can be answered on Monday. If you have problems with registration ask help on contact us page pleaseIf you not got email within 24~36 business hours, firstly check your spam box, and if no any email from the support there - back to the forum and read answer here. DO NOT ANSWER ON EMAILS [noreply@pluginus.net] FROM THE FORUM!! Emails are just for your info, all answers should be published only here.
The support doesn work on Saturdays and Sundays, so some Friday requests can be answered on Monday.
Quote from guiravg on September 29, 2026, 22:11Hello,
I'm using FOX - Currency Switcher Professional for WooCommerce (I recently updated to the latest version). My store base currency is ARS (Argentina).
My problem: international customers see prices in their own currency (COP, GTQ, etc.) thanks to the GeoIP rules. But at checkout they get "No payment methods available", because my PayPal and credit/debit card gateways only accept USD and EUR — so when the cart currency is COP or GTQ, no gateway is shown and the customer cannot pay.
What I need: for all non-Argentine customers, the customer should still SEE the price in their local currency as a reference, but the actual PAYMENT at checkout must be processed in USD (or EUR for Europe). Argentine customers must stay unchanged — they pay in ARS via Mercado Pago and bank transfer.
What I already tried:
- "Payment rules" tab: currencies set so PayPal/cards show only for USD/EUR and Mercado Pago only for ARS. This just hides the gateway, it doesn't convert the currency.
- "Approximate price / approximate amount" options: they only display a reference number, the checkout still charges in the customer's currency.
- "Is multiple allowed": Yes = pays in selected currency (my current problem); No = pays in base currency, but my base is ARS, not USD, so that doesn't help either.
My question: Is there a way to force a fixed payment currency (USD) per payment gateway at checkout, while keeping the displayed price in the customer's local currency? If yes, where exactly is that setting? If it's not possible natively, what do you recommend?
Thank you.
Hello,
I'm using FOX - Currency Switcher Professional for WooCommerce (I recently updated to the latest version). My store base currency is ARS (Argentina).
My problem: international customers see prices in their own currency (COP, GTQ, etc.) thanks to the GeoIP rules. But at checkout they get"No payment methods available", because my PayPal and credit/debit card gateways only accept USD and EUR — so when the cart currency is COP or GTQ, no gateway is shown and the customer cannot pay.
What I need: for all non-Argentine customers, the customer should still SEE the price in their local currency as a reference, but the actual PAYMENT at checkout must be processed in USD (or EUR for Europe). Argentine customers must stay unchanged — they pay in ARS via Mercado Pago and bank transfer.
What I already tried:
-"Payment rules" tab: currencies set so PayPal/cards show only for USD/EUR and Mercado Pago only for ARS. This just hides the gateway, it doesn't convert the currency.
-"Approximate price / approximate amount" options: they only display a reference number, the checkout still charges in the customer's currency.
-"Is multiple allowed": Yes = pays in selected currency (my current problem); No = pays in base currency, but my base is ARS, not USD, so that doesn't help either.
My question: Is there a way to force a fixed payment currency (USD) per payment gateway at checkout, while keeping the displayed price in the customer's local currency? If yes, where exactly is that setting? If it's not possible natively, what do you recommend?
Thank you.
Quote from Alex Dev on September 30, 2026, 16:27Hello
Thank you for the clear description. You tested the right options, and your conclusions are correct: Payment rules only hide gateways, Approximate price/amount only show a reference value, and "Is multiple allowed" = No charges in the base currency, which is ARS in your case. FOX has no per-gateway "payment currency" setting.
A word on the idea itself. Showing a total in COP and then charging USD without the customer seeing it is something we would advise against. PayPal and the customer's bank apply their own exchange rate, so the amount on the customer's statement will never match the COP figure they saw at checkout. That leads to questions, disputes and chargebacks. It is safer to be explicit: customers browse the catalog and cart in their local currency, and when they reach checkout the cart is converted to USD (or EUR) and they are clearly told so.
The snippet below does exactly that:
- Customers browse in their local currency (COP, GTQ, etc.) through your GeoIP rules, as now.
- On checkout, if the current currency is not ARS, USD or EUR, FOX switches it to USD. European currencies (GBP, CHF, SEK, PLN, etc.) switch to EUR. The switch is a normal currency change, so every checkout refresh (address, shipping method) stays in USD and the totals do not jump.
- A notice above the checkout form tells the customer that payments are processed in USD, that the cart was converted from their currency at today's rate, and that their bank or PayPal may apply its own rate.
- The order gets an order note and a meta field (_woocs_auto_converted_from) showing the currency the customer browsed in, so you can see these orders in the admin.
- Argentine customers are not affected. They stay in ARS with Mercado Pago and bank transfer.
Please add this to the functions.php of your child theme, or use a code snippets plugin:
function woocs_payable_currencies() { return array( 'ARS', 'USD', 'EUR' ); } // Pick the checkout currency for a non-payable browsing currency function woocs_target_checkout_currency( $from ) { // European non-EUR currencies are charged in EUR, everything else in USD $europe = array( 'GBP', 'CHF', 'SEK', 'NOK', 'DKK', 'PLN', 'CZK', 'HUF', 'RON', 'BGN', 'ISK' ); return in_array( $from, $europe, true ) ? 'EUR' : 'USD'; } // Switch the currency as soon as the customer lands on checkout (or its AJAX refresh) function woocs_force_payable_currency_on_checkout() { if ( ! function_exists( 'is_checkout' ) || ! ( is_checkout() || is_checkout_pay_page() ) ) { return; } // order-pay page for an existing order keeps the order currency if ( isset( $_GET['key'] ) ) { return; } global $WOOCS; if ( ! is_object( $WOOCS ) ) { return; } $current = $WOOCS->current_currency; if ( in_array( $current, woocs_payable_currencies(), true ) ) { return; } $target = woocs_target_checkout_currency( $current ); // remember where we converted from, used for the notice and the order note $WOOCS->storage->set_val( 'woocs_auto_converted_from', $current ); $WOOCS->set_currency( $target ); // recalculate cart totals in the new currency if ( function_exists( 'WC' ) && WC()->cart ) { WC()->cart->calculate_totals(); } } add_action( 'wp', 'woocs_force_payable_currency_on_checkout', 1000 ); add_action( 'woocommerce_checkout_update_order_review', 'woocs_force_payable_currency_on_checkout', 1 ); // Clear the flag if the customer later picks a payable currency himself (e.g. ARS) add_action( 'wp', function () { global $WOOCS; if ( ! is_object( $WOOCS ) || ( function_exists( 'is_checkout' ) && is_checkout() ) ) { return; } $from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' ); if ( $from && $WOOCS->current_currency !== woocs_target_checkout_currency( $from ) ) { $WOOCS->storage->set_val( 'woocs_auto_converted_from', '' ); } }, 1001 ); // Explicit notice above the checkout form add_action( 'woocommerce_before_checkout_form', function () { global $WOOCS; if ( ! is_object( $WOOCS ) ) { return; } $from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' ); if ( empty( $from ) ) { return; } $to = $WOOCS->current_currency; wc_print_notice( sprintf( 'Payments in our store are processed in %1$s. Your cart has been automatically converted from %2$s to %1$s at today\'s exchange rate. Your bank or PayPal may apply its own conversion rate.', esc_html( $to ), esc_html( $from ) ), 'notice' ); }, 5 ); // Tag the order so the shop owner sees it was auto-converted add_action( 'woocommerce_checkout_create_order', function ( $order ) { global $WOOCS; if ( ! is_object( $WOOCS ) ) { return; } $from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' ); if ( empty( $from ) ) { return; } $order->update_meta_data( '_woocs_auto_converted_from', $from ); $order->add_order_note( sprintf( 'Customer browsed in %s, checkout was automatically converted to %s.', $from, $order->get_currency() ) ); }, 10 );FOX settings to go with it:
- Is multiple allowed: Yes (as you have now).
- Hide switcher on checkout page: Yes. Otherwise a customer could switch back to COP on checkout and lose the payment methods again.
- Checkout by GeoIP rules: No. That option sets the GeoIP currency (COP) on checkout and would undo the conversion.
- Payment rules: keep them as they are, PayPal and cards for USD/EUR, Mercado Pago for ARS.
You can adjust the lists in woocs_payable_currencies() and woocs_target_checkout_currency() if you want other currencies mapped differently.
One question: are you using the classic checkout (the [woocommerce_checkout] shortcode) or the newer block-based checkout? The snippet is written for the classic checkout. If yours is block-based, the notice needs a different approach and we will adjust it.
Please test it first on a staging copy or with a test order, using a VPN or GeoIP from Colombia, from a European country and from Argentina, and let us know the result.
Best regards, Alex
p.s. Place please actual purchase code of the plugin into the private area of the ticket:
https://share.pluginus.net/image/i20230222134241.png
https://share.pluginus.net/image/i20230222134615.png
https://share.pluginus.net/image/i20230222134511.png
Hello
Thank you for the clear description. You tested the right options, and your conclusions are correct: Payment rules only hide gateways, Approximate price/amount only show a reference value, and"Is multiple allowed" = No charges in the base currency, which is ARS in your case. FOX has no per-gateway"payment currency" setting.
A word on the idea itself. Showing a total in COP and then charging USD without the customer seeing it is something we would advise against. PayPal and the customer's bank apply their own exchange rate, so the amount on the customer's statement will never match the COP figure they saw at checkout. That leads to questions, disputes and chargebacks. It is safer to be explicit: customers browse the catalog and cart in their local currency, and when they reach checkout the cart is converted to USD (or EUR) and they are clearly told so.
The snippet below does exactly that:
- Customers browse in their local currency (COP, GTQ, etc.) through your GeoIP rules, as now.
- On checkout, if the current currency is not ARS, USD or EUR, FOX switches it to USD. European currencies (GBP, CHF, SEK, PLN, etc.) switch to EUR. The switch is a normal currency change, so every checkout refresh (address, shipping method) stays in USD and the totals do not jump.
- A notice above the checkout form tells the customer that payments are processed in USD, that the cart was converted from their currency at today's rate, and that their bank or PayPal may apply its own rate.
- The order gets an order note and a meta field (_woocs_auto_converted_from) showing the currency the customer browsed in, so you can see these orders in the admin.
- Argentine customers are not affected. They stay in ARS with Mercado Pago and bank transfer.
Please add this to the functions.php of your child theme, or use a code snippets plugin:
function woocs_payable_currencies() {
return array( 'ARS', 'USD', 'EUR' );
}
// Pick the checkout currency for a non-payable browsing currency
function woocs_target_checkout_currency( $from ) {
// European non-EUR currencies are charged in EUR, everything else in USD
$europe = array( 'GBP', 'CHF', 'SEK', 'NOK', 'DKK', 'PLN', 'CZK', 'HUF', 'RON', 'BGN', 'ISK' );
return in_array( $from, $europe, true ) ? 'EUR' : 'USD';
}
// Switch the currency as soon as the customer lands on checkout (or its AJAX refresh)
function woocs_force_payable_currency_on_checkout() {
if ( ! function_exists( 'is_checkout' ) || ! ( is_checkout() || is_checkout_pay_page() ) ) {
return;
}
// order-pay page for an existing order keeps the order currency
if ( isset( $_GET['key'] ) ) {
return;
}
global $WOOCS;
if ( ! is_object( $WOOCS ) ) {
return;
}
$current = $WOOCS->current_currency;
if ( in_array( $current, woocs_payable_currencies(), true ) ) {
return;
}
$target = woocs_target_checkout_currency( $current );
// remember where we converted from, used for the notice and the order note
$WOOCS->storage->set_val( 'woocs_auto_converted_from', $current );
$WOOCS->set_currency( $target );
// recalculate cart totals in the new currency
if ( function_exists( 'WC' ) && WC()->cart ) {
WC()->cart->calculate_totals();
}
}
add_action( 'wp', 'woocs_force_payable_currency_on_checkout', 1000 );
add_action( 'woocommerce_checkout_update_order_review', 'woocs_force_payable_currency_on_checkout', 1 );
// Clear the flag if the customer later picks a payable currency himself (e.g. ARS)
add_action( 'wp', function () {
global $WOOCS;
if ( ! is_object( $WOOCS ) || ( function_exists( 'is_checkout' ) && is_checkout() ) ) {
return;
}
$from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' );
if ( $from && $WOOCS->current_currency !== woocs_target_checkout_currency( $from ) ) {
$WOOCS->storage->set_val( 'woocs_auto_converted_from', '' );
}
}, 1001 );
// Explicit notice above the checkout form
add_action( 'woocommerce_before_checkout_form', function () {
global $WOOCS;
if ( ! is_object( $WOOCS ) ) {
return;
}
$from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' );
if ( empty( $from ) ) {
return;
}
$to = $WOOCS->current_currency;
wc_print_notice(
sprintf(
'Payments in our store are processed in %1$s. Your cart has been automatically converted from %2$s to %1$s at today\'s exchange rate. Your bank or PayPal may apply its own conversion rate.',
esc_html( $to ),
esc_html( $from )
),
'notice'
);
}, 5 );
// Tag the order so the shop owner sees it was auto-converted
add_action( 'woocommerce_checkout_create_order', function ( $order ) {
global $WOOCS;
if ( ! is_object( $WOOCS ) ) {
return;
}
$from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' );
if ( empty( $from ) ) {
return;
}
$order->update_meta_data( '_woocs_auto_converted_from', $from );
$order->add_order_note( sprintf( 'Customer browsed in %s, checkout was automatically converted to %s.', $from, $order->get_currency() ) );
}, 10 );FOX settings to go with it:
- Is multiple allowed: Yes (as you have now).
- Hide switcher on checkout page: Yes. Otherwise a customer could switch back to COP on checkout and lose the payment methods again.
- Checkout by GeoIP rules: No. That option sets the GeoIP currency (COP) on checkout and would undo the conversion.
- Payment rules: keep them as they are, PayPal and cards for USD/EUR, Mercado Pago for ARS.
You can adjust the lists in woocs_payable_currencies() and woocs_target_checkout_currency() if you want other currencies mapped differently.
One question: are you using the classic checkout (the [woocommerce_checkout] shortcode) or the newer block-based checkout? The snippet is written for the classic checkout. If yours is block-based, the notice needs a different approach and we will adjust it.
Please test it first on a staging copy or with a test order, using a VPN or GeoIP from Colombia, from a European country and from Argentina, and let us know the result.
Best regards, Alex
p.s. Place please actual purchase code of the plugin into the private area of the ticket:
https://share.pluginus.net/image/i20230222134241.png
https://share.pluginus.net/image/i20230222134615.png
https://share.pluginus.net/image/i20230222134511.png
Quote from guiravg on September 30, 2026, 23:19Hi Alex,
Thank you for the detailed snippet. I installed it via the Code Snippets plugin (classic checkout confirmed, as you asked).
Unfortunately it caused a critical error on the site. When a customer browsing in COP (from Colombia) went from the cart to the payment details step of the checkout, the page showed "There has been a critical error on this website." The Code Snippets plugin automatically deactivated the snippet due to a fatal error.
My setup, in case it matters:
- Theme: Elessi (NASA) child theme - the checkout uses a custom multi-step layout.
- FOX PRO version 2.5.4.
- Classic checkout (shortcode), confirmed.
- Other active plugins include LiteSpeed Cache and Mercado Pago.I deactivated the snippet to keep the store working. Before I try again, could you tell me:
1. How can I get you the exact error message? (Should I enable WP_DEBUG and send you the debug.log line, or is there a safer way?)
2. Do you think the conflict could be with the Elessi/NASA theme's custom checkout, or with WC()->cart->calculate_totals() being called on the wp hook?I'd rather not test again on the live site until we understand the cause. Is there an adjusted version I can try?
Thank you.
Hi Alex,
Thank you for the detailed snippet. I installed it via the Code Snippets plugin (classic checkout confirmed, as you asked).
Unfortunately it caused a critical error on the site. When a customer browsing in COP (from Colombia) went from the cart to the payment details step of the checkout, the page showed"There has been a critical error on this website." The Code Snippets plugin automatically deactivated the snippet due to a fatal error.
My setup, in case it matters:
- Theme: Elessi (NASA) child theme - the checkout uses a custom multi-step layout.
- FOX PRO version 2.5.4.
- Classic checkout (shortcode), confirmed.
- Other active plugins include LiteSpeed Cache and Mercado Pago.
I deactivated the snippet to keep the store working. Before I try again, could you tell me:
1. How can I get you the exact error message? (Should I enable WP_DEBUG and send you the debug.log line, or is there a safer way?)
2. Do you think the conflict could be with the Elessi/NASA theme's custom checkout, or with WC()->cart->calculate_totals() being called on the wp hook?
I'd rather not test again on the live site until we understand the cause. Is there an adjusted version I can try?
Thank you.
Quote from Alex Dev on October 2, 2026, 12:42Hello
Thank you for the details and for testing carefully, and you did the right thing deactivating it.
I checked the snippet against FOX 2.5.4 line by line. Every FOX method it calls exists and is public in that version, and the function names do not clash with anything in the plugin. The fact that Code Snippets saved it without complaint also means the code itself is valid. So the crash most likely happens because of what runs in the same request. In your multi-step checkout, moving to the payment step fires the order review AJAX refresh. The snippet changes the currency there, and some other code in that same request (Mercado Pago, the Elessi checkout, or the cart recalculation the snippet itself triggers) does not handle the currency change and throws an error.
To stop guessing, we need the exact error message. You do not need to enable WP_DEBUG on the live site for that, here are two safer ways:
- Open Snippets in wp-admin and click Edit on the deactivated snippet. Code Snippets usually shows why it was deactivated, with the line number and the error text.
- When a fatal error happens, WordPress sends an email to the site admin address titled "Your Site is Experiencing a Technical Issue". It contains the file, the line and the error message. Please check that inbox, including spam.
Please copy the error text here exactly as it is. If it points to a file of Mercado Pago or the Elessi theme rather than to the snippet, that tells us where the real conflict is.
Meanwhile, here is an adjusted version of the snippet. It removes the manual cart recalculation (FOX and WooCommerce recalculate the cart on checkout anyway), runs later in the checkout refresh so it no longer steps in before WooCommerce and your theme, and wraps the currency switch in a safety net. If something fails, the checkout keeps working and the error is written to the PHP error log instead of breaking the page. Please replace the old snippet with this one:
function woocs_payable_currencies() { return array( 'ARS', 'USD', 'EUR' ); } // Pick the checkout currency for a non-payable browsing currency function woocs_target_checkout_currency( $from ) { // European non-EUR currencies are charged in EUR, everything else in USD $europe = array( 'GBP', 'CHF', 'SEK', 'NOK', 'DKK', 'PLN', 'CZK', 'HUF', 'RON', 'BGN', 'ISK' ); return in_array( $from, $europe, true ) ? 'EUR' : 'USD'; } // Switch the currency on checkout (page load and AJAX refresh) function woocs_force_payable_currency_on_checkout() { try { if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) { return; } // order-pay page for an existing order keeps the order currency if ( function_exists( 'is_checkout_pay_page' ) && is_checkout_pay_page() ) { return; } global $WOOCS; if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) ) { return; } $current = $WOOCS->current_currency; if ( in_array( $current, woocs_payable_currencies(), true ) ) { return; } $target = woocs_target_checkout_currency( $current ); // remember where we converted from, used for the notice and the order note $WOOCS->storage->set_val( 'woocs_auto_converted_from', $current ); $WOOCS->set_currency( $target ); } catch ( \Throwable $e ) { // never break the checkout, just log the reason error_log( 'woocs payable currency snippet: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() ); } } add_action( 'wp', 'woocs_force_payable_currency_on_checkout', 1000 ); add_action( 'woocommerce_checkout_update_order_review', 'woocs_force_payable_currency_on_checkout', 9999 ); // Clear the flag if the customer later picks a payable currency himself (e.g. ARS) add_action( 'wp', function () { global $WOOCS; if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) || ( function_exists( 'is_checkout' ) && is_checkout() ) ) { return; } $from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' ); if ( $from && $WOOCS->current_currency !== woocs_target_checkout_currency( $from ) ) { $WOOCS->storage->set_val( 'woocs_auto_converted_from', '' ); } }, 1001 ); // Explicit notice above the checkout form add_action( 'woocommerce_before_checkout_form', function () { global $WOOCS; if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) ) { return; } $from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' ); if ( empty( $from ) ) { return; } $to = $WOOCS->current_currency; wc_print_notice( sprintf( 'Payments in our store are processed in %1$s. Your cart has been automatically converted from %2$s to %1$s at today\'s exchange rate. Your bank or PayPal may apply its own conversion rate.', esc_html( $to ), esc_html( $from ) ), 'notice' ); }, 5 ); // Tag the order so the shop owner sees it was auto-converted add_action( 'woocommerce_checkout_create_order', function ( $order ) { global $WOOCS; if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) ) { return; } $from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' ); if ( empty( $from ) ) { return; } $order->update_meta_data( '_woocs_auto_converted_from', $from ); $order->add_order_note( sprintf( 'Customer browsed in %s, checkout was automatically converted to %s.', $from, $order->get_currency() ) ); }, 10 );As you said, please test it on a staging copy first, not on the live site. If the staging copy still crashes, one quick test is worth doing: temporarily deactivate Mercado Pago there and try the Colombian checkout again. If it passes without Mercado Pago, we know exactly where the conflict is.
And one more thing: please also place your actual purchase code of the plugin into the private area of the ticket, as asked in my previous message. You can send it together with the error message:
https://share.pluginus.net/image/i20230222134241.png
https://share.pluginus.net/image/i20230222134615.png
https://share.pluginus.net/image/i20230222134511.pngBest regards, Alex
Hello
Thank you for the details and for testing carefully, and you did the right thing deactivating it.
I checked the snippet against FOX 2.5.4 line by line. Every FOX method it calls exists and is public in that version, and the function names do not clash with anything in the plugin. The fact that Code Snippets saved it without complaint also means the code itself is valid. So the crash most likely happens because of what runs in the same request. In your multi-step checkout, moving to the payment step fires the order review AJAX refresh. The snippet changes the currency there, and some other code in that same request (Mercado Pago, the Elessi checkout, or the cart recalculation the snippet itself triggers) does not handle the currency change and throws an error.
To stop guessing, we need the exact error message. You do not need to enable WP_DEBUG on the live site for that, here are two safer ways:
- Open Snippets in wp-admin and click Edit on the deactivated snippet. Code Snippets usually shows why it was deactivated, with the line number and the error text.
- When a fatal error happens, WordPress sends an email to the site admin address titled"Your Site is Experiencing a Technical Issue". It contains the file, the line and the error message. Please check that inbox, including spam.
Please copy the error text here exactly as it is. If it points to a file of Mercado Pago or the Elessi theme rather than to the snippet, that tells us where the real conflict is.
Meanwhile, here is an adjusted version of the snippet. It removes the manual cart recalculation (FOX and WooCommerce recalculate the cart on checkout anyway), runs later in the checkout refresh so it no longer steps in before WooCommerce and your theme, and wraps the currency switch in a safety net. If something fails, the checkout keeps working and the error is written to the PHP error log instead of breaking the page. Please replace the old snippet with this one:
function woocs_payable_currencies() {
return array( 'ARS', 'USD', 'EUR' );
}
// Pick the checkout currency for a non-payable browsing currency
function woocs_target_checkout_currency( $from ) {
// European non-EUR currencies are charged in EUR, everything else in USD
$europe = array( 'GBP', 'CHF', 'SEK', 'NOK', 'DKK', 'PLN', 'CZK', 'HUF', 'RON', 'BGN', 'ISK' );
return in_array( $from, $europe, true ) ? 'EUR' : 'USD';
}
// Switch the currency on checkout (page load and AJAX refresh)
function woocs_force_payable_currency_on_checkout() {
try {
if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
return;
}
// order-pay page for an existing order keeps the order currency
if ( function_exists( 'is_checkout_pay_page' ) && is_checkout_pay_page() ) {
return;
}
global $WOOCS;
if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) ) {
return;
}
$current = $WOOCS->current_currency;
if ( in_array( $current, woocs_payable_currencies(), true ) ) {
return;
}
$target = woocs_target_checkout_currency( $current );
// remember where we converted from, used for the notice and the order note
$WOOCS->storage->set_val( 'woocs_auto_converted_from', $current );
$WOOCS->set_currency( $target );
} catch ( \Throwable $e ) {
// never break the checkout, just log the reason
error_log( 'woocs payable currency snippet: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() );
}
}
add_action( 'wp', 'woocs_force_payable_currency_on_checkout', 1000 );
add_action( 'woocommerce_checkout_update_order_review', 'woocs_force_payable_currency_on_checkout', 9999 );
// Clear the flag if the customer later picks a payable currency himself (e.g. ARS)
add_action( 'wp', function () {
global $WOOCS;
if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) || ( function_exists( 'is_checkout' ) && is_checkout() ) ) {
return;
}
$from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' );
if ( $from && $WOOCS->current_currency !== woocs_target_checkout_currency( $from ) ) {
$WOOCS->storage->set_val( 'woocs_auto_converted_from', '' );
}
}, 1001 );
// Explicit notice above the checkout form
add_action( 'woocommerce_before_checkout_form', function () {
global $WOOCS;
if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) ) {
return;
}
$from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' );
if ( empty( $from ) ) {
return;
}
$to = $WOOCS->current_currency;
wc_print_notice(
sprintf(
'Payments in our store are processed in %1$s. Your cart has been automatically converted from %2$s to %1$s at today\'s exchange rate. Your bank or PayPal may apply its own conversion rate.',
esc_html( $to ),
esc_html( $from )
),
'notice'
);
}, 5 );
// Tag the order so the shop owner sees it was auto-converted
add_action( 'woocommerce_checkout_create_order', function ( $order ) {
global $WOOCS;
if ( ! is_object( $WOOCS ) || ! is_object( $WOOCS->storage ) ) {
return;
}
$from = $WOOCS->storage->get_val( 'woocs_auto_converted_from' );
if ( empty( $from ) ) {
return;
}
$order->update_meta_data( '_woocs_auto_converted_from', $from );
$order->add_order_note( sprintf( 'Customer browsed in %s, checkout was automatically converted to %s.', $from, $order->get_currency() ) );
}, 10 );
As you said, please test it on a staging copy first, not on the live site. If the staging copy still crashes, one quick test is worth doing: temporarily deactivate Mercado Pago there and try the Colombian checkout again. If it passes without Mercado Pago, we know exactly where the conflict is.
And one more thing: please also place your actual purchase code of the plugin into the private area of the ticket, as asked in my previous message. You can send it together with the error message:
https://share.pluginus.net/image/i20230222134241.png
https://share.pluginus.net/image/i20230222134615.png
https://share.pluginus.net/image/i20230222134511.png
Best regards, Alex
Quote from guiravg on October 2, 2026, 20:26Hi Alex,
We got the exact error from the server's PHP log, and the cause was on our side, not in your snippet:
PHP Fatal error: Uncaught ValueError: Unknown format specifier "\" in the sprintf() of the checkout notice.
When the first snippet was loaded into the Code Snippets editor, extra backslashes were added before the $s placeholders (%1\$s instead of %1$s), which breaks sprintf(). It only fired for customers browsing in a non-payable currency (like COP), because that is when the notice is printed. So your code, Mercado Pago and the Elessi theme were not the problem.
Thank you for the adjusted version. We will install it by copy-paste (checking the placeholders) and test it. I also entered the purchase code in the private area.
Best regards
Hi Alex,
We got the exact error from the server's PHP log, and the cause was on our side, not in your snippet:
PHP Fatal error: Uncaught ValueError: Unknown format specifier"\" in the sprintf() of the checkout notice.
When the first snippet was loaded into the Code Snippets editor, extra backslashes were added before the $s placeholders (%1\$s instead of %1$s), which breaks sprintf(). It only fired for customers browsing in a non-payable currency (like COP), because that is when the notice is printed. So your code, Mercado Pago and the Elessi theme were not the problem.
Thank you for the adjusted version. We will install it by copy-paste (checking the placeholders) and test it. I also entered the purchase code in the private area.
Best regards