Add custom script in woocommerce refund hook - php

I'm trying to execute a tracking script every time a refund gets processed in woocommerce but for some reason it's not working.
add_action( 'woocommerce_order_refunded', 'custom_order_refunded', 10, 2 );
function custom_order_refunded( $order_id, $refund_id ) {
if ( $order_id > 0 ) {
$order = wc_get_order( $order_id );
$order_number = $order->get_id();?>
<script>
gtag('event', 'refund', { "transaction_id": <?php echo $order_number;?> });
</script>
<?
}
}
I tried executing it with a static value instead of the $order_number variable to see if it was running and nothing... I'm lost

Might be a little late to answer this question, but...
You are adding javascript to an action that is only executed in the back-end of PHP and not on a page like the thankyou page.
For Google Analytics to work you need to add your script to a page where the customer can refund their order on the front-end. So for example on their account page.
Here is a nice explanation of creating a refund page in WooCommerce on which you can add your Google Analytics script: https://jilt.com/blog/add-refund-requests-woocommerce-customers/

Related

Converting the order from processing to complete in WooCommerce (WordPress)

I used artificial intelligence for the first time
But the code you told me is not working
To convert veins automatically from treatment to complete after 30 seconds
Only on virtual products
There are two specific payment methods
But it doesn't work
// Add a 30 second delay for virtual products
add_filter( 'woocommerce_payment_complete_order_status', 'wc_delay_virtual_order', 10, 2 );
function wc_delay_virtual_order( $order_status, $order ) {
if ( $order->has_downloadable_item() && ! $order->has_status( 'completed' ) ) {
return 'on-hold'; // change to any other status you wish to use.
}
return $order_status;
}
add_action( 'woocommerce_thankyou', 'wc_delay_virtual', 30 );
function wc_delay_virtual( $orderid ) {
// Get the order object and check for downloadable items.
$order = new WCOrder($orderid);
if ( $order->hasDownloadableItem() ) {
// Set a 30 second delay for virtual products.
sleep(30);
// Update the order status to complete.
$order->updateStatus('completed');
}
}
// Add a custom payment gateway for MobileWallet and Reference Code payments.
add-filter('woocommerce-payment-gateways','wc-add-mobilewallet-referencecode');
function wc-add-mobilewallet-referencecode($methods){
$methods[] = 'WCMobileWallet'; // MobileWallet payment gateway class name.
$methods[] = 'WCReferenceCode'; // Reference Code payment gateway class name.
return $methods;
}
I tried to add this code inside plugin and inside function.php
I am waiting for your response to solve my problem, thank you
The part of your code posted below has an issue. you cant use - in between function name like wc-add-mobilewallet-referencecode instead it should be wc_add_mobilewallet_referencecode using and underscore "_"
Your correct code should look so:
add_filter('woocommerce-payment-gateways','wc_add_mobilewallet_referencecode');
function wc_add_mobilewallet_referencecode($methods){
$methods[] = 'WCMobileWallet'; // MobileWallet payment gateway class name.
$methods[] = 'WCReferenceCode'; // Reference Code payment gateway class name.
return $methods;
}
And since you just need to change order status to complete on downloadable product, just need the code below:
add_filter( 'woocommerce_payment_complete_order_status', 'wc_delay_virtual_order', 10, 2 );
function wc_delay_virtual_order( $order_status, $order ) {
if ( $order->has_downloadable_item() && ! $order->has_status( 'completed' ) ) {
sleep(30);
return 'completed'; //Here should be complete.
}
return $order_status;
}
The requirement doesn't seem to work for the following reasons:
Payment gateways will have their configuration where after each successful order, the status will be updated based on the configuration.
Making the customer wait 30 seconds on the browser is not recommended.
Even if you forcefully update the order status on the thankyou page hook, what will happen next is if the woocommerce or any third-party plugin or payment plugin has different order statuses, those will be updated as soon as your update is done.
Nevertheless, there are three possible ways for your requirement.
Search for payment configuration and update the order completion status there. For example, in the case of Novalnet Payment Gateway, I use their configuration, so I need not do anything here.
On the WooCommerce shop backend, you have the settings you can use it. Refer https://woocommerce.com/document/woocommerce-order-status-control/
Based on your business logic, you can set up a cron to update all the virtual orders that aren't on complete order status. Refer https://developer.wordpress.org/plugins/cron/

Change Woocommerce checkout end points to show order summary details

