Skip to content

Instantly share code, notes, and snippets.

@lukapaunovic
Last active January 2, 2026 03:15
Show Gist options
  • Select an option

  • Save lukapaunovic/3e4c4897cb045ae9671fd1f9e1b004ca to your computer and use it in GitHub Desktop.

Select an option

Save lukapaunovic/3e4c4897cb045ae9671fd1f9e1b004ca to your computer and use it in GitHub Desktop.
<?php
// Checkout snapshot: billing/shipping, payment, IP, user agent, shipping lines.
add_action( 'woocommerce_checkout_create_order', function( WC_Order $order, $data ) {
$shipping_lines = array();
foreach ( $order->get_shipping_methods() as $item ) {
$shipping_lines[] = array(
'method_id' => $item->get_method_id(),
'instance_id' => $item->get_instance_id(),
'name' => $item->get_name(),
'total' => $item->get_total(),
'total_tax' => $item->get_total_tax(),
'meta' => $item->get_formatted_meta_data(),
);
}
$order->update_meta_data(
'_wd_checkout_snapshot',
array(
'billing' => $order->get_address( 'billing' ),
'shipping' => $order->get_address( 'shipping' ),
'payment_method' => $order->get_payment_method(),
'payment_title' => $order->get_payment_method_title(),
'ip' => $order->get_customer_ip_address(),
'ua' => $order->get_customer_user_agent(),
'shipping_lines' => $shipping_lines,
)
);
}, 9000, 2 );
// Before saving: restore data and totals; add note only once.
add_action( 'woocommerce_before_order_object_save', function( $order ) {
if ( ! $order instanceof WC_Order ) return;
if ( 0 === count( $order->get_items( 'line_item' ) ) ) return;
$snap = $order->get_meta( '_wd_checkout_snapshot' );
$recovered = false;
if ( is_array( $snap ) ) {
foreach ( array( 'email','first_name','last_name','phone','address_1','address_2','city','postcode','country','company' ) as $k ) {
$g="get_billing_$k"; $s="set_billing_$k";
if ( method_exists($order,$g) && method_exists($order,$s) && empty($order->{$g}()) && !empty($snap['billing'][$k]) ) { $order->{$s}($snap['billing'][$k]); $recovered=true; }
}
foreach ( array( 'first_name','last_name','address_1','address_2','city','postcode','country','company' ) as $k ) {
$g="get_shipping_$k"; $s="set_shipping_$k";
if ( method_exists($order,$g) && method_exists($order,$s) && empty($order->{$g}()) && !empty($snap['shipping'][$k]) ) { $order->{$s}($snap['shipping'][$k]); $recovered=true; }
}
if ( $order->get_payment_method()==='' && !empty($snap['payment_method']) ) {
$order->set_payment_method( $snap['payment_method'] );
$order->set_payment_method_title( $snap['payment_title'] );
$recovered = true;
}
if ( ! $order->get_customer_ip_address() && !empty($snap['ip']) ) {
$order->set_customer_ip_address( $snap['ip'] ); $recovered=true;
}
if ( ! $order->get_customer_user_agent() && !empty($snap['ua']) ) {
$order->set_customer_user_agent( $snap['ua'] ); $recovered=true;
}
// Restore shipping lines if they were lost.
if ( empty( $order->get_shipping_methods() ) && ! empty( $snap['shipping_lines'] ) ) {
foreach ( $snap['shipping_lines'] as $line ) {
$item = new WC_Order_Item_Shipping();
$item->set_method_id( $line['method_id'] ?? '' );
$item->set_instance_id( $line['instance_id'] ?? 0 );
$item->set_name( $line['name'] ?? '' );
$item->set_total( $line['total'] ?? 0 );
$item->set_total_tax( $line['total_tax'] ?? 0 );
$order->add_item( $item );
}
$recovered = true;
}
}
// Recalculate total from items + shipping + fees + tax.
$item_total = array_sum( array_map( static fn( $i ) => (float) $i->get_total(), $order->get_items( 'line_item' ) ) );
$fee_total = array_sum( array_map( static fn( $f ) => (float) $f->get_total(), $order->get_fees() ) );
$shipping_total = array_sum( array_map( static fn( $s ) => (float) $s->get_total(), $order->get_shipping_methods() ) );
$shipping_tax = array_sum( array_map( static fn( $s ) => (float) $s->get_total_tax(), $order->get_shipping_methods() ) );
$tax_total = (float) $order->get_total_tax();
if ( $order->get_shipping_total() != $shipping_total ) { $order->set_shipping_total( $shipping_total ); $recovered=true; }
if ( $order->get_shipping_tax() != $shipping_tax ) { $order->set_shipping_tax( $shipping_tax ); $recovered=true; }
$calc_total = $item_total + $fee_total + $shipping_total + $tax_total;
if ( $calc_total > 0 && $order->get_total() <= 0 ) {
$order->set_total( $calc_total );
$order->update_meta_data( '_order_total', $calc_total );
$recovered = true;
}
if ( $recovered && ! $order->get_meta( '_wd_recovered_logged' ) ) {
$order->add_order_note( 'Auto-recovered checkout data (billing/shipping/total) due to empty-order anomaly.' );
$order->update_meta_data( '_wd_recovered_logged', 1 );
}
}, 5 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment