I have searched high and low but with no resolve. So we developed a custom "bacs" type gateway for our site. Here in Brazil you can pay via a bank billet. The billet usually has an expiration date for payment (around 7 days). So when a person goes through check-out the gateway sends the billet to our customer and he has to pay until the expiring date.

Since this is an offline payment, the order status goes to "on-hold". What I have been looking for is a way to specify that on-hold orders get canceled automatically after 8 days (since there's a 7 day limit).

If seen some code where people hook the pending order cancelation time-out but it seems like that wouldn't be the case. Any ideias?

  • 1
    Set up a cron that checks the date and updates the status. Set it up as a true cron instead of just the default WP implementation where it only triggers when people visit the site. – TurtleTread Feb 21 '18 at 20:16

So I got this working. I created a plugin and with a few hours running around several forums and a lot of help I got to something very interesting.

So call in orders, bacs, and all of the other types of offline orders are put on hold until payment is verified. The post_status is 'wc-on-hold'. What we needed was to exclude our rule to Checks, since we don't need to deal with expiration dates. This is the code we got to:

// To change the amount of days just change '-7 days' to your liking
function get_unpaid_submitted() {        
            global $wpdb;

            $unpaid_submitted = $wpdb->get_col( $wpdb->prepare( "
                    SELECT posts.ID
                    FROM {$wpdb->posts} AS posts
                    WHERE posts.post_status = 'wc-on-hold'
                    AND posts.post_date < %s
            ", date( 'Y-m-d H:i:s', strtotime('-7 days') ) ) );

            return $unpaid_submitted;

    // This excludes check payment type.
    function wc_cancel_unpaid_submitted() {        
            $unpaid_submit = get_unpaid_submitted();

            if ( $unpaid_submit ) {                
                    foreach ( $unpaid_submit as $unpaid_order ) {                        
                            $order = wc_get_order( $unpaid_order );
                            $cancel_order = True;

                            foreach  ( $order->get_items() as $item_key => $item_values) {                                
                                    $manage_stock = get_post_meta( $item_values['variation_id'], '_manage_stock', true );
                                    if ( $manage_stock == "no" ) {                                        
                                            $payment_method = $order->get_payment_method();                                        
                                            if ( $payment_method == "cheque" ) {
                                                    $cancel_order = False;
                            if ( $cancel_order == True ) {
                                    $order -> update_status( 'cancelled', __( 'Pagamento não identificado e cancelado.', 'woocommerce') );
    add_action( 'woocommerce_cancel_unpaid_submitted', 'wc_cancel_unpaid_submitted' );
    /* End of code. */
| improve this answer | |
  • @daniel-remagnoli remember to mark you own answer as a solution, if the question is answered. – Zeth Nov 6 '18 at 0:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.