I was able to follow the redirect tutorial https://businessbloomer.com/resolved-woocommerce-redirect-custom-thank-page/
But can't seem to add the woocommerce variables to the url.
I want something like this > http://example.com?EO_ID=M180924-678922&Product_Code=vssx2&Quantity=1&Email=billing_email#gmail.com'
Thanks.
The linked code is outdated and don't handle any URL query string. You should need to make changes and adapt the code.
Note: Orders can have many items, so to make it work for your case we use the first item only.
Try this (you will need to define your URL path for $path variable):
add_action( 'woocommerce_thankyou', 'thankyou_custom_redirect', 5, 1 );
function thankyou_custom_redirect( $order_id ){
// Get the WC_Order object instance
$order = wc_get_order( $order_id );
// Order data
$order_key = $order->get_order_key(); // Get order key (if needed)
$transaction_id= $order->get_transaction_id(); // Get order key (if needed)
$billing_email = $order->get_billing_email(); // Get billing email
$order_num = $order->get_order_number(); // Get order number
$order_date = $order->get_date_created(); // Get order creation date
// Order item data (first item)
$order_items = $order->get_items(); // Get order items
$first_item = reset($order_items); // Keep the first Item
$item_qty = $first_item->get_quantity(); // Item quantity
$product = $first_item->get_product(); // Get the WC_Product object instance
$sku = $product->get_sku(); // Get the product code (SKU)
// Build your query string
$query_string = '?EO_ID=' . $order_date->date('ymd') . -rand(pow(10, 5), pow(10, 6)-1);
$query_string .= '&Product_Code=' . $sku;
$query_string .= '&Quantity=' . $item_qty;
$query_string .= '&Email=' . $billing_email;
$path = '/custom-path/'; // <=== HERE define the url path (without the domain)
$url = home_url( $path . $query_string );
// Not for failed orders
if ( ! $order->has_status( 'failed' ) ) {
wp_redirect( $url );
exit();
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Related
While im pretty hopeless at php, i feel like im getting close on this one, i just cant quite lock it in
So we have 2 plugins in the mix here WCFM & AST
In WCFM, a vendor adds a tracking number and carrier this is store in the order meta data with a meta keys of
wcfm_tracking_code
AND
wcfm_tracking_url
i found this hook elesewhere that allows me to fire a set of things to happen, once the tracking has been submitted into the system
“wcfm_after_order_mark_shipped” (Parameters -> $order_id, $order_item_id, $tracking_code, $tracking_url)
so now i want to take the above 2 order meta datas and push them into another plugin called AST
They code they provide to push data into thier system is:
<?php if ( class_exists( 'WC_Advanced_Shipment_Tracking_Actions' ) ) {
$order_id = '123'; //Replace with your order id
$tracking_provider = 'USPS'; //Replace with your shipping provider
$tracking_number = '123123'; //Replace with your tracking number
$date_shipped = '2020-06-22'; ////Replace with your shipped date
$status_shipped = 1; // 0=no,1=shipped,2=partial shipped(if partial shipped order status is enabled)
$sku = 't-shirt,blue-jeans'; //the line item (product) SKU
$qty = '1,1'; //the line item (product) quantity
if ( function_exists( 'ast_insert_tracking_number' ) ) {
ast_insert_tracking_number( $order_id, $tracking_number, $tracking_provider, $date_shipped, $status_shipped, $sku, $qty );
}
}
SO using both codes provided, can anyone show me how i can take the metadata input from WCFM and push it into AST?
Ive hired someone on upwork, and they cant even figure it out, but it seems so straightforward.
This is the code we have,it pushes the data in but it comes in looking like this
Instead of this like it should
add_action( 'wcfm_after_order_mark_shipped', 'testwr', 99, 6 );
function testwr( $order_id, $order_item_id, $tracking_code, $tracking_url, $product_id, $wcfm_tracking_data ) {
$order = wc_get_order( $order_id );
$data['order_id'] = $order_id;
$data['tracking_provider'] = $tracking_url;
$data['wcfm_tracking_code'] = $wcfm_tracking_data['wcfm_tracking_code'];
$data['date_shipped'] = $order->order_date;
$data['status_shipped'] = 1;
extract($data);
foreach ($order->get_items() as $item) {
$product = wc_get_product($item->get_product_id());
$item_quantity[] = $item->get_quantity();
$item_sku[] = $product->get_sku();
}
if( $item_sku ) {
$data['sku'] = implode( ",",$item_sku );
}
$tracking_url = $tracking_url . "/" . $tracking_code;
$url = "<a href='".$tracking_url."'>test</a>";
$data['qty'] = implode( ",",$item_quantity );
$test = ast_insert_tracking_number( $order_id, $tracking_url, $tracking_url, $date_shipped, $status_shipped, $sku, $qty);
var_dump($test);
print_r($tracking_code);
print_r($data);
print_r($wcfm_tracking_data);
var_dump($order_item_id);
//ast_insert_tracking_number
die();
}
Kudos to anyone willing to give this a try and some time
Regards
I need to insert in a custom plugin the code to get the name of the discount codes I enter in the settings, the discount obtained with the code and the total.
Based on Get coupon data from WooCommerce orders answer code, I have inserted the following code:
$order = wc_get_order( $order_id );
// GET THE ORDER COUPON ITEMS
$order_items = $order->get_items('coupon');
// print_r($order_items); // For testing
// LOOP THROUGH ORDER COUPON ITEMS
foreach( $order_items as $item_id => $item ){
// Retrieving the coupon ID reference
$coupon_post_obj = get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' );
$coupon_id = $coupon_post_obj->ID;
// Get an instance of WC_Coupon object (necessary to use WC_Coupon methods)
$coupon = new WC_Coupon($coupon_id);
## Filtering with your coupon custom types
if( $coupon->is_type( 'fixed' ) || $coupon->is_type( 'percent' ) || $coupon->is_type( 'fixed_product' ) ){
// Get the Coupon discount amounts in the order
$order_discount_amount = wc_get_order_item_meta( $item_id, 'discount_amount', true );
$order_discount_tax_amount = wc_get_order_item_meta( $item_id, 'discount_amount_tax', true );
## Or get the coupon amount object
$coupons_amount = $coupons->get_amount();
}
}
$confirmation = str_ireplace("{order_items}", $order_items, $confirmation);
But the only information it brings back to me, when I do an echo is the word "array".
What am I doing wrong? Any help?
Try the following instead, that will add a coma separated string of applied coupon codes with their respective discount amount:
$order = wc_get_order( $order_id ); // If needed
$output = array(); // Initializing
// loop through order items "coupon"
foreach( $order->get_items('coupon') as $item_id => $item ){
// Get the coupon array data in an unprotected array
$data = $item->get_data();
// Format desired coupon data for output
$output[] = $data['code'] . ': ' . strip_tags( wc_price( $data['discount'] + $data['discount_tax'] ) );
}
$confirmation = str_ireplace("{order_items}", implode(', ', $output), $confirmation);
We add vendor information in the admin order details for each order via:
WooCommerce show vendor store-name (Dokan) in admin order details overview
Now I also want to add this information also in the order preview. I found this answer
Display custom data on Woocommerce admin order preview
We change the hook to woocommerce_admin_order_preview_end but now when we want to open the preview nothing happend.
Do we have to adjust the whole code in order that it works for the order preview or why is our approach not working?
function action_woocommerce_admin_order_vendor_data( $order ) {
// Empty array
$shop_names = array();
// Output
echo '<strong>' . __( 'Vendor(s): ', 'woocommerce' ) . '</strong>';
// Loop through order items
foreach ( $order->get_items() as $item ) {
// Get product object
$product = $item->get_product();
// Author id
$author_id = $product->post->post_author;
// Shopname
$vendor = dokan()->vendor->get( $author_id );
$shop_name = $vendor->get_shop_name();
// OR JUST USE THIS FOR SHOPNAME
// Shop name
// $shop_name = dokan()->vendor->get( $author_id )->get_shop_name();
// NOT in array
if ( ! in_array( $shop_name, $shop_names ) ) {
// Push to array
$shop_names[] = $shop_name;
// Output
echo $shop_name . ', ';
}
}
}
add_action('woocommerce_admin_order_preview_end', 'action_woocommerce_admin_order_vendor_data', 10, 1 );
As already explained in the link you referred to (By LoicTheAztec). You can't get the order object as it's a template that loads specific data via Ajax and there is no arguments for woocommerce_admin_order_preview_start action hook
Instead the filter hook woocommerce_admin_order_preview_get_order_details will allow you first to add some custom data that you will be able to call and display it via woocommerce_admin_order_preview_start or woocommerce_admin_order_preview_end action hook
So you get:
// Add custom order meta data to make it accessible in order preview template
function filter_woocommerce_admin_order_preview_get_order_details( $data, $order ) {
// Empty array
$shop_names = array();
// Loop through order items
foreach ( $order->get_items() as $item ) {
// Get product object
$product = $item->get_product();
// Author id
$author_id = $product->post->post_author;
// Shopname
$vendor = dokan()->vendor->get( $author_id );
$shop_name = $vendor->get_shop_name();
// OR JUST USE THIS FOR SHOPNAME
// Shop name
// $shop_name = dokan()->vendor->get( $author_id )->get_shop_name();
// NOT in array
if ( ! in_array( $shop_name, $shop_names ) ) {
// Push to array
$shop_names[] = $shop_name;
}
}
// NOT empty
if ( ! empty ( $shop_names ) ) {
// Store the value in the data array
$data['shop_names'] = implode( '<br>', $shop_names );
}
return $data;
}
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'filter_woocommerce_admin_order_preview_get_order_details', 10, 2 );
// Display custom values in order preview
function action_woocommerce_admin_order_preview_start() {
// Output
echo '<div class="wc-order-preview-wrapper">';
echo '<div class="wc-order-preview-shop-names" style="padding:1.5em 1.5em 0; box-sizing:border-box;">';
// H2
echo '<h2>' . __( 'Vendor(s)', 'woocommerce' ) . '</h2>';
// Call the stored value and display it
echo '{{{ data.shop_names }}}';
// Close
echo '</div></div>';
}
add_action( 'woocommerce_admin_order_preview_start', 'action_woocommerce_admin_order_preview_start', 10, 0 );
In WooCommerce, I would like to send a request to an API once the customer has successfully checked out. Its basically a website where the client is selling online courses (Like udemy).
When the customer checks out, I would like to send an API request and enroll the user for that particular course. I have tried several WooCommerce hooks but none worked for me.
This is the code that I'm using:
add_action('woocommerce_checkout_order_processed', 'enroll_student', 10, 1);
function enroll_student($order_id)
{
echo $order_id;
echo "Hooked";
}
I am writing this code for a plugin and to make it easier, I am currently using Cash on Delivery method.
Can anyone point me out where I am going wrong because when I checkout I cant see the message "hooked" that I am printing nor the $order_id?
It takes me to the success page and doesn't show these two things that I am printing.
Update 2 Only For Woocommerce 3+ (added restriction to execute the code only once)
add_action('woocommerce_thankyou', 'enroll_student', 10, 1);
function enroll_student( $order_id ) {
if ( ! $order_id )
return;
// Allow code execution only once
if( ! get_post_meta( $order_id, '_thankyou_action_done', true ) ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Get the order key
$order_key = $order->get_order_key();
// Get the order number
$order_key = $order->get_order_number();
if($order->is_paid())
$paid = __('yes');
else
$paid = __('no');
// Loop through order items
foreach ( $order->get_items() as $item_id => $item ) {
// Get the product object
$product = $item->get_product();
// Get the product Id
$product_id = $product->get_id();
// Get the product name
$product_id = $item->get_name();
}
// Output some data
echo '<p>Order ID: '. $order_id . ' — Order Status: ' . $order->get_status() . ' — Order is paid: ' . $paid . '</p>';
// Flag the action as done (to avoid repetitions on reload for example)
$order->update_meta_data( '_thankyou_action_done', true );
$order->save();
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Related thread:
Get Order items and WC_Order_Item_Product in WooCommerce 3
How to get WooCommerce order details
The code is tested and works.
Updated (to get the product Id from Orders items as asked in your comment)
May be you could use woocommerce_thankyou hook instead, that will display on order-received page your echoed code, this way:
add_action('woocommerce_thankyou', 'enroll_student', 10, 1);
function enroll_student( $order_id ) {
if ( ! $order_id )
return;
// Getting an instance of the order object
$order = wc_get_order( $order_id );
if($order->is_paid())
$paid = 'yes';
else
$paid = 'no';
// iterating through each order items (getting product ID and the product object)
// (work for simple and variable products)
foreach ( $order->get_items() as $item_id => $item ) {
if( $item['variation_id'] > 0 ){
$product_id = $item['variation_id']; // variable product
} else {
$product_id = $item['product_id']; // simple product
}
// Get the product object
$product = wc_get_product( $product_id );
}
// Ouptput some data
echo '<p>Order ID: '. $order_id . ' — Order Status: ' . $order->get_status() . ' — Order is paid: ' . $paid . '</p>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
The code is tested and works.
Then you can use all class WC_Abstract_Order methods on the $order object.
Related:
How to get WooCommerce order details
Get Order items and WC_Order_Item_Product in WooCommerce 3
How to get Customer details from Order in WooCommerce?
Rather than 'woocommerce_thankyou' hook, 'woocommerce_checkout_order_processed' hook is the relevant hook. 'woocommerce_checkout_order_processed' hook will be called only once and you will not need to add meta for each product and make additional calls to keep check for code to run only once. As, 'woocommerce_thankyou' can be called multiple times that is each time thankyou page loads.
Replace add_action('woocommerce_thankyou', 'enroll_student', 10, 1);
with
add_action('woocommerce_checkout_order_processed', 'enroll_student', 10, 1);
and remove meta code and checks. Updated code is
add_action('woocommerce_checkout_order_processed', 'enroll_student', 10, 1);
function enroll_student( $order_id ) {
// Getting an instance of the order object
$order = wc_get_order( $order_id );
if($order->is_paid())
$paid = 'yes';
else
$paid = 'no';
// iterating through each order items (getting product ID and the product object)
// (work for simple and variable products)
foreach ( $order->get_items() as $item_id => $item ) {
if( $item['variation_id'] > 0 ){
$product_id = $item['variation_id']; // variable product
} else {
$product_id = $item['product_id']; // simple product
}
// Get the product object
$product = wc_get_product( $product_id );
}
// Ouptput some data
echo '<p>Order ID: '. $order_id . ' — Order Status: ' . $order->get_status() . ' — Order is paid: ' . $paid . '</p>';
}
you can get the order items of an order by
// Getting an instance of the order object
$order = new WC_Order( $order_id );
$items = $order->get_items();
//Loop through them, you can get all the relevant data:
foreach ( $items as $item ) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
}
I am creating an online shop with WooCommerce and I'm adding a function which will update the bonus point to my database into absract-wc-payment-gateway.php.
Here is what I am doing:
Firstly, on the checkout page, the users will click the place order button and then the method will get the users bonus points and minus the bonus points with the get-total(), and then update to the database and go to the thank you page.
Then, the thank you page will get the user's bonus points from the database. And I set the bonus points value to 2000. So in this case, the bonus points should be minus by total Points($50.00)
Here is my code. It will be ran when the user clicks the place order button:
global $woocommerce;
$order = new WC_Order($order_id);
$total = $order->get_total();
$bonusPoint -= (int)$total; //minus total price and calculate the latest bonus point
$updateSql = "UPDATE userdata02 SET bonusPoint ='" .$bonusPoint. "' WHERE userID = 2147483647";
mysqli_query($link, $updateSql);// update to an int column
if(mysqli_query($link, $updateSql)) {
echo "Record updated successfully";
} else {
echo "Error update record: <>" . mysqli_error($link);
}
Call the method when the user clicks place button:
public function get_return_url( $order = null ) {
if ( $order ) {
//$message = "wrong answer";
//echo "<script type='text/javascript'>alert('$message');</script>";
$return_url = $order->get_checkout_order_received_url();
} else {
$return_url = wc_get_endpoint_url( 'order-received', '', wc_get_page_permalink( 'checkout' ) );
}
if ( is_ssl() || get_option('woocommerce_force_ssl_checkout') == 'yes' ) {
$return_url = str_replace( 'http:', 'https:', $return_url );
}
self::reducePoints(); //Call reducePoints();
return apply_filters( 'woocommerce_get_return_url', $return_url, $order );
}
The source code: reducePoints() lines 89 from abstract-WC-Payment-Gateway.php
The get_total() doesn't work and it returns zero.
What I am doing wrong?
You need to create an object for $order to use it with get_total(). Try this:
global $woocommerce;
$order = new WC_Order($order_id);
$total = $order->get_total(); //Get the total price of the order.
$bonusPoints -= (int)$total; //calculate the new bonusPoints
Update1: This is just solving the internal data error. We need to get the $order_id to get it work…
Note: You can remove global $woocommerce;before $order = new WC_Order($order_id); because is already included in public function reducePoints( ){
Update2 - The good track:
Remove my code:
global $woocommerce;
$order = new WC_Order($order_id);
Then at line 89 of your code just add $order in:
public function reducePoints( $order ){
global $woocommerce;
// ...
Really happy that this works… It was a long search...