Skip to content

Instantly share code, notes, and snippets.

@xlplugins
Created December 19, 2025 06:55
Show Gist options
  • Select an option

  • Save xlplugins/efec709e82ac1e4647828fe8d6644af6 to your computer and use it in GitHub Desktop.

Select an option

Save xlplugins/efec709e82ac1e4647828fe8d6644af6 to your computer and use it in GitHub Desktop.
Ensures billing fields are properly copied from shipping address when billing address is optional and "same as shipping" is selected.
if ( ! class_exists( 'WFACP_Billing_Field_Copy_Handler' ) ) {
class WFACP_Billing_Field_Copy_Handler {
/**
* Fields that should be copied from shipping to billing
*
* @var array
*/
private $copy_fields = array(
'first_name',
'last_name',
'company',
'address_1',
'address_2',
'city',
'state',
'postcode',
'country',
'phone',
);
/**
* Constructor - Register hooks
*/
public function __construct() {
// High priority to ensure it runs after WFACP's own processing
add_filter( 'woocommerce_checkout_posted_data', array( $this, 'copy_shipping_to_billing' ), 999 );
add_action( 'woocommerce_checkout_process', array( $this, 'validate_billing_fields' ), 5 );
}
/**
* Copy shipping address to billing when billing same as shipping is checked
*
* @param array $data Posted checkout data
* @return array Modified checkout data
*/
public function copy_shipping_to_billing( $data ) {
// Only proceed if this is a WFACP checkout
if ( ! isset( $_POST['_wfacp_post_id'] ) ) {
return $data;
}
// Check if billing same as shipping is enabled
$billing_same_as_shipping = isset( $_POST['billing_same_as_shipping'] ) ? absint( $_POST['billing_same_as_shipping'] ) : 0;
// Check if user has NOT opted for different billing address
$ship_to_different = isset( $_POST['ship_to_different_address'] ) ? absint( $_POST['ship_to_different_address'] ) : 0;
// Only copy if billing same as shipping is checked OR ship to different is not checked
if ( 1 !== $billing_same_as_shipping && 1 === $ship_to_different ) {
return $data;
}
// Copy each shipping field to corresponding billing field
foreach ( $this->copy_fields as $field ) {
$shipping_key = 'shipping_' . $field;
$billing_key = 'billing_' . $field;
// If shipping field exists and has value
if ( isset( $data[ $shipping_key ] ) && ! empty( $data[ $shipping_key ] ) ) {
// Copy to billing if billing is empty
if ( ! isset( $data[ $billing_key ] ) || empty( $data[ $billing_key ] ) ) {
$data[ $billing_key ] = $data[ $shipping_key ];
}
}
}
return $data;
}
/**
* Validate that required billing fields are not empty
* when billing address should be same as shipping
*
* @return void
*/
public function validate_billing_fields() {
// Only proceed if this is a WFACP checkout
if ( ! isset( $_POST['_wfacp_post_id'] ) ) {
return;
}
// Check if billing same as shipping is enabled
$billing_same_as_shipping = isset( $_POST['billing_same_as_shipping'] ) ? absint( $_POST['billing_same_as_shipping'] ) : 0;
// Only validate if billing same as shipping is checked
if ( 1 !== $billing_same_as_shipping ) {
return;
}
// Required fields that must be copied
$required_fields = array(
'first_name' => __( 'First name', 'woocommerce' ),
'last_name' => __( 'Last name', 'woocommerce' ),
'address_1' => __( 'Street address', 'woocommerce' ),
'city' => __( 'Town / City', 'woocommerce' ),
'postcode' => __( 'Postcode / ZIP', 'woocommerce' ),
'country' => __( 'Country / Region', 'woocommerce' ),
);
// Check each required field
foreach ( $required_fields as $field => $label ) {
$shipping_key = 'shipping_' . $field;
$billing_key = 'billing_' . $field;
// If shipping field has value, copy it to billing
if ( isset( $_POST[ $shipping_key ] ) && ! empty( $_POST[ $shipping_key ] ) ) {
if ( ! isset( $_POST[ $billing_key ] ) || empty( $_POST[ $billing_key ] ) ) {
$_POST[ $billing_key ] = sanitize_text_field( wp_unslash( $_POST[ $shipping_key ] ) );
}
}
}
}
}
// Initialize the handler
new WFACP_Billing_Field_Copy_Handler();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment