Execute some code only once for bank wire confirmed payment in WooCommerce

40 Views Asked by At

For the bank transfer (bacs) payment method, since the store manager manually confirms that the order is paid by changing the order status, you need to use the special woocommerce_order_status_changed hook.

The status of successful orders can be changed from

  1. On Hold to Processing,
  2. On Hold to Completed, or
  3. On Hold to Processing to Completed.

However, the action should only be fired once for each successful order.


I tried to achieve this by checking the payment date of the orders && ! $order->get_date_paid('edit'), but it seems not to be a working solution because a payment date is always received.

add_action( 'woocommerce_order_status_changed', 'bacs_payment_complete', 10, 4 );
function bacs_payment_complete( $order_id, $old_status, $new_status, $order ) {
  // 1. For Bank wire and cheque payments
  if( in_array( $order->get_payment_method(), array('bacs') 
  && in_array( $new_status, array('processing', 'completed') 
  && ! $order->get_date_paid('edit') ) {
    // Do something
  } 
}
1

There are 1 best solutions below

0
LoicTheAztec On BEST ANSWER

To get some code executed just once in this function, you need to tag the order like:

add_action( 'woocommerce_order_status_changed', 'bacs_payment_complete', 10, 4 );
function bacs_payment_complete( $order_id, $old_status, $new_status, $order ) {
    // 1. For Bank wire and cheque payments
    if ( $order->get_payment_method() === 'bacs' 
    && in_array( $new_status, wc_get_is_paid_statuses() )
    && $order->get_meta('confirmed_paid') !== 'yes' ) 
    {
        $order->update_meta_data('confirmed_paid', 'yes'); // Tag the order
        $order->save(); // Save to database

        // Here the code to be executed only once
    } 
}

Code goes in functions.php file of your child theme (or in a plugin). It should work.