On the checkout page, we've a currency switcher for USD, EUR, INR, GBP currencies.
However, out of 3, only 1 gateway supports all currencies, & 2 supports INR.
So, I need to hide other two gateways, if someone selects USD, EUR & GBP
Can we use selected currency & do the needed function?
TIA
I use this to remove gateways if a particular product is in the cart:
add_filter('woocommerce_available_payment_gateways','filter_gateways',1);
function filter_gateways($gateways){
global $woocommerce;
foreach ($woocommerce->cart->cart_contents as $key => $values ) {
$product_ = array(1063);
if(in_array($values['product_id'],$product_)){
unset($gateways['paypal']);
break;
}}
return $gateways;
}
I dont know what your currency switcher is to get any variable from to modify the woocommerce_available_payment_gateways filter though.
This is working code and I have implemented it on [www.edupediapublications.org][1]
add_filter('woocommerce_available_payment_gateways', 'woocs_filter_gateways', 1);
function woocs_filter_gateways($gateway_list)
{
global $WOOCS;
$exclude = array(
'paypal' => array('EUR', 'GBP'), //do not show paypal gate if current currency is EUR or GBP
'stripe' => array('USD')//do not show stripe gate if current currency is USD
);
//***
foreach ($exclude as $gateway_key => $currencies)
{
if (isset($gateway_list[$gateway_key]) AND in_array($WOOCS->current_currency, $currencies))
{
unset($gateway_list[$gateway_key]);
}
}
return $gateway_list;
}
Okay. found a solution. Giving details below, if anyone stumbles here.
The "WooCommerce Currency Switcher" plugin changes the shop currency & stores using session / transient method. Not just that, it also adds a body class for each selected currency.
e.g.: currency-usd or currency-eur or currency-gbp
This is what is possible simply using CSS
.currency-usd .payment_method_instamojo, .currency-usd .payment_method_paynimo, .currency-eur .payment_method_instamojo, .currency-eur .payment_method_paynimo, .currency-gbp .payment_method_instamojo, .currency-gbp .payment_method_paynimo {display:none}
This works as expected w/o writing a separate function. Hope this helps.
Related
I need to display product price in the template commerce-product.html.twig
The variable {{ product.variation_price }} is rendered as currency and number e.g. USD700
And I can't understand how to display only number without currency?
There are two ways to achieve this:
Use the Commerce Currency Settings module.
Implement hook_commerce_currency_info_alter() in your custom module.
Since the task is very simple and will most likely never need to be updated after initial setup, there is no need to install another module. This means less components to think about and update in the long run, and less pages in the admin.
By implementing this in your custom module you will also get complete freedom to change the format in which the values are displayed. You can replace the dollar sign with USD, move it before / after the value or add custom labels.
Here's the code you need to use:
/**
* Implements hook_commerce_currency_info_alter().
*/
function YOUR_MODULE_commerce_currency_info_alter(&$currencies) {
// Get the abbreviation of the default currency. This will return "USD" for
// US Dollars, "EUR" for Euros, etc.
// If your site is using multiple currencies, you can skip this and just use
// the abbreviation of the currency you want to change the format for.
$default_currency = commerce_default_currency();
$currencies[$default_currency]['format_callback'] = 'YOUR_MODULE_commerce_currency_format';
}
/**
* Commerce currency format callback.
*/
function YOUR_MODULE_commerce_currency_format($amount, $currency, $currency_code, $object = NULL, $convert = TRUE) {
// Format the price as a number.
$price = number_format($amount, 2, $currency['decimal_separator'], $currency['thousands_separator']);
// Establish the replacement values to format this price for its currency.
$replacements = array(
'#code_before' => $currency['code_placement'] == 'before' ? '' : '', //Here you can set empty or put $currency['code']
'#symbol_before' => $currency['symbol_placement'] == 'before' ? '' : '', // set empty or $currency['symbol']
'#price' => $price,
'#symbol_after' => $currency['symbol_placement'] == 'after' ? '' : '', // set empty or $currency['symbol']
'#code_after' => $currency['code_placement'] == 'after' ? '' : '', //set empty or $currency['code']
'#negative' => $amount < 0 ? '-' : '',
'#symbol_spacer' => $currency['symbol_spacer'],
'#code_spacer' => $currency['code_spacer'],
);
return trim(t('#code_before#code_spacer#negative#symbol_before#price#symbol_spacer#symbol_after#code_spacer#code_after', $replacements));
}
NOTE: if you place the hook_commerce_currency_info_alter()
implementation in YOUR_MODULE.commerce.inc file, the callback will
still need to be placed in the .module file, because the .commerce.inc
file will not be automatically loaded everywhere.
That's it - all prices will be displayed without currency code.
Well, I've just found the answer by myself.
If a product has only one variation, we can get its price as number in Twig like:
{% set price_number = product.variation_price['#items'].0.number %}
Now, according to Displaying prices we can print it without fraction part like:
{{ price_number|number_format(0) }}
I want to enter the value of digits_phone meta key to be entered as billing_phone for every woocommerce order.
I came up with something like this but it did not work :
//Automatically add the digits phone number of the user, to woocommerce orders for every order
add_filter('woocommerce_checkout_posted_data', 'dg_manipulate_checkout_posted_data');
function dg_manipulate_checkout_posted_data ($data) {
$data['billing_phone'] =['digits_phone'];
return $data;
}
can anyone please help me to figure this out?
I have never used the plugin myself, take this as a guideline
THIS CODE IS NOT TESTED !
Maybe this question is a better fit for wordpress.stackexchange.com
From the last comment of this post I see that there should be 2 user metadata related to some digits_phone: 'digits_phone' and 'digits_phone_no'
Assuming that the one we want is digits_phone, this code should be a hint in the right direction:
add_filter('woocommerce_checkout_posted_data', 'dg_manipulate_checkout_posted_data');
function dg_manipulate_checkout_posted_data ($data) {
// save current user data in variable $current_user
$current_user = wp_get_current_user();
//get digits phone from db and save in variable $digits_phone
$digits_phone = get_user_meta( $current_user->ID, 'digits_phone' , true );
// assign to POSTed array and return it
$data['billing_phone'] = $digits_phone;
return $data;
}
Also have a look at How can I convert woocommerce checkout fields in capital letters to get a better picture of manipulating POST data
Is there a way for the customer to choose whether or not to include the tax in his order?
I imagine a field called "With / Without TAX"
And some code that based on that field, perform the necessary calculations.
If this is not possible, how could you add a button within the order edition to include or exclude taxes?
Thank you.
I did something similar by hooking into woocommerce_checkout_create_order when the order is placed. (Normal orders are taxed on customer's address, curbside orders are based on store address. You can simply use 0 based on if your customer checks a box)
add_action( 'woocommerce_checkout_create_order', array( $this, 'curbside_order'), 10, 1);
public function curbside_order( $order ) {
if( /** without tax - post_meta, checkbox or however you set it**/){
$order->set_cart_tax(0);
}
}
I have some e-commerce website where the customer billing address is predefined on the back-end.
I need to set the "Billing Address" fields as 'readonly' to avoid the customer to replace the information placed there... but i don´t know how/where to do it...
Is it possible?
Put following code in your theme's "function.php" file.
add_action('woocommerce_checkout_fields','customization_readonly_billing_fields',10,1);
function customization_readonly_billing_fields($checkout_fields){
$current_user = wp_get_current_user();;
$user_id = $current_user->ID;
foreach ( $checkout_fields['billing'] as $key => $field ){
if($key == 'billing_address_1' || $key == 'billing_address_2'){
$key_value = get_user_meta($user_id, $key, true);
if( strlen($key_value)>0){
$checkout_fields['billing'][$key]['custom_attributes'] = array('readonly'=>'readonly');
}
}
}
return $checkout_fields;
}
This function checks if the address fields have value (i.e. if the address is specified), and if it has value, makes the field/s readonly. Else keeps the fields open to add data for user.
Hope this helps.
You have not specified which form you want to customize making the billing address fields read-only. Normally the billing address fields appear on two types of forms on a WooCommerce site:
On a checkout form
On a my-account/edit-address/billing/ page
If your case is the first one, then zipkundan's answer is the best one. But if your case is the second one, then copy and paste the following code to your active theme's (or child theme if any) functions.php file:
add_filter('woocommerce_address_to_edit', 'cb_woocommerce_address_to_edit');
function cb_woocommerce_address_to_edit($address){
array_key_exists('billing_first_name', $address)?$address['billing_first_name']['custom_attributes'] = array('readonly'=>'readonly'):'';
array_key_exists('billing_last_name', $address)?$address['billing_last_name']['custom_attributes'] = array('readonly'=>'readonly'):'';
array_key_exists('billing_email', $address)?$address['billing_email']['custom_attributes'] = array('readonly'=>'readonly'):'';
array_key_exists('billing_email-2', $address)?$address['billing_email-2']['custom_attributes'] = array('readonly'=>'readonly'):'';
return $address;
}
The above code will make the following fields read-only:
Billing first name
Billing last name
Billing email address
Billing confirm email address
Array keys for other form fields on the same page are as follows:
billing_company
billing_country
billing_address_1
billing_address_2
billing_city
billing_state
billing_postcode
billing_phone
Additionally, you can make the read-only fields appear slightly faded out. So, add the following CSS to your theme's style.css
.woocommerce-address-fields input[readonly="readonly"]{
opacity: 0.5;
}
$checkout_fields['billing'][$key]['custom_attributes'] = array('readonly'=>'readonly');
this solves the problem
This one worked for me.
https://www.sitekickr.com/snippets/woocommerce/make-checkout-field-read
add_filter('woocommerce_billing_fields', 'my_woocommerce_billing_fields');
function my_woocommerce_billing_fields($fields)
{
$fields['billing_first_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_last_name']['custom_attributes'] = array('readonly'=>'readonly');
return $fields;
}
I have this error in my woocommerce web site:
Gateway Disabled: PayPal does not support your store currency.
Any one have specific solution for this?
I am using currency Saudi Riyaal(SAR) and american Dollars($).
I have been working on this problem for few days and here are the solutions I found. In my case I need BGN, so the codes are for that currency (they can be easily adapted for other currencies).
=== Solution 1 ===
The code in this solution is for a plugin file called paypal-bgn-to-euro.php (saved as UTF-8 without BOM for the Bulgarian words) that is in a folder called paypal-bgn-to-euro. The plugin tells PayPal to support BGN. Then after the user leaves the order page and goes to the PayPal site, it converts the currency (and amount) to EUR (an actual PayPal supported currency). The exchange rate is updated automatically twice daily from a free API. The user pays in EUR but the created order in WooCommerce is still in BGN. WooCommerce detects an error (or sometimes two) in the validation because the currencies (and amounts) do not match and it puts the order on hold. The plugin then changes the status to processing for any order with an order note saying something about PayPal currencies or amounts not matching. Read the comments in the code for more info.
<?php
/*
Plugin Name: Paypal BGN support
Description: Plugin description here.
Author: Nikolay Nikolov
Version: 1.0.0
*/
/////////////////////BEGIN segment 1
//this segment I got from here and changed it a little: http://devseon.com/en/wordpress-tutorials/woocommerce-add-a-paypal-unsupported-currency
//it lies to PayPal that the BGN currency is supported, and converts it to EUR when the payment is made
//it does not change the currency in the WooCommerce order, it remains the same, and WooCommerce detects an error and it puts the order on hold
//but we fix that in segment 3
add_filter( 'woocommerce_paypal_supported_currencies', 'pbte_add_bgn_paypal_valid_currency' );
function pbte_add_bgn_paypal_valid_currency( $currencies )
{
array_push ( $currencies , 'BGN' );
return $currencies;
}
add_filter('woocommerce_paypal_args', 'pbte_convert_bgn_to_eur');
function pbte_convert_bgn_to_eur($paypal_args)
{
if ( $paypal_args['currency_code'] == 'BGN')
{
$convert_rate = get_option('pbte_eur_to_bgn_rate'); //set the converting rate
$paypal_args['currency_code'] = 'EUR'; //change BGN to EUR
$i = 1;
while (isset($paypal_args['amount_' . $i]))
{
$paypal_args['amount_' . $i] = round( $paypal_args['amount_' . $i] / $convert_rate, 2);
++$i;
}
}
return $paypal_args;
}
/////////////////////END segment 1
/////////////////////BEGIN segment 2
//I made this segment so the exchange rate is updated automatically with a wordpress cron job twice daily
//runs on plugin activation
register_activation_hook( plugin_dir_path( __FILE__ )."paypal-bgn-to-euro.php", 'pbte_activate_plugin' );
//runs on plugin deactivation
register_deactivation_hook( plugin_dir_path( __FILE__ )."paypal-bgn-to-euro.php", 'pbte_deactivate_plugin' );
//when the cron job runs, we call a function to update the exchange rate option value
add_action('pbte_twicedaily_check_eur_event', 'pbte_update_eur_rate_option');
//runs on plugin activation
function pbte_activate_plugin()
{
pbte_update_eur_rate_option(); //we update the exchange rate option
if (!wp_next_scheduled('pbte_twicedaily_check_eur_event')) //adds an cron job (if it is not already added) to udpate the exchange rate twice daily
wp_schedule_event(time(), 'twicedaily', 'pbte_twicedaily_check_eur_event');
}
//runs on plugin deactivation
function pbte_deactivate_plugin()
{
wp_clear_scheduled_hook('pbte_twicedaily_check_eur_event'); //removes the cron job we added
}
//gets the exchange rate from a free api and updates our option
function pbte_update_eur_rate_option()
{
$data = json_decode(file_get_contents("http://api.fixer.io/latest?symbols=BGN&base=EUR")); //gets the exchange rate from a free api
if(!empty($data->rates->BGN))
{
if(get_option('pbte_eur_to_bgn_rate'))
update_option('pbte_eur_to_bgn_rate', floatval($data->rates->BGN));
else
add_option('pbte_eur_to_bgn_rate', floatval($data->rates->BGN)); //if the option does not exist for some reason, we create it
}
else //something went wrong while getting the data from the api so we will email the admin
{
$message = "This is a message from ".get_site_url()
.". There is a problem getting the API data in the plugin PayPal BGN support.";
$subject = "Problem with Paypal BGN support";
$to_email = get_bloginfo('admin_email');
$headers[] = 'Content-Type: text/html; charset=UTF-8';
wp_mail($to_email, $subject, $message, $headers);
}
}
/////////////////////END segment 2
/////////////////////BEGIN segment 3
//Since the currencies do not match, WooCommerce puts the order on hold. We fix this with this segment.
//this runs when a new note is added to the order
add_filter( 'woocommerce_new_order_note_data', 'pbte_fix_order_status', 10, 2 );
//if the note says that the PayPal currencies or amounts do not match, then we will change the status to processing
function pbte_fix_order_status($a_note, $a_order)
{
//the check is done in two languages
if ( strpos($a_note['comment_content'],'PayPal валутите не съвпадат') !== false
|| strpos($a_note['comment_content'],'PayPal currencies do not match') !== false
|| strpos($a_note['comment_content'],'PayPal наличността не отговаря') !== false
|| strpos($a_note['comment_content'],'PayPal amounts do not match') !== false )
{
//we create the order var
$order = new WC_Order($a_order['order_id']);
//if the current status is on-hold - we change it to processing and add an optional note
if($order->status == 'on-hold')
$order->update_status('processing', 'The PayPal BGN support plugin did this note.');
}
return $a_note;
}
/////////////////////END segment 3
?>
=== Solution 2 ===
--- Step 1 ---
You need to add this code with a small plugin or in your functions.php:
add_filter( 'woocommerce_paypal_supported_currencies', 'add_my_own_paypal_currency' );
function add_my_own_paypal_currency( $currencies )
{
array_push ( $currencies , 'BGN' );
return $currencies;
}
--- Step 2 ---
We convert the currency (and amount) to a supported one while the user is on the order page in our site, as he chooses the PayPal method.
So we need a different currency for different WooCommerce gateways. Which is exactly one of the features of a free plugin called Booster for WooCommerce (it has a paid version too). This feature is called Payment Gateways Currency.
When we activate the plugin and the selected feature we can choose a different currency only for PayPal and we enter there a conversion rate (for some reason it wants a comma for a separator and not a point). The paid version though is said to support automatic updates of the conversion rates (I haven't tested it).
After the payment is made, the order in WooCommerce is with the new currency now (not like Solution 1). Which might affect other plugins that you are using if they assume all orders are in the WooCommerce store currency.
=== Solution 3 ===
I haven't tested this one, but I found this paid plugin called "PAYPAL CURRENCY CONVERTER PRO FOR WOOCOMMERCE" and the author claims that it solves the problem.
if you are still having issues with this, here is a solution which i found.
Change the currency to correspond to your currency.
add_filter( 'woocommerce_paypal_supported_currencies', 'add_a_paypal_valid_currency' );
function add_a_paypal_valid_currency( $currencies ) {
array_push ( $currencies , 'AED' ); // AED = United Arab Emirates Dirham.
return $currencies;
}
add_filter('woocommerce_paypal_args', 'convert_to_usd');
function convert_to_usd($paypal_args){
if ( $paypal_args['currency_code'] == 'AED'){
$convert_rate = 3.67; // set the converting rate here
$paypal_args['currency_code'] = 'USD'; // change to USD
$i = 1;
while (isset($paypal_args['amount_' . $i])) {
$paypal_args['amount_' . $i] = round( $paypal_args['amount_' . $i] / $convert_rate, 2);
++$i;
}
}
return $paypal_args;
}