Premium add-on for Bricks Builder

How to Show BricksUltimate Custom Checkout Fields in WooCommerce Emails

BricksUltimate’s Billing Fields and Shipping Fields elements allow you to create custom checkout fields from the Bricks Builder checkout template. These fields are saved with the WooCommerce order, but WooCommerce email templates may not automatically display them.

The good news is that you do not need to edit the BricksUltimate plugin files.

Ultimate Product Addons

How BricksUltimate Saves Custom Fields

When you create a custom billing field, BricksUltimate automatically normalizes the field key.

Example:

vat_number

becomes:

billing_vat_number

WooCommerce stores the value as order meta:

_billing_vat_number

For shipping fields, the same logic applies.

Example:

delivery_note

becomes:

shipping_delivery_note

and is stored as:

_shipping_delivery_note

Where to Add the Code

Add the snippet to one of these places:

  • Child theme functions.php
  • Code Snippets plugin
  • A small custom site plugin

Do not add it directly inside the BricksUltimate plugin, because plugin updates will overwrite your changes.

<?php
/**
 * Show BricksUltimate Billing/Shipping custom field values in WooCommerce emails.
 */
add_action( 'woocommerce_email_order_meta', 'bu_show_checkout_custom_fields_in_emails', 20, 4 );

function bu_show_checkout_custom_fields_in_emails( $order, $sent_to_admin, $plain_text, $email ) {
	if ( ! $order instanceof WC_Order ) {
		return;
	}

	$fields = bu_get_bricksultimate_checkout_custom_fields();

	if ( empty( $fields ) ) {
		return;
	}

	$rows = [];

	foreach ( $fields as $field ) {
		$value = bu_get_bricksultimate_order_custom_field_value( $order, $field );

		if ( $value === '' || $value === null ) {
			continue;
		}

		$rows[] = [
			'label' => $field['label'],
			'value' => bu_format_bricksultimate_custom_field_value( $value, $field ),
		];
	}

	if ( empty( $rows ) ) {
		return;
	}

	if ( $plain_text ) {
		echo "\n" . esc_html__( 'Additional information', 'bricksultimate' ) . "\n\n";

		foreach ( $rows as $row ) {
			echo wp_strip_all_tags( $row['label'] ) . ': ' . wp_strip_all_tags( $row['value'] ) . "\n";
		}

		return;
	}

	echo '<h2>' . esc_html__( 'Additional information', 'bricksultimate' ) . '</h2>';
	echo '<table cellspacing="0" cellpadding="6" border="1" style="width:100%; border:1px solid #e5e5e5; margin-bottom:20px;">';

	foreach ( $rows as $row ) {
		echo '<tr>';
		echo '<th scope="row" style="text-align:left; width:35%;">' . esc_html( $row['label'] ) . '</th>';
		echo '<td>' . wp_kses_post( $row['value'] ) . '</td>';
		echo '</tr>';
	}

	echo '</table>';
}

function bu_get_bricksultimate_checkout_custom_fields() {
	if ( ! class_exists( '\Bricks\Woocommerce' ) || ! defined( 'BRICKS_DB_PAGE_CONTENT' ) ) {
		return [];
	}

	$template_id = \Bricks\Woocommerce::get_template_data_by_type( 'wc_form_checkout', false );

	if ( ! $template_id ) {
		return [];
	}

	$template_data = get_post_meta( $template_id, BRICKS_DB_PAGE_CONTENT, true );

	if ( empty( $template_data ) || ! is_array( $template_data ) ) {
		return [];
	}

	$fields = [];

	foreach ( $template_data as $element ) {
		if ( empty( $element['name'] ) || empty( $element['settings'] ) ) {
			continue;
		}

		$settings = $element['settings'];

		if ( $element['name'] === 'bu-billing-fields' && ( $settings['billing_field'] ?? '' ) === 'custom' ) {
			$prefix = 'billing';
		} elseif ( $element['name'] === 'bu-shipping-fields' && ( $settings['shipping_field'] ?? '' ) === 'custom' ) {
			$prefix = 'shipping';
		} else {
			continue;
		}

		if ( empty( $settings['field_key'] ) ) {
			continue;
		}

		$legacy_key = sanitize_key( $settings['field_key'] );
		$field_key  = bu_normalize_bricksultimate_custom_field_key( $legacy_key, $prefix );

		if ( ! $field_key ) {
			continue;
		}

		$fields[] = [
			'prefix'      => $prefix,
			'legacy_key'  => $legacy_key,
			'field_key'   => $field_key,
			'label'       => ! empty( $settings['label'] ) ? wp_strip_all_tags( $settings['label'] ) : $field_key,
			'field_type'  => ! empty( $settings['field_type'] ) ? sanitize_key( $settings['field_type'] ) : 'text',
			'options_raw' => $settings['fieldOptions'] ?? '',
		];
	}

	return $fields;
}

