I was setting up WooCommerce Checkout and I wanted to make the checkout fields optional for PayPal checkout as PayPal also require such data.
While I still want other gateways like Stripe to require checkout field being filled.
I am new to PHP. Here's the code I tried, but it didn't work:
add_filter( 'woocommerce_default_address_fields' ,'custom_override_default_address_fields' );
$answer = $_POST['payment_method'];
if ( $answer == "cppec_paypal" ) {
function custom_override_default_address_fields( $address_fields ) {
$address_fields['address_1']['required'] = false;
return $address_fields;
}
...
I want the field to be optional for PayPal, but required for Stripe.
The second option is that we somehow bring the paypal button from cart here as it didnt required the data but the checkout does
Thanks
Related
I want to set the billing phone number required or not required based on the shipping method.
I have set the shipping method as an array and checked it from the session selected shipping method but it not working
add_filter('woocommerce_checkout_fields', 'fire_remove_billing_checkout_fields');
function fire_remove_billing_checkout_fields($fields) {
global $woocommerce;
$methods = array('flat_rate:2', 'flat_rate:3', 'flat_rate:17', 'flat_rate:20');// Set shipping method to hide the checkout field(s).
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if(in_array($chosen_shipping, $methods)){
$fields['billing']['billing_phone'][ 'required' ] = true;
}else{
$fields['billing']['billing_phone'][ 'required' ] = false;
}
return $fields;
}
Your code works well for me. I've added my shipping rate IDs and it works as expected, however refresh of the page is necessary, because WooCommerce doesn't refresh the billing fields natively on update_checkout trigger.
You should either reload the page using Javascript/jQuery on updated_checkout event, or reload only the billing fields using AJAX like so:
add_action( 'wp_footer', 'reload_billing_fields_on_updated_checkout' );
function reload_billing_fields_on_updated_checkout() {
?>
<script>
jQuery(document.body).on('updated_checkout', () => {
jQuery('.woocommerce-billing-fields').load(`${location.href} .woocommerce-billing-fields>*`, '');
});
</script>
<?php
}
Keep in mind that it might take a short while for those fields to reload, so you might want to add some loading CSS classes, or maybe a spinner.
How do I clear a specfic checkout fields in WooCommerce after placing an order?
For example Billing email and Billing Phone. So that when the registered customer makes his/her next order, he/she has to fill that fields again?
I see this code, but this clean all the fields, i need only a specific field. Any advice?
add_filter('woocommerce_checkout_get_value','__return_empty_string',10);
The woocommerce_checkout_get_value hook has 2 arguments:
$value argument that is returned
$input argument to target checkout field(s)
So in your case, you get:
function filter_woocommerce_checkout_get_value( $value, $input ) {
// Target checkout fields. Multiple fields can be added, separated by a comma
if ( in_array( $input, array( 'billing_phone', 'billing_email' ) ) ) {
$value = '';
}
return $value;
}
add_filter( 'woocommerce_checkout_get_value' , 'filter_woocommerce_checkout_get_value' , 10, 2 );
You could probably achieve this with some custom javascript:
document.getElementById('fieldID').value = ''
Or jQuery:
$('#fieldID').val('');
I don't know if it's possible, but, we would need to add some different payment methods for Barcelona.
So, our idea is that if the customer lives in Barcelona area (Catalunya), he will see a credit card payment method and a bank transfer account different than the rest of Spain.
Is that possible with WooCommerce?
Thanks.
If you want to enable this kind of feature in WooCommerce, Customers need to be registered and logged on first, as it's the only way to get they town location before checkout process.
Also you will have to change some settings in WooCommerce allowing only registerers users to checkout.
Then you will have to add some mandatory fields in the registration process as the town, zip code and country.
Once that done, it's going to be easy to enable / disable payment gateways based on this registered customer fields.
1) For customizing the registration fields:
How to add custom fields in user registration on the “My Account” page
2) For payment gateways/methods based on this Customer information, You can use a custom hooked function in woocommerce_available_payment_gateways filter hook:
add_filter( 'woocommerce_available_payment_gateways', 'custom_payment_gateways_process' );
function custom_payment_gateways_process( $available_gateways ) {
// Not in backend (admin)
if( is_admin() )
return $available_gateways;
if ( is_admin() || !is_user_logged_in() )
return $available_gateways;
$current_user_id = get_current_user_id();
$user_meta = get_user_meta( $current_user_id );
// User City, Postcode, State and Country code
$user_city = $user_meta['billing_city'];
$user_postcode = $user_meta['shipping_postcode'];
$user_State = $user_meta['shipping_state'];
$user_country = $user_meta['shipping_country'];
// Disable Cash on delivery ('cod') method example for customer out of spain:
if ( isset( $available_gateways['cod'] ) && $user_country != 'ES' ) {
unset( $available_gateways['cod'] );
}
// You can set many conditions based on the user data
return $available_gateways;
}
This code is just an example, and you will have to set inside the right conditions for the targeted payment methods/gateways…
Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.
I'm writing a custom WordPress function that will change the flat_rate shipping when a customer changes the "State" field from a select menu. Currently I'm doing it in my theme's functions.php
I have created a custom field to represent "State" field as a drop down menu in the billing fields. I used "WooCommerce Checkout Manager" plugin to setup the custom field and disabled the default "State" field.
Now I want to change the shipping cost depending on the value of my custom "State" field. I'm unable to retrieve the data of the field. Also I want to know what hook I can use to change the flat rate shipping once this field's value is changed.
I've used this filter hook (woocommerce_package_rates) and it doesn't work.
Here is my code to do it which I got it from another tutorial then made my customization
function wc_ninja_change_flat_rates_cost( $rates, $package ) {
$destination = $package['destination'];
$city = $destination['myfield12']; // getting the city field value
// Make sure flat rate is available
if ( isset( $rates['flat_rate'] ) ) {
if ( $city == 'Alex' || $city == 'الإسكندرية' ) {
// Set flat rate to cost $10 more
$rates['flat_rate']->cost = 30;
}
else {
$rates['flat_rate']->cost = 20;
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'wc_ninja_change_flat_rates_cost', 10, 2 );
I found this:
How to update shipping cost in cart dynamically (ajax) based on a custom field in WooCommerce
Basically it captures the field data through JS and send an Ajax request to the server which then stores the value in the session. Then adds an additional fee. It is not exactly what I was seeking to do but its a functional workaround.
I have a Wordpress setup with WooCommerce using the standard Paypal Gateway. Payments are being received and going through fine. Paypal IPN is being received by the site and marked as "Completed" for an order, but the order status remains unchanged in WooCommerce and still reads as "Processing".
10-04-2016 # 11:04:18 - Received valid response from PayPal
10-04-2016 # 11:04:18 - Found order #1303
10-04-2016 # 11:04:18 - Payment status: completed
Other things entered into Paypal gateway settings:
Paypal API Details
Paypal Identity Token
Clients Paypal login email as the receiver email and paypal email
Payment set to capture
Paypal Return URL:
http://[URL]/checkout/order-received/
Paypal Notification URL:
http://[URL]/?wc-api=WC_Gateway_Paypal
Other Related Woo Plugins installed:
https://woocommerce.com/products/woocommerce-bookings/
https://woocommerce.com/products/smart-coupons/
I'm a little stumped as what else to try, as the IPN is obviously being recieved but for whatever reason the WooCommerce is not updating the order status with this information. There are some PHP Notices regarding unrelated points in other templates but not anything that should be interfering with WooCommerce. Any help or ideas to try would be much appreciated!
I was having the same issue and discovered this is probably normal for WooCommerce since the product is supposed to be shipped out and then set to Completed. You can use a plugin to autocomplete the orders.
WooCommerce Autocomplete Orders
https://wordpress.org/plugins/woocommerce-autocomplete-order/
How To Automatically Set WooCommerce PayPal Orders as Completed
http://biostall.com/how-to-automatically-set-woocommerce-paypal-orders-as-completed/
Note: You have to make sure your product is Virtual and set the Mode to "Paid orders of virtual products only" under WooCommerce > Settings > Extra Options
Thanks for the reply, I did see the auto complete plugin but the client In hand required this to be a manual method. I managed to figure out a method that works for Paypal standard payment, based off the below resource:
http://codecharismatic.com/run-your-own-damn-code-after-paypal-calls-woocommerce-back/
<?php
/**
* Auto Complete Woocommerce 'processing' orders
*/
add_action( 'valid-paypal-standard-ipn-request', 'handle_paypal_ipn_response', 50, 1 );
function handle_paypal_ipn_response( $formdata ) {
if ( !empty( $formdata['invoice'] ) && !empty( $formdata['custom'] ) ) {
if( $formdata['payment_status'] == 'Completed' ) {
// decode data
$order_data = json_decode($formdata['custom'], true);
// get order
$order_id = ($order_data) ? $order_data['order_id'] : '';
$order = new WC_Order( $order_id );
// got something to work with?
if ( $order ) {
if ($order->post->post_status == 'wc-processing'){
// Status success
WC_Gateway_Paypal::log( 'Changing order #' . $order->id . ' status from processing to completed');
$order->update_status( 'completed' );
} else {
// Status fail
WC_Gateway_Paypal::log( 'Status fail, order #' . $order->id . ' status is set to ' . $order->post->post_status . ', not processing');
}
} else {
// Order fail
WC_Gateway_Paypal::log( 'Fail, no order found');
}
} else {
// Payment fail
WC_Gateway_Paypal::log( 'Payment status fail, not completed');
}
}
}