I use Lirox One theme on Wordpress with WooCommerce. I want make custom redirections after payment:
If a customer buy product ID 333, It will be redirected to product 444 (for example).
I have make some custom code but it doesn't works, I get an error 500 (and debug is empty).
What I am doing wrong and how can I make it work?
This is my code:
add_action( 'woocommerce_thankyou', 'check_order_product_id', 1 );
function check_order_product_id( $order_id ){
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
//* single product id
if ( $product_id == 399 ) {
// Content Title line
$url = 'http://yoursite.com/custom-url1';
}
if ( $product_id == 358 ) {
$url = 'http://yoursite.com/custom-url2';
}
if ( $product_id == 398 ) {
$url = 'http://yoursite.com/custom-url3';
}
if ( $product_id == 357) {
$url = 'http://yoursite.com/custom-url5';
}
if ( $product_id == 356) {
$url = 'http://yoursite.com/custom-url6';
}
if ( $product_id == 335) {
$url = 'http://yoursite.com/custom-url';
}
if ( $order->status != 'failed' ) {
wp_redirect($url);
exit;
}
For redirections, use a custom function hooked in WordPress template_redirect action hook, to avoid errors 500…
I have changed your code as you will see, to match your requirements. This code is made for WooCommerce version 3+:
add_action( 'template_redirect', 'conditional_redirection_after_payment');
function conditional_redirection_after_payment(){
// When "thankyou" order-received page is reached …
if ( is_wc_endpoint_url( 'order-received' ) ) {
global $wp;
// Get the order ID from the browser url
$order_id = intval( str_replace( 'checkout/order-received/', '', $wp->request ) );
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// If the order status is 'failed' we stop the function
if( $order->has_status( 'failed' ) ) return;
// HERE set in the array for each product ID the coresponding url final path
$product_id_url_paths = array(
'399' => '/custom-url1',
'358' => '/custom-url2',
'398' => '/custom-url3',
'357' => '/custom-url4',
'356' => '/custom-url5',
'335' => '/custom-url6',
);
// Iterating through each order items
foreach( $order->get_items() as $item_id => $item_values ){
// The Product ID
$product_id = $item_values->get_product_id();
foreach( $product_id_url_paths as $key_id => $url_path ){
if( $key_id == $product_id ){
// Product is found and ID match: we got our path url. We redirect
wp_redirect( home_url( $url_path ) );
exit(); // always exit
}
}
}
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Code is tested and works on WC 3+
Note: In your Code you have to remove the exit which you have used after the wp_redirect. Other all will work fine. Some more References are provided below in order to have better understanding of the Concept.
Explanation: Then you Provide Redirect only for the Particular Product
ID alone not For all the Product IDS since it may lead you to the
Internal Server Error as it is in the Foreach Loop.
It is Fine using wp_redirect() for the redirection purpose.
It is correct what have you checked for the Product ID. The Thing is that you have to follow another method if the URL are to be explicitly passed.
// We don't know for sure whether this is a URL for this site,
// so we use wp_safe_redirect() to avoid an open redirect.
wp_safe_redirect( $url );
// We are trying to redirect to another site, using a hard-coded URL.
wp_redirect( 'https://example.com/some/page' );
Some More Reference:
<?php wp_redirect( home_url() ); exit; ?>
Redirects can also be external, and/or use a “Moved Permanently” code :
<?php wp_redirect( 'http://www.example-one.com', 301 ); exit; ?>
The code below redirects to the parent post URL which can be used to redirect attachment pages back to the parent.
<?php wp_redirect( get_permalink( $post->post_parent ) ); exit; ?>
Reference: https://developer.wordpress.org/reference/functions/wp_redirect/
Th accepted answer works for Woocommerce 3+, for older versions (I'm using 2.6.4) it does not. For anyone else using this version, try the following code:
add_action( 'template_redirect', 'conditional_redirection_after_payment');
function conditional_redirection_after_payment(){
// When "thankyou" order-received page is reached …
if ( is_wc_endpoint_url( 'order-received' ) ) {
global $wp;
$order_id = intval( str_replace( 'checkout/order-received/', '', $wp->request ) );
// Get an instance of the WC_Order object
$order = new WC_Order( $order_id );
// If the order status is 'failed' we stop the function
if( $order->has_status( 'failed' ) ) return;
// HERE set in the array for each product ID the coresponding url final path
$product_id_url_paths = array(
'1234' => '/your-path/'
);
// Iterating through each order items
foreach( $order->get_items() as $item){
// echo $item_id;
// The Product ID
$product_id = $item['product_id'];
foreach( $product_id_url_paths as $key_id => $url_path ){
if( $key_id == $product_id ){
// Product is found and ID match: we got our path url. We redirect
wp_redirect( home_url( $url_path ) );
exit(); // always exit
}
}
}
}
}
Related
So i have custom text field meta in the product so that if has a url i would like to redirect users to a custom TY page after checkout. Here is my code and not redirecting!!
add_action('template_redirect', 'my_redirect_after_purchase');
function my_redirect_after_purchase() {
global $post, $wp;
$my_redirect = get_post_meta( get_the_ID(), '_my_redirect', true ); // This has the redirect URL entered in the field tested and working
if ( '' !== $my_redirect ) { // am checking here if the field is not empty
if (!empty($wp->query_vars['order-received'])) {
wp_redirect(esc_url($my_redirect));
exit;
}
}
}
I have tried few other ways but no luck too. Am guessing the query for order-recieved runs after and thus the meta returns empty?
How should i go about this? Thanks
First, you have to get order items using wc_get_order then you can get meta based on product id. Try the below code.
add_action('template_redirect', 'my_redirect_after_purchase');
function my_redirect_after_purchase() {
/* return if we are not on order-received page */
if( !is_wc_endpoint_url( 'order-received' ) || empty( $_GET['key'] ) ) {
return;
}
$order_id = wc_get_order_id_by_order_key( $_GET['key'] );
$order = wc_get_order( $order_id );
foreach( $order->get_items() as $item ) {
$my_redirect = get_post_meta( $item['product_id'] , '_my_redirect', true );
if( $my_redirect != '' ){
wp_redirect( $my_redirect );
exit;
}
}
}
I want to redirect to a custom wordpress page if a customers woocommerce order fails.
I have found and implemented the following code which redirects to a new page upon payment success.
Is it possible to add to this code, so a failed order is sent to another specific url ?
add_action( 'woocommerce_thankyou', 'bbloomer_redirectcustom');
function bbloomer_redirectcustom( $order_id ){
$order = wc_get_order( $order_id );
$url = 'https://yoursite.com/custom-url';
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url );
exit;
}
}
Based on the code you have, you can use $order->has_status( 'failed' )
So you get:
function action_woocommerce_thankyou( $order_id ) {
// Get $order object
$order = wc_get_order( $order_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Settings
$url1 = 'https://yoursite.com/custom-url-1';
$url2 = 'https://yoursite.com/custom-url-2';
// Compare
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url1 );
exit;
} else {
wp_safe_redirect( $url2 );
exit;
}
}
}
add_action( 'woocommerce_thankyou', 'action_woocommerce_thankyou', 10, 1 );
Code goes in functions.php file of the active child theme (or active theme). Tested and works in Wordpress 5.8.1 & WooCommerce 5.8.0
I need to make it so when people press place order on our webshop, they will get redirectet to My Account, but only if the categories is XXX , XXX , XXX
But i can't seem to get it working unfortunally
I have tried using && is_product_category('Category x','Category x','Category x')
// REDIRECT AFTER PLACE ORDER BUTTON!
add_action( 'woocommerce_thankyou', 'KSVS_redirect_custom');
function KSVS_redirect_custom( $order_id ){
$order = new WC_Order( $order_id );
$url = 'https://kanselvvilselv.dk/min-konto/';
if ( $order->status != 'failed' ) {
wp_redirect($url);
exit;
}
}
It is working without putting in && is_product_category('Category x','Category x','Category x'), But then it is working on categories where it should not work.
The following code using dedicated template_redirect hook and WordPress has_term() conditional function (to be used with product categories), will redirect customers after checkout to my account section, when their order contain items from defined product categories:
add_action( 'template_redirect', 'order_received_redirection_to_my_account' );
function order_received_redirection_to_my_account() {
// Only on "Order received" page
if( is_wc_endpoint_url('order-received') ) {
global $wp;
// HERE below define your product categories in the array
$categories = array('Tshirts', 'Hoodies', 'Glasses');
$order = wc_get_order( absint($wp->query_vars['order-received']) ); // Get the Order Object
$category_found = false;
// Loop theough order items
foreach( $order->get_items() as $item ){
if( has_term( $categories, 'product_cat', $item->get_product_id() ) ) {
$category_found = true;
break;
}
}
if( $category_found ) {
// My account redirection url
$my_account_redirect_url = get_permalink( get_option('woocommerce_myaccount_page_id') );
wp_redirect( $my_account_redirect_url );
exit(); // Always exit
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: i'm not familiar with woocommerce at all, please take my answer with ease.
Seems like function is_product_category have different purpouse, by quick overview I came with this, give it a try:
$redirectWhenCategoryIs = ['cat x', 'cat y', 'cat z'];
$categories = [];
foreach($order->get_items() as $item) {
foreach(get_the_terms($item['product_id'], 'product_cat') as $term){
$categories[] = $term->slug;
}
}
if(count(array_intersect($redirectWhenCategoryIs, $categories))){
wp_redirect($url);
}
Updated, this should loop through all ordered products and if it matches 1 product with a category then it will redirect to your URL:
add_action( 'woocommerce_thankyou', 'KSVS_redirectcustom');
function KSVS_redirectcustom( $order_id ){
$order = wc_get_order( $order_id );
$url = get_permalink( get_option('woocommerce_myaccount_page_id') );
if ( $order->status != 'failed' ) {
$product_cats = array('product-cat1', 'product-cat', 'product-cat3');
foreach ($order->get_items() as $item) {
if ( has_term( $product_cats, 'product_cat', $product->id) ) {
$cat_check = true;
break;
}
}
if ( $cat_check ) {
wp_redirect($url);
exit;
}
}
}
I have this code:
add_action('template_redirect', 'woo_custom_redirect');
function woo_custom_redirect( $redirect ) {
if (
! is_user_logged_in()
&& (is_checkout())
) {
wp_redirect( home_url( '/my-account/edit-account/' ) );
return $redirect;
}
}
How can I replace the redirection condition when I make an order to purchase a product from a certain category?
For example, if a user purchases a product from a certain category, then when he attempts to place an order, he redirects to registration and back, after successful registration.
The following code will redirect to my account page the non logged user in checkout page when they have an item from a specific product category. You will have to define in the code your specific product category:
add_action('template_redirect', 'woo_custom_redirect');
function woo_custom_redirect( $redirect ) {
// HERE set your product category (can be term IDs, slugs or names)
$category = 'posters';
$found = false;
// CHECK CART ITEMS: search for items from our product category
foreach ( WC()->cart->get_cart() as $cart_item ){
if( has_term( $category, 'product_cat', $cart_item['product_id'] ) ) {
$found = true;
break;
}
}
if ( ! is_user_logged_in() && is_checkout() && $found ) {
wp_redirect( get_permalink( get_option('woocommerce_myaccount_page_id') ) );
exit();
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I needed to do this recently and this solution worked for me. This solution checks what product categories the items are in, in the order details once the order has been received. So the redirect will take place after payment has been made.
add_action( 'template_redirect', 'woocommerce_redirect_after_checkout' );
function woocommerce_redirect_after_checkout() {
global $wp;
if ( is_checkout() && ! empty( $wp->query_vars['order-received'] ) ) {
$order_id = absint( $wp->query_vars['order-received'] );
$order = wc_get_order( $order_id );
$prod_category = [CAT ID OR SLUG];
foreach( $order->get_items() as $item ) {
if( has_term( $prod_category, 'product_cat', $item['product_id'] ) ) {
// change below to the URL that you want to send your customer to
$redirect_url = 'https://www.example.com/custom-thank-you/';
wp_redirect($redirect_url );
exit;
}
}
}
}
I am trying to get all products to redirect to one custom page EXCEPT for 3 products which go to Checkout (this part works).
function my_custom_add_to_cart_redirect( $url ) {
if ( ! isset( $_REQUEST['add-to-cart'] ) || ! is_numeric( $_REQUEST['add-to-cart'] ) ) {
$url = get_permalink( 16 ); // URL page ID to redirect for all pages but below mentioned
return $url;
}
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_REQUEST['add-to-cart'] ) );
// Only redirect the product IDs in the array to the checkout
if ( in_array( $product_id, array( 999, 997, 872) ) ) {
$url = WC()->cart->get_checkout_url();
}
return $url;
}
add_filter( 'woocommerce_add_to_cart_redirect', 'my_custom_add_to_cart_redirect' );
To make your code working as expected, is very simple. Below I have change a little bit your code:
add_filter( 'woocommerce_add_to_cart_redirect', 'my_custom_add_to_cart_redirect', 10, 1 );
function my_custom_add_to_cart_redirect( $url ) {
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_REQUEST['add-to-cart'] ) );
// Only redirect the product IDs in the array to the checkout
if ( in_array( $product_id, array( 999, 997, 872) ) ) {
// This is more correct to get the checkout URL
$url = get_permalink( get_option('woocommerce_checkout_page_id') );
} else {
// All other products that are not in your array will be redirected to this URL
$url = get_permalink( 16 ); // URL page ID to redirect for all pages but below mentioned
}
return $url;
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.