function bu_normalize_bricksultimate_custom_field_key( $field_key, $prefix ) {
	$field_key = sanitize_key( $field_key );
	$field_prefix = $prefix . '_';

	if ( $field_key && strpos( $field_key, $field_prefix ) !== 0 ) {
		$field_key = $field_prefix . $field_key;
	}

	return $field_key;
}

function bu_get_bricksultimate_order_custom_field_value( $order, $field ) {
	$value = $order->get_meta( '_' . $field['field_key'] );

	// Fallback for older orders if the field was previously saved without billing_/shipping_ prefix.
	if ( ( $value === '' || $value === null ) && $field['legacy_key'] !== $field['field_key'] ) {
		$value = $order->get_meta( '_' . $field['legacy_key'] );

		if ( $value === '' || $value === null ) {
			$value = $order->get_meta( $field['legacy_key'] );
		}
	}

	return $value;
}

function bu_format_bricksultimate_custom_field_value( $value, $field ) {
	if ( is_array( $value ) ) {
		$value = implode( ', ', array_map( 'wc_clean', $value ) );
	}

	if ( $field['field_type'] === 'checkbox' ) {
		return in_array( $value, [ '1', 1, 'yes', true ], true ) ? esc_html__( 'Yes', 'woocommerce' ) : esc_html__( 'No', 'woocommerce' );
	}

	if ( $field['field_type'] === 'date' ) {
		$timestamp = strtotime( $value );
		return $timestamp ? date_i18n( wc_date_format(), $timestamp ) : esc_html( $value );
	}

	if ( $field['field_type'] === 'time' ) {
		$timestamp = strtotime( $value );
		return $timestamp ? date_i18n( wc_time_format(), $timestamp ) : esc_html( $value );
	}

	$options = bu_parse_bricksultimate_field_options( $field['options_raw'] );

	if ( isset( $options[ $value ] ) ) {
		return esc_html( $options[ $value ] );
	}

	return esc_html( $value );
}

function bu_parse_bricksultimate_field_options( $raw_options ) {
	$options = [];

	if ( empty( $raw_options ) ) {
		return $options;
	}

	foreach ( explode( "\n", $raw_options ) as $line ) {
		$parts = array_map( 'trim', explode( ':', $line, 2 ) );

		if ( empty( $parts[0] ) ) {
			continue;
		}

		$options[ $parts[0] ] = $parts[1] ?? $parts[0];
	}

	return $options;
}

What the Snippet Does

The snippet reads the active Bricks checkout template, finds all BricksUltimate custom billing and shipping fields, gets their saved order meta values, and prints them inside WooCommerce emails under an “Additional information” section.

It supports:

  • Billing custom fields
  • Shipping custom fields
  • Text fields
  • Select/radio option labels
  • Checkbox yes/no values
  • Date fields
  • Time fields
  • Plain text emails
  • HTML emails

Result

After adding the snippet, WooCommerce emails will include your BricksUltimate custom checkout field values automatically whenever those fields have data on the order.

Buy One Get One

Leave the first comment