• Resolved bluantinoo

    (@bluantinoo)


    is it possibile to setup different “hold stock minutes” for different payment methods?

    is there some hook for that?

Viewing 8 replies - 1 through 8 (of 8 total)
  • Hi @bluantinoo

    Try using the below code snippet in the active theme functions.php file.

    add_action( 'woocommerce_checkout_order_created', 'wc_reserve_stock_for_specific_payment_gateway', 5 );
    function wc_reserve_stock_for_specific_payment_gateway( $order ) {
    // Define the specific payment ID(s)
    $target_payment_ids = array('cod', 'bacs');
    // Define the time in minutes to hold stock
    $stock_hold_minutes = 150;

    if ( in_array( $order->get_payment_method(), $target_payment_ids ) ) {
    // Remove the default functionality to hold stock for 60 minutes
    remove_action( 'woocommerce_checkout_order_created', 'wc_reserve_stock_for_order' );

    if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) {
    return;
    }

    $order = $order instanceof WC_Order ? $order : wc_get_order( $order );

    if ( is_object( $order ) ) {
    // Restore the functionality with a custom delay to hold the stock
    ( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->reserve_stock_for_order( $order, $stock_hold_minutes );
    }
    }
    }
    Thread Starter bluantinoo

    (@bluantinoo)

    that’s brilliant!

    Many thanks @mujuonly

    I had no clue of such a filter

    Thread Starter bluantinoo

    (@bluantinoo)

    Actually even if the reserve stock expires is set accordingly to the filter,
    The order gets cancelled anyway after the “Hold stock (minutes)” set in Woocomerce Inventory Settings.

    I tried to set WC Hold stock to 5 minutes, and put $stock_hold_minutes = 2880 in filter for an asyncronous payment method that may need up to 48 hours.

    In the wp_wc_reserved_stock the expires time is correct.
    But order gets cancelled after 5 minutes.

    I think we should look to ‘woocommerce_cancel_unpaid_order’ hook as well

    maybe we’re missing something?

    • This reply was modified 2 months, 1 week ago by bluantinoo.
    Plugin Contributor Nadir Seghir a11n

    (@assassinateur)

    Which Checkout are you using for testing this?

    For Store API/Checkout block, stock reserve happens before we reach the payment method, so you can hook into woocommerce_store_api_checkout_update_order_from_request and change the value of woocommerce_order_hold_stock_minutes

    Code example (need a different top hook for old Checkout):

    add_action('woocommerce_store_api_checkout_update_order_from_request', function($order, $request) {
    add_filter( 'woocommerce_order_hold_stock_minutes', function( $minutes, $order ) use ($request) {
    $payment_method = $request->get_param('payment_method');
    if ($payment_method === 'cod') {
    return 37;
    }
    return $minutes;
    }, 10, 2 );
    }, 10, 2);
    Thread Starter bluantinoo

    (@bluantinoo)

    @assassinateur not sure 100% what you’re asking, but I’m speaking about standard checkout, the one usually at shop.com/checkout url.

    Anyway, I managed to solve the issue adding to the @mujuonly solution another hook to woocommerce_cancel_unpaid_order taking care of checking if the woocommerce_cancel_unpaid_orders cron is allowed to delete the order or not.

    Just to be clear for anyone could use this, I post the entire code:

    Just

    /* this set a longer hold stock in minutes for specific payment methods orders */
    add_action( 'woocommerce_checkout_order_created', 'ixxx_reserve_stock_for_specific_payment_gateway', 5 );
    function xxx_reserve_stock_for_specific_payment_gateway( $order ) {
    // Define the specific payment ID(s)
    $target_payment_ids = array('komoju_konbini', 'omise_konbini');
    // Define the time in minutes to hold stock
    $stock_hold_minutes = 10;

    if ( in_array( $order->get_payment_method(), $target_payment_ids ) ) {
    // Remove the default functionality to hold stock for 60 minutes
    remove_action( 'woocommerce_checkout_order_created', 'wc_reserve_stock_for_order' );

    if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) {
    return;
    }

    $order = $order instanceof WC_Order ? $order : wc_get_order( $order );

    if ( is_object( $order ) ) {
    // Restore the functionality with a custom delay to hold the stock
    ( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->reserve_stock_for_order( $order, $stock_hold_minutes );
    }
    }
    }


    /* This avoid that the cron job change order status to cancelled untill it's time */
    add_filter( 'woocommerce_cancel_unpaid_order', 'xxx_check_if_order_has_to_be_canceled', 10, 2 );
    function xxx_check_if_order_has_to_be_canceled( $created_via, $order ){

    if ( 'checkout' != $created_via ){
    return false;
    }

    // Define the specific payment ID(s)
    $target_payment_ids = array('komoju_konbini', 'omise_konbini');
    // define intervall
    $stock_hold_minutes = 2880; // 48 hours

    if ( in_array( $order->get_payment_method(), $target_payment_ids ) ) {

    $order_date_created = $order->get_date_created();
    $current_date = current_datetime();
    $deadline_date = $order_date_created->modify( '+' . $stock_hold_minutes . ' minutes' )->format('Y-m-d H:i:s');

    if ( $current_date->format('Y-m-d H:i:s') < $deadline_date ){
    return false;
    } else {
    return true;
    }
    } else {
    // for all other payment methods
    return true;
    }
    }

    Anyone welcome in improving it.

    Plugin Contributor Nadir Seghir a11n

    (@assassinateur)

    Glad you got that to work, just noting that the above logic will only work for orders created via the shortcode Checkout.

    Starting November last year, the new default Checkout has changed to Checkout block.

    Thread Starter bluantinoo

    (@bluantinoo)

    thanks for your advice @assassinateur

    I’m actually using Elementor pro so I guess it is using the shortcode version.

    which other checkout types exist?

    Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @bluantinoo

    WooCommerce primarily has two types of checkout: The Checkout Block and Shortcode. More info can be found here:

    I hope this clarifies your concern. If you have any other questions, feel free to ask.

Viewing 8 replies - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.