// ── 0. Server-side Add to Cart Handoff (?owl_add_to_cart=PRODUCT_ID&owlb_*...) ──── add_action( 'wp_loaded', function () { if ( empty( $_GET['owl_add_to_cart'] ) ) return; header('X-Owl-Handoff-Executed: 1'); $product_id = intval( $_GET['owl_add_to_cart'] ); $design_id = intval( $_GET['owlb_design_id'] ?? 0 ); $qty = max( 1, intval( $_GET['owl_qty'] ?? ( $_GET['owlb_qty'] ?? 1 ) ) ); if ( ! $product_id ) { wp_redirect( wc_get_cart_url() ); exit; } if ( function_exists( 'wc_load_cart' ) && ( ! function_exists( 'WC' ) || ! WC()->cart ) ) { wc_load_cart(); } if ( ! function_exists( 'WC' ) || ! WC()->cart ) { wp_redirect( wc_get_cart_url() ); exit; } // Populate $cart_item_data, $_POST and $_REQUEST so all WooCommerce filters capture the design data $cart_item_data = []; foreach ( $_GET as $key => $value ) { $k = (string) $key; if ( strpos( $k, 'owlb_' ) === 0 || strpos( $k, 'badge' ) === 0 || strpos( $k, 'form-' ) === 0 || strpos( $k, 'addon-' ) === 0 || strpos( $k, 'element' ) === 0 || strpos( $k, 'panel' ) === 0 || strpos( $k, 'section' ) === 0 || in_array( $k, [ 'step', 'idPatchNote', 'additionalInformation', 'additionalInformationNumber', 'cartItemKey', ], true ) ) { $unslashed = wp_unslash( $value ); $_POST[ $k ] = $unslashed; $_REQUEST[ $k ] = $unslashed; $cart_item_data[ $k ] = $unslashed; } } if ( ! empty( $_GET['owlb_price'] ) ) { $cart_item_data['owlb_price'] = floatval( $_GET['owlb_price'] ); } $cart_item_data['owlb_unique_key'] = md5( microtime() . ( $design_id ?: rand() ) ); // If editing an existing cart item, remove old item before adding updated design if ( ! empty( $_GET['replace_cart_item'] ) ) { $old_key = sanitize_text_field( $_GET['replace_cart_item'] ); if ( isset( WC()->cart->cart_contents[ $old_key ] ) ) { WC()->cart->remove_cart_item( $old_key ); } } $_POST['add-to-cart'] = $product_id; $_POST['quantity'] = $qty; $cart_item_key = WC()->cart->add_to_cart( $product_id, $qty, 0, array(), $cart_item_data ); if ( $cart_item_key ) { wc_add_notice( sprintf( __( '“%s” has been added to your cart.', 'woocommerce' ), get_the_title( $product_id ) ), 'success' ); } if ( function_exists( 'WC' ) && WC()->session ) { if ( method_exists( WC()->session, 'set_customer_session_cookie' ) ) { WC()->session->set_customer_session_cookie( true ); } if ( method_exists( WC()->session, 'save_data' ) ) { WC()->session->save_data(); } } header( 'X-Owl-Handoff-Executed: 1' ); header( 'X-Owl-Cart-Key: ' . ( $cart_item_key ?: 'FAILED' ) ); header( 'X-Owl-Price-Set: ' . ( $cart_item_data['owlb_price'] ?? 'NONE' ) ); wp_redirect( wc_get_cart_url() ); exit; }, 5 ); // ── 1. Capture owlb_* / collar-pin / challenge-coin params on add-to-cart ───── add_filter( 'woocommerce_add_cart_item_data', function( $cart_item_data, $product_id, $variation_id ) { // Standard owlb_* fields (read from $_GET — sent by the HMAC redirect) $fields = [ 'owlb_design_id' => 'Design ID', 'owlb_token' => 'Token', 'owlb_template' => 'Template', 'owlb_type' => 'Badge Type', 'owlb_size' => 'Size', 'owlb_color' => 'Color', 'owlb_font' => 'Font', 'owlb_text_1' => 'Line 1', 'owlb_text_type_1' => 'Line 1 Type', 'owlb_text_2' => 'Line 2', 'owlb_text_type_2' => 'Line 2 Type', 'owlb_text_3' => 'Line 3', 'owlb_text_type_3' => 'Line 3 Type', 'owlb_text_4' => 'Line 4', 'owlb_text_type_4' => 'Line 4 Type', 'owlb_seal' => 'Seal', 'owlb_attachment' => 'Attachment', 'owlb_colors' => 'Patch Colors', 'owlb_price' => 'Design Price', 'owlb_qty' => 'Quantity', 'owlb_preview_image' => 'Badge Preview', 'owlb_pin_text' => 'Pin Text', 'owlb_pin_text_color' => 'Pin Text Color', 'owlb_pin_text_style' => 'Pin Text Style', // Collar-pin specific keys (form-collar-* and collarPin*) 'form-collar-text' => 'Pin Text', 'form-collar-text-color' => 'Pin Text Color Hex', 'form-collar-text-color-name' => 'Pin Text Color', 'form-collar-text-style' => 'Pin Text Style', 'form-collar-text-size-label' => 'Pin Text Size', 'form-collar-attachment' => 'Attachment', 'form-collar-image' => 'Collar Preview', 'form-collar-image-wm-off' => 'Collar Preview WM Off', 'collarPinTextPanel' => 'Pin Text', 'collarPinTextColor' => 'Pin Text Color Hex', 'collarPinTextColorName' => 'Pin Text Color Name', 'collarPinTextStyle' => 'Pin Text Style', 'collarPinTextSizeLabel' => 'Pin Text Size Label', 'collarPinAttachment' => 'Collar Attachment', // Challenge-coin specific keys (form-coin-* primary + coin-* aliases) 'form-coin-front-paneltext1' => 'Front Text Panel 1', 'form-coin-front-paneltext2' => 'Front Text Panel 2', 'form-coin-back-paneltext1' => 'Back Text Panel 1', 'form-coin-back-paneltext2' => 'Back Text Panel 2', 'form-coin-front-panel1-color-name' => 'Front Text Color', 'form-coin-front-panel1-color-code' => 'Front Text Color Code', 'form-coin-front-panel2-color-name' => 'Front Text 2 Color', 'form-coin-front-panel2-color-code' => 'Front Text 2 Color Code', 'form-coin-back-panel1-color-name' => 'Back Text Color', 'form-coin-back-panel1-color-code' => 'Back Text Color Code', 'form-coin-back-panel2-color-name' => 'Back Text 2 Color', 'form-coin-back-panel2-color-code' => 'Back Text 2 Color Code', 'form-coin-front-basecolor-name' => 'Front Base Color', 'form-coin-front-basecolor-code' => 'Front Base Color Code', 'form-coin-back-basecolor-name' => 'Back Base Color', 'form-coin-back-basecolor-code' => 'Back Base Color Code', 'form-coin-front-bordercolor-name' => 'Front Border Color', 'form-coin-front-bordercolor-code' => 'Front Border Color Code', 'form-coin-back-bordercolor-name' => 'Back Border Color', 'form-coin-back-bordercolor-code' => 'Back Border Color Code', 'form-coin-front-bgcolor-name' => 'Front BG Color', 'form-coin-front-bgcolor-code' => 'Front BG Color Code', 'form-coin-back-bgcolor-name' => 'Back BG Color', 'form-coin-back-bgcolor-code' => 'Back BG Color Code', 'form-coin-front-seal-id' => 'Front Seal ID', 'form-coin-back-seal-id' => 'Back Seal ID', 'form-coin-front-seal-image' => 'Front Seal Image', 'form-coin-back-seal-image' => 'Back Seal Image', 'form-coin-front-image' => 'Front Coin Image', 'form-coin-back-image' => 'Back Coin Image', 'form-coin-edges-id' => 'Coin Edge ID', 'form-coin-edges-price' => 'Coin Edge Price', 'form-coin-front-font' => 'Front Text Font', 'form-coin-back-font' => 'Back Text Font', // coin-* aliases 'coin-front-paneltext1' => 'Front Text 1', 'coin-front-paneltext2' => 'Front Text 2', 'coin-front-top-textcolorname' => 'Front Top Color', 'coin-front-top-textcolorcode' => 'Front Top Color Code', 'coin-front-bottom-textcolorname' => 'Front Bottom Color', 'coin-front-bottom-textcolorcode' => 'Front Bottom Color Code', 'coin-front-basecolorname' => 'Front Base Color', 'coin-front-basecolorcode' => 'Front Base Color Code', 'coin-front-bordercolorname' => 'Front Border Color', 'coin-front-bordercolorcode' => 'Front Border Color Code', 'coin-front-bgcolorname' => 'Front BG Color', 'coin-front-bgcolorcode' => 'Front BG Color Code', 'coin-front-seal-imageid' => 'Front Seal ID', 'coin-front-seal-image' => 'Front Seal Image', 'coin-front-image' => 'Front Coin Image URL', 'coin-front-font' => 'Front Font', 'coin-front-separator' => 'Front Separator', 'coin-edges-id' => 'Edge ID', 'coin-edges-price' => 'Edge Price', 'coin-back-paneltext1' => 'Back Text 1', 'coin-back-paneltext2' => 'Back Text 2', 'coin-back-top-textcolorname' => 'Back Top Color', 'coin-back-top-textcolorcode' => 'Back Top Color Code', 'coin-back-bottom-textcolorname' => 'Back Bottom Color', 'coin-back-bottom-textcolorcode' => 'Back Bottom Color Code', 'coin-back-basecolorname' => 'Back Base Color', 'coin-back-basecolorcode' => 'Back Base Color Code', 'coin-back-bordercolorname' => 'Back Border Color', 'coin-back-bordercolorcode' => 'Back Border Color Code', 'coin-back-bgcolorname' => 'Back BG Color', 'coin-back-bgcolorcode' => 'Back BG Color Code', 'coin-back-seal-imageid' => 'Back Seal ID', 'coin-back-seal-image' => 'Back Seal Image', 'coin-back-image' => 'Back Coin Image URL', 'coin-back-font' => 'Back Font', 'coin-back-separator' => 'Back Separator', // owlb_coin_* extended fields (set by our badge designer backend) 'owlb_coin_edge' => 'Edge', 'owlb_coin_edge_price' => 'Edge Price', 'owlb_coin_packaging' => 'Packaging', 'owlb_coin_base_color' => 'Base Color', 'owlb_coin_front_ring' => 'Front Text Ring', 'owlb_coin_front_inner' => 'Front Inner Circle', 'owlb_coin_back_ring' => 'Back Text Ring', 'owlb_coin_back_inner' => 'Back Inner Circle', 'owlb_coin_front_element' => 'Front Element', 'owlb_coin_back_element' => 'Back Element', ]; // Image URL keys — allow both full URLs and base64 data URIs $image_keys = [ 'owlb_preview_image', 'form-collar-image', 'form-collar-image-wm-off', 'form-coin-front-image', 'form-coin-back-image', 'coin-front-image', 'coin-back-image', ]; // Capture from $_GET (HMAC redirect) and $_POST (direct form) $src = array_merge( $_GET, $_POST, $_REQUEST ); foreach ( $fields as $key => $label ) { if ( isset( $src[ $key ] ) && strlen( (string) $src[ $key ] ) > 0 ) { if ( in_array( $key, $image_keys, true ) ) { $val = $src[ $key ]; // Allow both URLs and base64 data URIs if ( strpos( $val, 'data:image/' ) === 0 ) { $cart_item_data[ $key ] = $val; } else { $cart_item_data[ $key ] = esc_url_raw( wp_unslash( $val ) ); } } else { $cart_item_data[ $key ] = sanitize_text_field( wp_unslash( $src[ $key ] ) ); } } } // Always generate unique key for designer items to prevent unwanted cart merging $design_id = $cart_item_data['owlb_design_id'] ?? ( $src['owlb_design_id'] ?? '' ); if ( $design_id || ! empty( $cart_item_data['owlb_price'] ) ) { $cart_item_data['owlb_unique_key'] = md5( microtime() . ( $design_id ?: rand() ) ); } // Zero out WC_Product_Addons prices for designer items (designer price already includes all add-ons) if ( ! empty( $cart_item_data['owlb_price'] ) ) { $unit_price = floatval( $cart_item_data['owlb_price'] ); $cart_item_data['_is_order_again'] = true; $cart_item_data['_order_again_unit_total'] = $unit_price; $cart_item_data['_order_again_unit_subtotal'] = $unit_price; $cart_item_data['addons_price'] = 0; if ( ! empty( $cart_item_data['addons'] ) && is_array( $cart_item_data['addons'] ) ) { foreach ( $cart_item_data['addons'] as &$addon ) { $addon['price'] = 0; } } } return $cart_item_data; }, 100, 3 ); // Override Product Add-Ons & Theme price modifications when cart item is created add_filter( 'woocommerce_add_cart_item', function( $cart_item, $cart_item_key ) { if ( isset( $cart_item['owlb_price'] ) && strlen( (string) $cart_item['owlb_price'] ) > 0 ) { $unit_price = floatval( $cart_item['owlb_price'] ); if ( $unit_price >= 0 && isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) ) { $cart_item['_is_order_again'] = true; $cart_item['_order_again_unit_total'] = $unit_price; $cart_item['_order_again_unit_subtotal'] = $unit_price; $cart_item['data']->owlb_custom_price = $unit_price; $cart_item['data']->set_price( $unit_price ); $cart_item['data']->set_regular_price( $unit_price ); $cart_item['data']->set_sale_price( '' ); } } return $cart_item; }, 999999, 2 ); // Restore custom designer session properties when cart items are loaded from DB session add_filter( 'woocommerce_get_cart_item_from_session', function( $cart_item, $values, $key ) { $price_val = $values['owlb_price'] ?? ( $cart_item['owlb_price'] ?? null ); if ( $price_val !== null && strlen( (string) $price_val ) > 0 ) { $unit_price = floatval( $price_val ); if ( $unit_price >= 0 ) { $cart_item['owlb_price'] = $unit_price; $cart_item['_is_order_again'] = true; $cart_item['_order_again_unit_total'] = $unit_price; $cart_item['_order_again_unit_subtotal'] = $unit_price; if ( isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) ) { $cart_item['data']->owlb_custom_price = $unit_price; $cart_item['data']->set_price( $unit_price ); $cart_item['data']->set_regular_price( $unit_price ); $cart_item['data']->set_sale_price( '' ); } } } if ( isset( $values['owlb_design_id'] ) ) { $cart_item['owlb_design_id'] = $values['owlb_design_id']; } return $cart_item; }, 999999, 3 ); // Unhook theme's unpatched priority 20 and priority 150 price calculators add_action( 'wp_loaded', function() { global $wp_filter; if ( isset( $wp_filter['woocommerce_before_calculate_totals'] ) ) { unset( $wp_filter['woocommerce_before_calculate_totals']->callbacks[10] ); unset( $wp_filter['woocommerce_before_calculate_totals']->callbacks[20] ); } remove_action( 'woocommerce_before_calculate_totals', 'custom_calculate_totals', 150 ); }, 999 ); // Re-add safe pricing logic for standard items while preserving designer prices add_action( 'woocommerce_before_calculate_totals', function( $cart_object ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { return; } static $running = false; if ( $running ) return; $running = true; // 1. Process standard site items with attachment pricing rules (skipping designer items) $pricing_rules = function_exists( 'get_field' ) ? get_field( 'attachment_pricing', 'option' ) : null; if ( ! empty( $pricing_rules ) && is_array( $pricing_rules ) ) { foreach ( $cart_object->get_cart() as $cart_item ) { if ( ! empty( $cart_item['owlb_price'] ) ) { continue; } $product = $cart_item['data'] ?? null; if ( ! $product || ! is_object( $product ) ) continue; $qty = $cart_item['quantity'] ?? 1; $original_price = floatval( $product->get_price() ); $adjustment = 0; if ( ! empty( $cart_item['addons'] ) && is_array( $cart_item['addons'] ) ) { foreach ( $cart_item['addons'] as $addon ) { $addon_price = floatval( $addon['price'] ?? 0 ); $adjustment -= $addon_price; foreach ( $pricing_rules as $rule ) { if ( strtolower( trim( $rule['attachment_name'] ?? '' ) ) === strtolower( trim( $addon['value'] ?? '' ) ) && $qty >= intval( $rule['min_qty'] ?? 0 ) && $qty <= intval( $rule['max_qty'] ?? 999999 ) ) { $adjustment +=floatval( $rule['price'] ?? 0 ); break; } } } } if ( function_exists( 'is_product_with_builder' ) && is_product_with_builder( 'patches' , $product->get_id() ) ) { $product->set_price( $original_price + $adjustment ); } } } if ( ! isset( $GLOBALS['cart_object_rank_number_price_seted'] ) || ! is_array( $GLOBALS['cart_object_rank_number_price_seted'] ) ) { $GLOBALS['cart_object_rank_number_price_seted'] = []; } foreach ( $cart_object->get_cart() as $hash => $value ) { // Priority 1: Designer custom price override $price_val = $value['owlb_price'] ?? ( $value['data']->owlb_custom_price ?? ( $_REQUEST['owlb_price'] ?? ( $_GET['owlb_price'] ?? null ) ) ); if ( $price_val !== null && strlen( (string) $price_val ) > 0 ) { $unit_price = floatval( $price_val ); if ( $unit_price >= 0 && isset( $value['data'] ) && is_object( $value['data'] ) ) { $value['data']->owlb_custom_price = $unit_price; $value['data']->set_price( $unit_price ); $value['data']->set_regular_price( $unit_price ); $value['data']->set_sale_price( '' ); // Mark item in theme's global bypass array so theme.php skips recalculation if ( ! in_array( $hash, $GLOBALS['cart_object_rank_number_price_seted'], true ) ) { $GLOBALS['cart_object_rank_number_price_seted'][] = $hash; } // Zero out WC_Product_Addons price adjustments on cart contents if ( isset( $cart_object->cart_contents[ $hash ] ) ) { $cart_object->cart_contents[ $hash ]['addons_price'] = 0; if ( ! empty( $cart_object->cart_contents[ $hash ]['addons'] ) && is_array( $cart_object->cart_contents[ $hash ]['addons'] ) ) { foreach ( $cart_object->cart_contents[ $hash ]['addons'] as &$ad ) { $ad['price'] = 0; } } } // Wipe out stored dynamic pricing adjustments for designer items if ( isset( $cart_object->cart_contents[ $hash ]['discounts'] ) ) { unset( $cart_object->cart_contents[ $hash ]['discounts'] ); } if ( isset( $cart_object->cart_contents[ $hash ]['discounts_before_tax'] ) ) { unset( $cart_object->cart_contents[ $hash ]['discounts_before_tax'] ); } continue; // Skip theme's patch builder pricing calculations for designer items } } // Priority 2: Standard theme patch builder pricing calculations for standard site items $product = $value['data']; if ( ! is_object( $product ) ) continue; $original_price = floatval( get_field( 'base_price', $product->get_id() ) ); if ( ! $original_price ) { $original_price = floatval( $product->get_price() ); } $pricing_rules = get_field( 'attachment_pricing', $product->get_id() ); $adjustment = 0; $qty = intval( $value['quantity'] ?? 1 ); if ( ! empty( $value['addons'] ) && is_array( $value['addons'] ) && ! empty( $pricing_rules ) && is_array( $pricing_rules ) ) { foreach ( $value['addons'] as $addon ) { foreach ( $pricing_rules as $rule ) { if ( strtolower( trim( $rule['attachment_name'] ?? '' ) ) === strtolower( trim( $addon['value'] ?? '' ) ) && $qty >= intval( $rule['min_qty'] ?? 0 ) && $qty <= intval( $rule['max_qty'] ?? 999999 ) ) { $adjustment +=floatval( $rule['price'] ?? 0 ); break; } } } } if ( function_exists( 'is_product_with_builder' ) && is_product_with_builder( 'patches' , $product->get_id() ) ) { $product->set_price( $original_price + $adjustment ); } } // 2. Call theme's custom_calculate_totals for standard items if ( function_exists( 'custom_calculate_totals' ) ) { custom_calculate_totals( $cart_object ); } $running = false; }, 1 ); // Disable WooCommerce Dynamic Pricing plugin for designer items (preserves designer unit price) add_filter( 'woocommerce_dynamic_pricing_process_product_discounts', function( $process, $product = null, $module_id = '', $module = null, $cart_item = null ) { if ( is_array( $cart_item ) ) { if ( ! empty( $cart_item['owlb_price'] ) || ! empty( $cart_item['owlb_design_id'] ) ) { return false; } } if ( ! empty( $_GET['owlb_price'] ) || ! empty( $_REQUEST['owlb_price'] ) || ! empty( $_GET['owl_add_to_cart'] ) ) { return false; } return $process; }, 999999, 5 ); add_filter( 'woocommerce_dynamic_pricing_is_object_discounted', function( $is_discounted, $cart_item = null, $cart_item_key = '' ) { if ( is_array( $cart_item ) ) { if ( ! empty( $cart_item['owlb_price'] ) || ! empty( $cart_item['owlb_design_id'] ) ) { return false; } } if ( ! empty( $_GET['owlb_price'] ) || ! empty( $_REQUEST['owlb_price'] ) || ! empty( $_GET['owl_add_to_cart'] ) ) { return false; } return $is_discounted; }, 999999, 3 ); // Helper to resolve designer unit price for a given WC_Product instance if ( ! function_exists( 'owlb_get_product_unit_price' ) ) { function owlb_get_product_unit_price( $product ) { if ( is_object( $product ) && isset( $product->owlb_custom_price ) && $product->owlb_custom_price !== null ) { return $product->owlb_custom_price; } if ( function_exists( 'WC' ) && WC()->cart && ! empty( WC()->cart->get_cart() ) ) { $product_id = is_object( $product ) && method_exists( $product, 'get_id' ) ? intval( $product->get_id() ) : 0; foreach ( WC()->cart->get_cart() as $cart_item ) { $price_val = $cart_item['owlb_price'] ?? null; if ( $price_val !== null && strlen( (string) $price_val ) > 0 ) { $item_id = 0; if ( ! empty( $cart_item['product_id'] ) ) { $item_id = intval( $cart_item['product_id'] ); } elseif ( isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) && method_exists( $cart_item['data'], 'get_id' ) ) { $item_id = intval( $cart_item['data']->get_id() ); } if ( ! $product_id || ! $item_id || $product_id === $item_id ) { $unit_price = floatval( $price_val ); if ( $unit_price >= 0 ) { if ( is_object( $product ) ) { $product->owlb_custom_price = $unit_price; } return $unit_price; } } } } } if ( ! function_exists( 'owlb_get_edit_design_url' ) ) { function owlb_get_edit_design_url( $cart_item, $cart_item_key ) { $product_id = ! empty( $cart_item['product_id'] ) ? intval( $cart_item['product_id'] ) : ( isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) ? intval( $cart_item['data']->get_id() ) : 0 ); $design_id = $cart_item['owlb_design_id'] ?? ( $cart_item['owlb_token'] ?? '' ); if ( ! $design_id || ! $product_id ) { return ''; } $user_id = is_user_logged_in() ? get_current_user_id() : 0; $user_email = is_user_logged_in() ? ( wp_get_current_user()->user_email ) : ''; $user_name = is_user_logged_in() ? ( wp_get_current_user()->display_name ) : ''; $exp = time() + 86400; $secret = defined('OWL_MEDIA_SECRET') ? OWL_MEDIA_SECRET : 'OwlWP2026!BadgeSave#Secure'; $sig_payload = "{$user_id}|{$user_email}|{$product_id}|{$exp}"; $sig = hash_hmac('sha256', $sig_payload, $secret); $params = [ 'woo_user_id' => $user_id, 'woo_email' => $user_email, 'woo_name' => $user_name, 'woo_product' => $product_id, 'woo_exp' => $exp, 'woo_sig' => $sig, 'owlb_design_id' => $design_id, 'replace_cart_item' => $cart_item_key, ]; return 'https://designer.owlbadges.com/?' . http_build_query($params); } } // Force get_price() to return our custom unit price even if ACF/Dynamic Pricing/PAO filters get_price add_filter( 'woocommerce_product_get_price', function( $price, $product ) { $custom_price = owlb_get_product_unit_price( $product ); return $custom_price !== null ? $custom_price : $price; }, 999999, 2 ); add_filter( 'woocommerce_product_variation_get_price', function( $price, $product ) { $custom_price = owlb_get_product_unit_price( $product ); return $custom_price !== null ? $custom_price : $price; }, 999999, 2 ); add_filter( 'woocommerce_product_get_regular_price', function( $price, $product ) { $custom_price = owlb_get_product_unit_price( $product ); return $custom_price !== null ? $custom_price : $price; }, 999999, 2 ); add_filter( 'woocommerce_product_get_sale_price', function( $price, $product ) { $custom_price = owlb_get_product_unit_price( $product ); return $custom_price !== null ? $custom_price : $price; }, 999999, 2 ); add_filter( 'woocommerce_get_price_html', function( $price_html, $product ) { $custom_price = owlb_get_product_unit_price( $product ); return $custom_price !== null ? wc_price( $custom_price ) : $price_html; }, 999999, 2 ); add_filter( 'woocommerce_cart_product_price', function( $price_html, $product ) { $custom_price = owlb_get_product_unit_price( $product ); return $custom_price !== null ? wc_price( $custom_price ) : $price_html; }, 999999, 2 ); // Guarantee cart HTML display uses our unit price and subtotal add_filter( 'woocommerce_cart_item_price', function( $price_html, $cart_item, $cart_item_key ) { $unit_price = null; $source = 'none'; if ( isset( $cart_item['owlb_price'] ) && strlen( (string) $cart_item['owlb_price'] ) > 0 ) { $unit_price = floatval( $cart_item['owlb_price'] ); $source = 'cart_item'; } elseif ( isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) && isset( $cart_item['data']->owlb_custom_price ) ) { $unit_price = floatval( $cart_item['data']->owlb_custom_price ); $source = 'product_object'; } elseif ( function_exists( 'WC' ) && WC()->cart ) { $session_cart = WC()->cart->get_cart(); if ( isset( $session_cart[ $cart_item_key ]['owlb_price'] ) && strlen( (string) $session_cart[ $cart_item_key ]['owlb_price'] ) > 0 ) { $unit_price = floatval( $session_cart[ $cart_item_key ]['owlb_price'] ); $source = 'session_cart'; } else { $p_val = owlb_get_product_unit_price( $cart_item['data'] ?? null ); if ( $p_val !== null ) { $unit_price = $p_val; $source = 'owlb_get_product_unit_price'; } } } if ( $unit_price !== null && $unit_price >= 0 ) { return wc_price( $unit_price ) . ''; } return $price_html . ''; }, 999999, 3 ); add_filter( 'woocommerce_cart_item_subtotal', function( $subtotal_html, $cart_item, $cart_item_key ) { $unit_price = null; if ( isset( $cart_item['owlb_price'] ) && strlen( (string) $cart_item['owlb_price'] ) > 0 ) { $unit_price = floatval( $cart_item['owlb_price'] ); } elseif ( isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) && isset( $cart_item['data']->owlb_custom_price ) ) { $unit_price = floatval( $cart_item['data']->owlb_custom_price ); } elseif ( function_exists( 'WC' ) && WC()->cart ) { $session_cart = WC()->cart->get_cart(); if ( isset( $session_cart[ $cart_item_key ]['owlb_price'] ) && strlen( (string) $session_cart[ $cart_item_key ]['owlb_price'] ) > 0 ) { $unit_price = floatval( $session_cart[ $cart_item_key ]['owlb_price'] ); } } if ( $unit_price !== null && $unit_price >= 0 ) { $qty = ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 1; return wc_price( $unit_price * $qty ); } return $subtotal_html; }, 999999, 3 ); // ── 2. Replace cart thumbnail with designer preview image ───────────────────── add_filter( 'woocommerce_cart_item_thumbnail', function( $thumbnail, $cart_item, $cart_item_key ) { // Priority: owlb_preview_image (URL) → form-collar-image // NOTE: form-coin-front-image is intentionally skipped — our designer sends // the composite (front+back) as owlb_preview_image; using form-coin-front-image // too would cause the website's own plugin to show 4 coins instead of 2. $preview = ''; if ( ! empty( $cart_item['owlb_preview_image'] ) ) { $preview = $cart_item['owlb_preview_image']; } elseif ( ! empty( $cart_item['form-collar-image'] ) ) { $preview = $cart_item['form-collar-image']; } if ( ! $preview ) { return $thumbnail; } if ( strpos( $preview, 'data:image/' ) === 0 ) { $src = esc_attr( $preview ); } else { $src = esc_url( $preview ); } return 'Design Preview'; }, 99, 3 ); // ── 3. Display design details in cart & checkout ────────────────────────────── add_filter( 'woocommerce_get_item_data', function( $data, $cart_item ) { // Preview image (URL only — skip base64) $preview_img = ! empty( $cart_item['owlb_preview_image'] ) ? $cart_item['owlb_preview_image'] : ''; if ( ! $preview_img && ! empty( $cart_item['form-coin-front-image'] ) ) { $preview_img = $cart_item['form-coin-front-image']; } if ( ! $preview_img && ! empty( $cart_item['form-collar-image'] ) ) { $preview_img = $cart_item['form-collar-image']; } if ( $preview_img && strpos( $preview_img, 'data:image/' ) !== 0 ) { $img_url = esc_url( $preview_img ); $data[] = [ 'name' => 'Badge Preview', 'value' => $img_url, 'display' => 'Design Preview', ]; } // Detect product type from cart data $is_coin = ! empty( $cart_item['form-coin-front-paneltext1'] ) || ! empty( $cart_item['coin-front-paneltext1'] ) || ! empty( $cart_item['owlb_coin_edge'] ); $is_collar = ! $is_coin && ( ! empty( $cart_item['form-collar-text'] ) || ! empty( $cart_item['collarPinTextPanel'] ) ); if ( $is_coin ) { // ── Challenge Coin display ───────────────────────────────────────── // Helper: read first non-empty value from a list of keys $get = function( array $keys ) use ( $cart_item ) { foreach ( $keys as $k ) { if ( ! empty( $cart_item[ $k ] ) ) { return $cart_item[ $k ]; } } return ''; }; $rows = [ [ 'Front Text Panel 1', [ 'form-coin-front-paneltext1', 'coin-front-paneltext1' ] ], [ 'Front Text Color', [ 'form-coin-front-panel1-color-name', 'coin-front-top-textcolorname' ] ], [ 'Front Text Font', [ 'form-coin-front-font', 'coin-front-font' ] ], [ 'Front Text Panel 2', [ 'form-coin-front-paneltext2', 'coin-front-paneltext2' ] ], [ 'Front Text 2 Color', [ 'form-coin-front-panel2-color-name', 'coin-front-bottom-textcolorname' ] ], [ 'Back Text Panel 1', [ 'form-coin-back-paneltext1', 'coin-back-paneltext1' ] ], [ 'Back Text Color', [ 'form-coin-back-panel1-color-name', 'coin-back-top-textcolorname' ] ], [ 'Back Text Font', [ 'form-coin-back-font', 'coin-back-font' ] ], [ 'Back Text Panel 2', [ 'form-coin-back-paneltext2', 'coin-back-paneltext2' ] ], [ 'Back Text 2 Color', [ 'form-coin-back-panel2-color-name', 'coin-back-bottom-textcolorname' ] ], [ 'Base Color', [ 'owlb_coin_base_color', 'form-coin-front-basecolor-name', 'coin-front-basecolorname' ] ], [ 'Edge', [ 'owlb_coin_edge' ] ], [ 'Front Text Ring', [ 'owlb_coin_front_ring' ] ], [ 'Front Inner Circle', [ 'owlb_coin_front_inner' ] ], [ 'Front Element', [ 'owlb_coin_front_element' ] ], [ 'Back Text Ring', [ 'owlb_coin_back_ring' ] ], [ 'Back Inner Circle', [ 'owlb_coin_back_inner' ] ], [ 'Back Element', [ 'owlb_coin_back_element' ] ], [ 'Packaging', [ 'owlb_coin_packaging' ] ], ]; foreach ( $rows as [$label, $keys] ) { $val = $get( $keys ); if ( $val !== '' ) { $data[] = [ 'name' => $label, 'value' => esc_html( $val ), 'display' => esc_html( $val ), ]; } } if ( ! empty( $cart_item['owlb_design_id'] ) ) { $data[] = [ 'name' => 'Design #', 'value' => esc_html( $cart_item['owlb_design_id'] ), 'display' => esc_html( $cart_item['owlb_design_id'] ), ]; } } elseif ( $is_collar ) { // ── Collar-pin display ───────────────────────────────────────────── $cp_display = [ 'form-collar-text' => 'Pin Text', 'form-collar-text-color-name' => 'Pin Text Color', 'form-collar-text-style' => 'Pin Text Style', 'form-collar-attachment' => 'Attachment', ]; $cp_fallbacks = [ 'form-collar-text' => 'collarPinTextPanel', 'form-collar-text-color-name' => 'collarPinTextColorName', 'form-collar-text-style' => 'collarPinTextStyle', 'form-collar-attachment' => 'collarPinAttachment', ]; foreach ( $cp_display as $key => $label ) { $val = ! empty( $cart_item[ $key ] ) ? $cart_item[ $key ] : ( ! empty( $cart_item[ $cp_fallbacks[ $key ] ] ) ? $cart_item[ $cp_fallbacks[ $key ] ] : '' ); if ( $val ) { $data[] = [ 'name' => $label, 'value' => esc_html( $val ), 'display' => esc_html( $val ), ]; } } if ( ! empty( $cart_item['owlb_design_id'] ) ) { $data[] = [ 'name' => 'Design #', 'value' => esc_html( $cart_item['owlb_design_id'] ), 'display' => esc_html( $cart_item['owlb_design_id'] ), ]; } } else { // ── Standard badge / patch display ──────────────────────────────── $display = [ 'owlb_type' => 'Badge Type', 'owlb_size' => 'Size', 'owlb_color' => 'Color', 'owlb_colors' => 'Patch Colors', 'owlb_font' => 'Font', 'owlb_text_1' => 'Line 1', 'owlb_text_2' => 'Line 2', 'owlb_text_3' => 'Line 3', 'owlb_text_4' => 'Line 4', 'owlb_seal' => 'Seal', 'owlb_attachment' => 'Attachment', 'owlb_design_id' => 'Design #', ]; foreach ( $display as $key => $label ) { if ( ! empty( $cart_item[ $key ] ) ) { $data[] = [ 'name' => $label, 'value' => esc_html( $cart_item[ $key ] ), 'display' => esc_html( $cart_item[ $key ] ), ]; } } } return $data; }, 10, 2 ); // ── 4. Save design details to order line item (visible in admin orders) ──────── add_action( 'woocommerce_checkout_create_order_line_item', function( $item, $cart_item_key, $values, $order ) { $meta_fields = [ 'owlb_design_id' => 'Design ID', 'owlb_template' => 'Template', 'owlb_type' => 'Badge Type', 'owlb_size' => 'Size', 'owlb_color' => 'Color', 'owlb_colors' => 'Patch Colors', 'owlb_font' => 'Font', 'owlb_text_1' => 'Line 1', 'owlb_text_type_1' => 'Line 1 Type', 'owlb_text_2' => 'Line 2', 'owlb_text_type_2' => 'Line 2 Type', 'owlb_text_3' => 'Line 3', 'owlb_text_type_3' => 'Line 3 Type', 'owlb_text_4' => 'Line 4', 'owlb_text_type_4' => 'Line 4 Type', 'owlb_seal' => 'Seal', 'owlb_attachment' => 'Attachment', 'owlb_price' => 'Design Price', 'owlb_preview_image' => 'Badge Preview URL', // Collar-pin specific 'form-collar-text' => 'Pin Text', 'form-collar-text-color-name' => 'Pin Text Color', 'form-collar-text-style' => 'Pin Text Style', 'form-collar-attachment' => 'Collar Attachment', 'collarPinTextPanel' => 'Pin Text (alt)', 'collarPinTextColorName' => 'Pin Text Color (alt)', 'collarPinTextStyle' => 'Pin Text Style (alt)', 'collarPinAttachment' => 'Collar Attachment (alt)', // Challenge-coin specific 'form-coin-front-paneltext1' => 'Front Text Panel 1', 'form-coin-front-paneltext2' => 'Front Text Panel 2', 'form-coin-back-paneltext1' => 'Back Text Panel 1', 'form-coin-back-paneltext2' => 'Back Text Panel 2', 'form-coin-front-panel1-color-name' => 'Front Text Color', 'form-coin-front-panel2-color-name' => 'Front Text 2 Color', 'form-coin-back-panel1-color-name' => 'Back Text Color', 'form-coin-back-panel2-color-name' => 'Back Text 2 Color', 'form-coin-front-basecolor-name' => 'Front Base Color', 'form-coin-back-basecolor-name' => 'Back Base Color', 'form-coin-front-font' => 'Front Text Font', 'form-coin-back-font' => 'Back Text Font', 'form-coin-edges-price' => 'Coin Edge Price', 'owlb_coin_edge' => 'Edge', 'owlb_coin_packaging' => 'Packaging', 'owlb_coin_base_color' => 'Base Color', 'owlb_coin_front_ring' => 'Front Text Ring', 'owlb_coin_front_inner' => 'Front Inner Circle', 'owlb_coin_back_ring' => 'Back Text Ring', 'owlb_coin_back_inner' => 'Back Inner Circle', 'owlb_coin_front_element' => 'Front Element', 'owlb_coin_back_element' => 'Back Element', ]; foreach ( $meta_fields as $key => $label ) { if ( ! empty( $values[ $key ] ) && strpos( $values[ $key ], 'data:image/' ) !== 0 ) { $item->add_meta_data( $label, $values[ $key ], true ); } } }, 10, 4 ); // ── 5. Restore our custom keys from WooCommerce session ─────────────────────── // Another plugin (owl-badge-media-urls.php) may rebuild cart items from session // and only restore the keys it knows about, silently dropping ours. // This filter explicitly re-applies every key we stored so nothing is lost. add_filter( 'woocommerce_get_cart_item_from_session', function( $cart_item, $values, $key ) { $our_keys = [ // Standard owlb 'owlb_design_id', 'owlb_token', 'owlb_template', 'owlb_type', 'owlb_size', 'owlb_color', 'owlb_font', 'owlb_text_1', 'owlb_text_2', 'owlb_text_3', 'owlb_text_4', 'owlb_seal', 'owlb_attachment', 'owlb_colors', 'owlb_price', 'owlb_qty', 'owlb_preview_image', 'owlb_pin_text', 'owlb_pin_text_color', 'owlb_pin_text_style', // Collar-pin 'form-collar-text', 'form-collar-text-color', 'form-collar-text-color-name', 'form-collar-text-style', 'form-collar-text-size-label', 'form-collar-attachment', 'form-collar-image', 'form-collar-image-wm-off', 'collarPinTextPanel', 'collarPinTextColor', 'collarPinTextColorName', 'collarPinTextStyle', 'collarPinTextSizeLabel', 'collarPinAttachment', // Challenge coin — form-coin-* primary keys 'form-coin-front-paneltext1', 'form-coin-front-paneltext2', 'form-coin-back-paneltext1', 'form-coin-back-paneltext2', 'form-coin-front-panel1-color-name', 'form-coin-front-panel1-color-code', 'form-coin-front-panel2-color-name', 'form-coin-front-panel2-color-code', 'form-coin-back-panel1-color-name', 'form-coin-back-panel1-color-code', 'form-coin-back-panel2-color-name', 'form-coin-back-panel2-color-code', 'form-coin-front-basecolor-name', 'form-coin-front-basecolor-code', 'form-coin-back-basecolor-name', 'form-coin-back-basecolor-code', 'form-coin-front-bordercolor-name', 'form-coin-front-bordercolor-code', 'form-coin-back-bordercolor-name', 'form-coin-back-bordercolor-code', 'form-coin-front-bgcolor-name', 'form-coin-front-bgcolor-code', 'form-coin-back-bgcolor-name', 'form-coin-back-bgcolor-code', 'form-coin-front-seal-id', 'form-coin-back-seal-id', 'form-coin-front-seal-image', 'form-coin-back-seal-image', 'form-coin-front-image', 'form-coin-back-image', 'form-coin-edges-id', 'form-coin-edges-price', 'form-coin-front-font', 'form-coin-back-font', // Challenge coin — coin-* aliases 'coin-front-paneltext1', 'coin-front-paneltext2', 'coin-back-paneltext1', 'coin-back-paneltext2', 'coin-front-top-textcolorname', 'coin-front-top-textcolorcode', 'coin-front-bottom-textcolorname', 'coin-front-bottom-textcolorcode', 'coin-back-top-textcolorname', 'coin-back-top-textcolorcode', 'coin-back-bottom-textcolorname', 'coin-back-bottom-textcolorcode', 'coin-front-basecolorname', 'coin-front-basecolorcode', 'coin-back-basecolorname', 'coin-back-basecolorcode', 'coin-front-bordercolorname', 'coin-front-bordercolorcode', 'coin-back-bordercolorname', 'coin-back-bordercolorcode', 'coin-front-bgcolorname', 'coin-front-bgcolorcode', 'coin-back-bgcolorname', 'coin-back-bgcolorcode', 'coin-front-seal-imageid', 'coin-front-seal-image', 'coin-back-seal-imageid', 'coin-back-seal-image', 'coin-front-image', 'coin-back-image', 'coin-edges-id', 'coin-edges-price', 'coin-front-font', 'coin-front-separator', 'coin-back-font', 'coin-back-separator', // Challenge coin — owlb_coin_* extended fields 'owlb_coin_edge', 'owlb_coin_edge_price', 'owlb_coin_packaging', 'owlb_coin_base_color', 'owlb_coin_front_ring', 'owlb_coin_front_inner', 'owlb_coin_front_element', 'owlb_coin_back_ring', 'owlb_coin_back_inner', 'owlb_coin_back_element', 'owlb_unique_key', ]; foreach ( $our_keys as $k ) { if ( isset( $values[ $k ] ) && ! isset( $cart_item[ $k ] ) ) { $cart_item[ $k ] = $values[ $k ]; } } if ( isset( $values['owlb_price'] ) && strlen( (string) $values['owlb_price'] ) > 0 ) { $unit_price = floatval( $values['owlb_price'] ); if ( $unit_price >= 0 ) { $cart_item['owlb_price'] = $unit_price; if ( isset( $cart_item['data'] ) && is_object( $cart_item['data'] ) ) { $cart_item['data']->owlb_custom_price = $unit_price; $cart_item['data']->set_price( $unit_price ); } } } return $cart_item; }, 20, 3 ); // ── 6. Show design meta cleanly in admin order detail page ──────────────────── add_filter( 'woocommerce_order_item_display_meta_key', function( $key ) { // Already using human-readable labels above — return as-is return $key; } ); California Highway Patrol Badge 16-H30CA | Owl Badges
Hoot Hoot! Call For 1st Order Discount 626-412-1200
HomeShop7 Point Star
California Highway Patrol Badge 16-H30CA
California Highway Patrol Badge 16-H30CA view 2
California Highway Patrol Badge 16-H30CA view 3
California Highway Patrol Badge 16-H30CA view 4
California Highway Patrol Badge 16-H30CA view 5

