i write a payment gateway for woocommerce and i change the order status after payment is success. If status change to processing i reduce the order stock. Everything goes well.
By the way in the plugin settings the admin can change the status for success payments... processing or completed (for physical or virtual products)
function setOrderPaid($OrderID, $status){
$order = new WC_Order($OrderID);
if(!$order){
return false;
}else{
$order->update_status($status);
if($status=="processing") $order->reduce_order_stock();
WC()->cart->empty_cart();
return true;
}
}
After a success payment with changing the order status to processing, i go and change the status manual to completed (backoffice woocommerce->orders) and the system reduce the order stock again.
I have to reduce the stock after the success payment, to prevent problems with other orders on the same product. How can i fix this order reduce problem?
I find this Woocommerce set_status. Maybe this helps... bool $manual_update is this a manual order status change? So the system knows that stock is already reduced???
This has to do with what are considered as paid order statuses in woocommerce. You can customize the list of paid order statuses. The above function will trigger each time the order enters any of those paid order statuses.
Now, your first instinct would be to truncate the paid status list. This may be advisable in a few cases, but in this particular case the instinct is wrong.
What you need to do instead is check the current order status. If the status is not a paid status, only then you should trigger the reduce stock function. This assumes that the order won't jump between a paid and unpaid status repeatedly.
Related
I have a difficult problem which i'm trying to solve for some time now.. We are using plugin called admin customer order fields, which let's to create a new column for order. For this part I have made second order status which is called "Payment status" - it can be not paid, paid, or late payment. And these statuses work depending on payment type. For example if customer pays via bank, status becomes "pending" and second column becomes "not paid". But the problem is that we are using Partial Payments plugin, which let's customer to pay for order after some time, for example 30 days. But during these 30 days the product will be shipped to his address and he can pay for order later. The logic is like this:
Customer orders product with option to pay after 30 days.
Order status becomes processing / payment status becomes not paid
And administrator can change the order status - if he ships it it becomes completed. So the statuses would be:
Order status - completed / payment status - not paid. And it should still let user to pay for the order even if order status is completed
Is it possible to make, that it customer could pay for order depending on payment status, not default order statuses? As the best what I have found is this hook:
woocommerce_valid_order_statuses_for_payment
But you can only make that the order statuses could be valid for payments, but I need to make it on payment status which is made with custom plugin.
Attaching screenshot to be clear as possible.
The idea is to make that if payment status is "APMOKĖTA" you couldn't pay anymore, and if it's "ATIDĖTAS MOKĖJIMAS" you could pay for your order.
You can try using the woocommerce_order_needs_payment hook like this
add_filter( 'woocommerce_order_needs_payment', 'custom_needs_payment', 10, 2 );
function custom_needs_payment( $needs_payment, $order ){
$payment_status = get_post_meta( $order->get_id(), 'payment_status', true );
if($payment_status == 'APMOKĖTA'){
return false;
}
return true;
}
You might need to change the names of the post meta to whatever it's named on your end
I have a shopping website with limited products. I'm looking for a solution in which, if Order status is "Processing", then Products in that specific Order remains hide from the Shop and Search result, unless Order status changed to Completed. (which means product is back in shop for purchase).
Moreover, all products will be sold individually.
You can use woocommerce_order_status_changed hooks. Using these hook you will get 3 params called $old_status, $new_status and $order_id.
Then you just check is $new_status is processing or not. if processing then gets the order using $order_id and then create a loop for line_items. For each line item, you will get product_id and check the product is publish or not. If Publish then just make the product in draft status, if not then just continue the loop.
Like the same procedure, you can also check for Completed status. If the status is completed just loop through the order items and make each product draft to publish.
Hope you understand. If not, then let me know. I will share the code snippet
Is there a way to set all new orders to "pending payment" (or some other status, maybe custom status?) without it auto changing to "on hold" or "processing"? What I'm wanting to do is basically have all new orders not only not capture CC payment (using Stripe), but also wanting it to not authorize. So, what I'm wanting to do is:
Submitted
"Pending Payment" (new order created, but not authorized or captured. Order status stay here until manual advance. I put in quotes because if this status HAS to be kept as-is with it auto connecting to the gateway, then maybe a custom status goes in between a submitted new order and Pending Payment...)
Processing (authorize and capture payment)
Completed
The whole reason for this is because my products are large and require us to box/weigh and manually get shipping prices (from various freight companies, etc). As it is now, new orders will auto authorize an amount and then put on hold. The problem is, we need to be able to manually go in and adjust shipping prices once we have a price and then add that to the order. There is no way to "re-authorize" for a higher amount (since we added shipping). So either we add a set flat rate amount per item for shipping (which would have to be more than the actual shipping rates could be) then come in and manually lower the shipping rate before capturing payment, OR we somehow don't let the new order to auto send to authorize.
Thanks for any help!
You can use this function to set the status of all upcoming new orders to 'Pending payment' regardless of any original status. Please note that the default order status is set by the payment method and you can't override it. The 'Pending payment' status will be set next to the default order status.
Add this to your theme's 'functions.php'.
add_action( 'woocommerce_thankyou', 'change_new_order_status', 10, 1 );
function change_new_order_status( $order_id ){
if( ! $order_id ) return;
$order = wc_get_order( $order_id );
$order->update_status( 'pending' ); //set status to Pending payment
}
There should be an option in Stripe payment method plugin to just authorize and not capture. You can enable that option but note that you cannot disable authorize.
I have an online store where customers place an order and it is done with payment as COD. It is integrated with our warehouse management where it will export all the orders at the end of the day to the system from the site.
The status of the orders places are processing.
I am trying to make a php cron job where the order status of all these order set as completed when the list of orders are exported.
I have looked at various solutions and all change the order status at the time of placing the order while i want it later, once the data is exported.
If somebody can help me with the php function that sets all the order in the woocommerce to "complete" at some trigger, I would be really grateful.
In your cron function you may have a loop to get the order ID that needs to be exported, so just pass the Order ID to the given function it'll update the Order Status to wc-complete, you can also pass an order note if you need.
function wh_mark_order_as_omplete($order_id, $note = '')
{
//this check is option if you do not need this you can remove it.
//for COD order only
if ('cod' != get_post_meta($order_id, '_payment_method', true))
return;
$order = wc_get_order($order_id);
if (empty($note)):
$order->update_status('completed');
else:
$order->update_status('completed', $note);
endif;
}
Hope this helps!
Using three plugins:
WooCommerce
Subscriptio
WooEvents
I have created a product which allows for a customer to pay for an event over five instalments.
A customer has placed an order and made their first of the five payments via PayPal and has then contacted me to advise they have booked the wrong event.
The correct event is exactly the same except the dates are a month sooner.
I have added the following snippet to be able to edit 'processing' orders:
add_filter( 'wc_order_is_editable', 'wc_make_processing_orders_editable', 10, 2 );
function wc_make_processing_orders_editable( $is_editable, $order ) {
if ( $order->get_status() == 'processing' ) {
$is_editable = true;
}
return $is_editable;
}
From the order screen within the back-end of WordPress I can see that the the order can be edit by way of removing the product from the order or editing the meta data and cost.
The correct product that should have been ordered has a different product/variation ID.
My question is simply:
Should I remove the incorrectly ordered product from the order and add the correct product (both have the same properties with the exception of the courses dates); or
Should I just change the meta data and increase the stock levels for the incorrectly product back to X and reduce the stock level for the correct product?
Your second option is much better. Change the meta from database if its accessible and then manage the stock accordingly.
I have not yet done this, but according to this exchange ...
How can I add a product to an existing and paid Woocommerce order?
... you can set the order status to "On Hold" and make changes to the order itself. I presume you would then return the status to "Processing".
I would expect that if the application permits those changes, then it would be doing the background meta changes to inventory levels, etc., and spare you the problem of doing so (and the potential errors that may occur when messing with the data tables outside of the application).
Like I said, I haven't done this. But it might be worthwhile doing a little test to make sure it works as it seems to be described in the answer to the other question.
J