I have a woocommerce website & using PayU payment system. As of now when customer order fails, then the redirection is happening to order-pay endpoint & when order is success, page is redirecting to order-received endpoint. I need customer to redirect to a specific custom url when order fails and for success order, instead of redirecting to order-received endpoint, I would like to show the order summary details & prevent user from redirecting to home page.
I tried the below in functions.php
add_action( 'woocommerce_thankyou', 'test_func');
function test_func( $order_id ) {
$order = wc_get_order( $order_id );
$url1 = 'https://yoursite.com/custom-url-1';
$url2 = 'https://yoursite.com/custom-url-2';
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url1 );
exit;
} else {
wp_safe_redirect( $url2 );
exit;
}
}
But still it is redirecting to the checkout end points mentioned.
I know that it is taking from the woocommerce checkout endpoints mentioned in the Advance Section, but can somebody please help me to find a workaround for this?
Any help would be really appreciated.
Thanks in Advance.
I have prepared a solution for your problem. I have tested your code and it looks like woocommerce has changed something or I don't know and this kind of code is not working anymore. But no worries. I have searched over the internet and found a good solution for you which I have prepared and tested on my staging website and it works great.
You need to use template_redirect and set it for checkout endpoint url (your case - order-received). Then you need to do the rest with the right functionality to make it work as you expect. Put my code bellow into the functions.php file of your theme and your problem should be solved. Do not forget to change endpoint url with the endpoint url of your website (order-received) and then change the url for failed order status (google.com) and other statuses (yahoo.com)
add_action( 'template_redirect', 'wc_thank_you_redirect' );
function wc_thank_you_redirect(){
if( isset( $_GET['key'] ) && is_wc_endpoint_url( 'order-received' ) ) { //change order-received to your endpoint if you will change it in the future
$order_id = wc_get_order_id_by_order_key( $_GET['key'] );
if ( ! empty( $order_id ) ) {
$order = wc_get_order( $order_id );
$order_status = $order->get_status();
if ('failed' == $order_status ) { //failed order status
wp_redirect( 'https://google.com' ); //change url here
exit;
} else {
wp_redirect( 'https://yahoo.com' ); //change url here for other statuses redirect
exit;
}
}
}
}
To do this with order-pay you could easily modify my function and change your endpoint url to order-pay and remove else from the function. To display order summary you need to set template for your new URL. Maybe it is better to redirect only failed orders and modify existing woocommerce template for your thank you page.

Does the "woocommerce_thankyou" action hook fire on failed orders?

My affiliate script tracks a conversion after an order is placed. it runs inside the woocommerce_thankyou action hook:
function affiliate_tracking_code( $order_id ) {
// get the order info for the script
?>
<script>
// affiliate script here
</script>
<?php
}
add_action( 'woocommerce_thankyou', 'affiliate_tracking_code', 10, 1 );
I do not want this script to fire if the order has failed or is pending. Only if it is successful. I can not find in the documentation whether or not the woocommerce_thankyou action hook fires for anything but successful orders.
If it does then what is the best way to make sure that my script only tracks conversions for successful orders and not failed ones.?
One way I have tested is to wrap my script in an if and check if ( $order->get_status() == 'processing' ) : // run the script however I am not sure if there are hidden loopholes.
Yes, it will fire or failed orders as well.
add_action('woocommerce_before_thankyou', 'woocommerce_before_thankyou_failed_order')
function woocommerce_before_thankyou_failed_order( $order_id ) {
$order = wc_get_order( $order_id );
if ( !$order->has_status( 'failed' ) ) {
// if order not failed
}
}
See the hook under wp-content/plugins/woocommerce/templates/checkout/thankyou.php

Stay on same page and not empty the cart session during Woocomerce checkout