California Highway Patrol Badge 16-H30CA

Style 16-H30CA · 7 point star

$150.00 per badge · free mold and setup
Design now Get a quote
At a glance
Shape7 Point Star
Text panels3
Seal or logo wellCentered, 41% of face
MaterialDie-struck alloy brass
Dimensions2.25″ × 3.13″, .25 lb
Mold and setupFree

What each panel holds

Panel 1
Up to 40 characters
Panel 2
Up to 40 characters
Panel 3
Up to 24 characters

Sizes and order minimums

Size Minimum
3" x 2.91" Premium 1 piece
1.25" x 1.21" Lapel Pin 50 pieces

Order this badge for your team

Department buyers comparing shield and star layouts can browse every configuration at department police badge styles, elected offices rebadging on a seal change should start at county sheriff badge styles, and single officers can order one at a time from individual officer badges.

More 7 point star styles

badge sheriff a gold star shaped badge with blue and yellow text
7 Point Star Badge 16-H20
Custom gold 6 pointed star metal badge with detailed silver panels, featuring a banner at the top that reads “SENIOR AGENT” and a circular blue and white ring around the center with the text “BAIL ENFORCEMENT AGENT VT.”
Bail Enforcement Agent Badge 7 Point Star Ribbons…
Custom 7 point stat flex badge for the Forge Valley Police Department officer, featuring a polished silver finish. The title "OFFICER" is prominently displayed at the top in bold black letters, surrounding a central emblem representing the state of South Carolina. Below, "POLICE DEPARTMENT" and "FORGE VALLEY" are elegantly showcased, with the badge number "123" clearly visible at the bottom. A Velcro attachment ensures secure and versatile wear.
Vintage 7 Point Star Badge with Floral Accents,…
16-H30 Buy Custom Sheriff Badges And Design Create Build and Order Personalized Sheriff Badges Deputy Gold
Traditional 7 Point Star Badge with Laurel Accents,…