WooCommerce - Do not authorize or capture on new order - wordpress

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.

Related

Woocommerce - let customer pay for order when order column value is late payment

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

Creating WooCommerce placeholder for Emails sent

My client, a courier company, is using delivery software that is able to track with both WooCommerce order no. and ID, which means it requires both order no. and ID ("wc_order_abcdefg") to work, I believe this falls in the phpmyadmin database of post_password column.
Full tracking ID goes like: wc_order_abcdefg.66
So in the WooCommerce email settings, it only has {order_number}. How do I create one for {order_id}?
It looks like, your shipment tracking number is {order_key}.{order_number}.
Once you get hold of the order object, you can get its key simply with: $order->get_order_key().
{order_key} is not available as an email placeholder. So in order to include it in the email sent to the customer, you have different options depending on where you want it to be displayed. For example:
You could include the tracking number in the body of the email. In this case, you can override one of the WooCommerce email templates (e.g. email-order-details.php). See the WooCommerce docs for more info on how to override templates.
You could include the tracking number in the subject of the email. In this case, you can use the woocommerce_email_subject_customer_completed_order filter. E.g. (this snippet should be added to your functions.php):
add_filter( 'woocommerce_email_subject_customer_completed_order', 'add_tracking_number_to_email_subject', 1, 2 );
function add_tracking_number_to_email_subject( $subject, $order ) {
return sprintf( 'Thank you for your order! Your shipment tracking number is: %s.%s', $order->get_order_key(), $order->get_id() );
}

WooCommerce If order status is in processing then products in that specific order will be hide from the shop

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

WooCommerce Order Status & reduce Stock

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.

WordPress custom order field

I have a requirement where, I have a list of pin codes which are serviceable by different courier partners. What I want is, Once someone books a order, I want to first check the pin code and accordingly add the respective Courier partner name in the order meta field. For that I have created a custom checkout field. And once someone submits the address I can check through the pincodes and add respective courier.
But now after this, I also have a list of awb numbers given by respective courier partners. And I would also like to add respective courier awb number to the order and also send the same in the order recived email to the customer.
I am looking out, is there any action hook from Woocommerce which allows me to check the pincode and accordingly add the AWB number and send the same to customer/admin invoice. The only twist is, I want to add a function of assigning awb number after the order is marked as processing and before email-invoice is sent to the customer.
Is there any action hook which allows me to get order detail and add awb number after order is set as processing and before email-invoice is sent to the customer?
I think you should try woocommerce_order_status_processing with a high priority.
add_action('woocommerce_order_status_processing', 'your_fn', 0);
function your_fn( $order_id )
{
$order = wc_get_order( $order_id );
// ...
}

Resources