I’m working on a custom checkout function and need help preventing duplicate orders in WooCommerce. Here’s my current implementation:
public function handle_order_submission() {
try {
$security_token = wc_get_var( $_REQUEST['woocommerce-checkout-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) );
$session_expired_msg = sprintf(
__( 'Your session expired. <a href="%s">Go back to store</a>', 'woocommerce' ),
esc_url( wc_get_page_permalink( 'shop' ) )
);
if ( empty( $security_token ) || ! wp_verify_nonce( $security_token, 'woocommerce-checkout' ) ) {
if ( WC()->cart->is_empty() ) {
throw new Exception( $session_expired_msg );
}
WC()->session->set( 'refresh_totals', true );
throw new Exception( __( 'Order processing failed, please retry.', 'woocommerce' ) );
}
wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true );
wc_set_time_limit( 0 );
do_action( 'woocommerce_before_checkout_process' );
if ( WC()->cart->is_empty() ) {
throw new Exception( $session_expired_msg );
}
do_action( 'woocommerce_checkout_process' );
$validation_errors = new WP_Error();
$form_data = $this->get_submitted_data();
$this->refresh_session( $form_data );
$this->validate_order_data( $form_data, $validation_errors );
foreach ( $validation_errors->errors as $error_code => $error_messages ) {
$error_data = $validation_errors->get_error_data( $error_code );
foreach ( $error_messages as $error_message ) {
wc_add_notice( $error_message, 'error', $error_data );
}
}
if ( empty( $form_data['woocommerce_update_checkout'] ) && 0 === wc_notice_count( 'error' ) ) {
$this->handle_customer_data( $form_data );
$new_order_id = $this->generate_order( $form_data );
$current_order = wc_get_order( $new_order_id );
if ( is_wp_error( $new_order_id ) ) {
throw new Exception( $new_order_id->get_error_message() );
}
if ( ! $current_order ) {
throw new Exception( __( 'Order creation failed.', 'woocommerce' ) );
}
do_action( 'woocommerce_order_creation_complete', $new_order_id, $form_data, $current_order );
if ( apply_filters( 'woocommerce_payment_required', $current_order->needs_payment(), WC()->cart ) ) {
$this->handle_payment_processing( $new_order_id, $form_data['payment_method'] );
} else {
$this->complete_free_order( $new_order_id );
}
}
} catch ( Exception $error ) {
wc_add_notice( $error->getMessage(), 'error' );
}
$this->return_ajax_error();
}
This is from the WooCommerce core for testing purposes. I’ll implement this using proper hooks later.
I need this function to check if a customer already has an existing order for the same product. If they do, it should either block the new order creation or update the existing order instead of creating a duplicate.
What’s the best approach to implement this duplicate order prevention?