I am in the middle of creating an additional plugin which is a custom payment gateway using the Woocommerce plugin and a child theme to style it.
This is working and I see the payment form correctly and items which is great.
The issue I have is with the payment process option.
The checkout page has an i-frame to the payment solution and is supposed to show only when an order is created and an ID is present. And to make sure we have all the persons details etc.
However the process payment take you to the thanks you page instead.
It also dumps the cart session.
even if I redirect the URL back to the cart page by playing around with it, it still kills the cart.
This would be fine in normal circumstances as I'd expect it to go to a payment page, checkout and be done. But I do not want to do this because this site has to mirror one that is currently live and how that works.
The function in my extended class is this.
public function process_payment( $order_id ) {
global $woocommerce;
#$order = wc_create_order();
///
$order = new WC_Order( $order_id );
// Mark as on-hold (we're awaiting the cheque)
$order->update_status('on-hold', __( 'Awaiting Confirmation of Funds', 'woocommerce' ));
// Reduce stock levels
///$order->reduce_order_stock();
// Remove cart
//$woocommerce->cart->empty_cart();
// Return thankyou redirect
return array(
'refresh' => true,
'reload' => false,
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
///return $order_id;
}
As you can see I commented out the bit where to empty the cart and the also the endpoint brings in the thank you template instead of just staying on the same page.
So far I have tried:
Replicating the code on my checkout to the thank you page and that
results in an undefined checkout, because the process removes it by
then
Changing the end-point reference to the same as checkout
Creating another page and putting the same shortcode on it
Nothing works, and I have been through the plugin and can see a few things I could do.
Copy the process_payment function into my extended class and
effectively re-write it
or
Find a filter similar to below that could do what I need
add_action( 'woocommerce_thankyou', function(){
global $woocommerce;
$order = new WC_Order();
if ( $order->status != 'failed' ) {
wp_redirect( home_url() ); exit; // or whatever url you want
}
});
What I need is it to stay on the same page (refresh) the same way it does when it checks the details to refresh the totals.
Create an order with those current details in and return an order number
Will not kill the cart session at that point, so if I was to refresh the browser for arguments sake it would stay live. (I will work out a way to kill the cart when the person navigates away and a unique session has been created at that point).
Its just this bit I have been fighting with for the past couple of days and not sure the best way.
Any help or pointers would be greatly appreciated.
thanks
Andi
Ok figured this one out.
There is a header action that clears the cart.
We needed to add some more statuses to the array so that it ignores it.
1st remove the action and then add your own method.
function st_wc_clear_cart_after_payment( $methods ) {
global $wp, $woocommerce;
if ( ! empty( $wp->query_vars['order-received'] ) ) {
$order_id = absint( $wp->query_vars['order-received'] );
if ( isset( $_GET['key'] ) )
$order_key = $_GET['key'];
else
$order_key = '';
if ( $order_id > 0 ) {
$order = wc_get_order( $order_id );
if ( $order->order_key == $order_key ) {
WC()->cart->empty_cart();
}
}
}
if ( WC()->session->order_awaiting_payment > 0 ) {
$order = wc_get_order( WC()->session->order_awaiting_payment );
if ( $order->id > 0 ) {
// If the order has not failed, or is not pending, the order must have gone through
if ( ! $order->has_status( array( 'failed', 'pending','pending-st-cleared-funds','on-hold' ) ) ) { ///// <- add your custom status here....
WC()->cart->empty_cart();
}
}
}
}
function override_wc_clear_cart_after_payment() {
remove_filter('get_header', 'wc_clear_cart_after_payment' );
add_action('get_header', 'st_wc_clear_cart_after_payment' );
}
add_action('init', 'override_wc_clear_cart_after_payment');

Woocommerce: custom price based on user input

I did not want to post here but I could not find the answer I was looking for and I do not have enough reputation to comment on other VERY SIMILAR questions to get my exact answer.
I found an almost perfect answer from this post: WooCommerce: Add product to cart with price override?
using the code:
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price');
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custome price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
and it works great...if you set a hard coded custom price.
My question is: How can I set a custom price based on user input?
I have tried every way I can think of to pass information (I even tried using cookies, globals, sessions) and none of them worked how I wanted and all of them were, at BEST, hacks.
The specific product in question is a donation and the customer wants the user to be able to set the donation price (rather than just creating a variable product with set price points).
On the donation page when the user submits the donation form I am adding the donation product to the cart like so:
$donation_success = $woocommerce->cart->add_to_cart($donation_id);
My donation product has a set price of 0.00 so when it is added to the cart it has a price of 0.00 (I don't know if the price is set at this point or later)
I have tried passing in information at this point using the last variable in the add_to_cart method which accepts an array of arguments but I couldn't seem to get that to work either.
I am sure the answer is simple but I have been trying for hours to do this right and I cannot get it to work. I am out of ideas.
The actual code I am using at the moment is slightly different than was suggested by the answerer of the above post but works basically the same:
add_action( 'woocommerce_before_calculate_totals', 'woo_add_donation');
function woo_add_donation() {
global $woocommerce;
$donation = 10;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if($cart_item['data']->id == 358 || $cart_item['data']->id == 360){
$cart_item['data']->set_price($donation);
}
}
}
Thanks in advance for any helpful advice!
I found a solution which is not elegant but works for my purposes.
I was trying to use cookies before but I didn't set the cookie path so it was only available to the page it was set on.
I am now setting a cookie with the donation price:
setcookie("donation", $_GET['donation'], 0, "/");
Then I am setting the price like so:
add_action( 'woocommerce_before_calculate_totals', 'woo_add_donation');
function woo_add_donation() {
global $woocommerce;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if($cart_item['data']->id == 358 && ! empty($_COOKIE['donation'])){
$cart_item['data']->set_price($_COOKIE['donation']);
}
}
}
I have been looking for exactly the same thing. I found this WooCommerce plugin (not free) for this
name your price plugin
Initially I wasn't sure what search terms to use to find plugins like this but it looks like "WooCommerce name your price" brings up links to other sources of similar plugins.
[this is a comment] Where do you set the cookie? My first guess is that the refreshes in the same page, using the GET method, and provides a PHP code-block with the $_GET['donation'] to set the cookie with.
And then, once the cookie is set, you redirect the page to Woocommerce Cart page to continue the shopping process. If you're doing it easier way, please let me know. Thanks.
Sorry, I couldn't post this as a comment to the selected answer due to the lack of points.
This code will create order with custom price:
$product = wc_get_product($product_id);
$order = wc_create_order();
try {
$order->add_product($product);
//$order->set_customer_id($user->ID);
$order->set_billing_email($customer_email);
} catch (WC_Data_Exception $e) {
wp_send_json_error("Failed to create order");
}
$order->calculate_totals();
try {
$order->set_total($custom_price); // $custom_price should be float value
} catch (WC_Data_Exception $e) {
wp_send_json_error("Failed to change order details");
}
$order->save();
$order->update_status( 'completed' );

Categories