init_hooks(); } /** * Initialize hooks. */ private function init_hooks() { add_action( 'init', array( $this, 'register_order_statuses' ) ); add_filter( 'wc_order_statuses', array( $this, 'add_order_statuses' ) ); add_filter( 'woocommerce_reports_order_statuses', array( $this, 'add_reports_statuses' ) ); } /** * Register custom order statuses. */ public function register_order_statuses() { register_post_status( 'wc-adp-pending', array( 'label' => _x( 'AfriDirect: Pending Payment', 'Order status', 'afridirect-payment' ), 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: Number of orders with this status */ 'label_count' => _n_noop( 'AfriDirect: Pending Payment (%s)', 'AfriDirect: Pending Payment (%s)', 'afridirect-payment' ), ) ); register_post_status( 'wc-adp-proof', array( 'label' => _x( 'AfriDirect: Proof Uploaded', 'Order status', 'afridirect-payment' ), 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: Number of orders with this status */ 'label_count' => _n_noop( 'AfriDirect: Proof Uploaded (%s)', 'AfriDirect: Proof Uploaded (%s)', 'afridirect-payment' ), ) ); register_post_status( 'wc-adp-approved', array( 'label' => _x( 'AfriDirect: Approved', 'Order status', 'afridirect-payment' ), 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: Number of orders with this status */ 'label_count' => _n_noop( 'AfriDirect: Approved (%s)', 'AfriDirect: Approved (%s)', 'afridirect-payment' ), ) ); register_post_status( 'wc-adp-rejected', array( 'label' => _x( 'AfriDirect: Rejected', 'Order status', 'afridirect-payment' ), 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: Number of orders with this status */ 'label_count' => _n_noop( 'AfriDirect: Rejected (%s)', 'AfriDirect: Rejected (%s)', 'afridirect-payment' ), ) ); register_post_status( 'wc-adp-expired', array( 'label' => _x( 'AfriDirect: Expired', 'Order status', 'afridirect-payment' ), 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: Number of orders with this status */ 'label_count' => _n_noop( 'AfriDirect: Expired (%s)', 'AfriDirect: Expired (%s)', 'afridirect-payment' ), ) ); } /** * Add order statuses to WooCommerce. * * @param array $order_statuses Existing order statuses. * @return array */ public function add_order_statuses( $order_statuses ) { $new_statuses = array(); // Add afridirect-pending after pending. foreach ( $order_statuses as $key => $status ) { $new_statuses[ $key ] = $status; if ( 'wc-pending' === $key ) { $new_statuses['wc-adp-pending'] = _x( 'AfriDirect: Pending Payment', 'Order status', 'afridirect-payment' ); } } // Add other statuses. $new_statuses['wc-adp-proof'] = _x( 'AfriDirect: Proof Uploaded', 'Order status', 'afridirect-payment' ); $new_statuses['wc-adp-approved'] = _x( 'AfriDirect: Approved', 'Order status', 'afridirect-payment' ); $new_statuses['wc-adp-rejected'] = _x( 'AfriDirect: Rejected', 'Order status', 'afridirect-payment' ); $new_statuses['wc-adp-expired'] = _x( 'AfriDirect: Expired', 'Order status', 'afridirect-payment' ); return $new_statuses; } /** * Add statuses to reports. * * @param array $statuses Existing statuses. * @return array */ public function add_reports_statuses( $statuses ) { $statuses[] = 'adp-pending'; $statuses[] = 'adp-proof'; $statuses[] = 'adp-approved'; return $statuses; } /** * Self-heal an order that should be in the AfriDirect flow but whose status * was reset to something generic (e.g. 'pending') after checkout. * * Some checkout stacks (block checkout's Store API in particular) validate or * override an unrecognised order status after a gateway's process_payment() * runs. If that happens to an AfriDirect order that hasn't had proof * uploaded/reviewed yet, this restores it to 'adp-pending' so the * customer still sees the countdown and upload form instead of nothing. * * @param WC_Order $order Order to check. * @return string The (possibly corrected) order status. */ public static function maybe_restore_pending( $order ) { $status = $order->get_status(); $our_statuses = array( 'adp-pending', 'adp-proof', 'adp-rejected', 'adp-expired' ); if ( in_array( $status, $our_statuses, true ) ) { return $status; } if ( 'afridirect_payment' !== $order->get_payment_method() ) { return $status; } // Only restore orders that haven't already been reviewed or expired. if ( $order->get_meta( '_afridirect_proof_url' ) || $order->get_meta( '_afridirect_review_status' ) ) { return $status; } $order->update_status( 'adp-pending', __( 'Payment status restored to Pending Payment after checkout.', 'afridirect-payment' ) ); $order->save(); return 'adp-pending'; } }