You can use woocommerce_review_order_before_payment
action hook to display radio buttons before payment section in WooCommerce checkout page as follow:
// Display a Custom radio buttons input fields before checkout available payment gateways section
add_action( 'woocommerce_review_order_before_payment','checkout_customer_type_radio_buttons' );
function checkout_customer_type_radio_buttons() {
echo '<div id="custom-radio-buttons">';
echo '<h3>' . __("Your section sub-title", "woocommerce") . '</h3>';
// Here below set your field Id (or field key)
$field_id = '_custom_key';
woocommerce_form_field( $field_id, array(
'type' => 'radio',
'class' => array( 'some-class' ),
'options' => array(
'First Option' => __('First Option', 'woocommerce'),
'Second Option' => __('Second Option', 'woocommerce'),
),
'default' => 'First Option',
'required' => true,
), WC()->checkout->get_value( $field_id ) );
echo '</div>';
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Addition - For a better display you can use instead the following:
// Display a Custom radio buttons input fields before checkout available payment gateways section
add_action( 'woocommerce_review_order_before_payment','checkout_customer_type_radio_buttons' );
function checkout_customer_type_radio_buttons() {
## YOUR RADIO BUTTONS SETTINGS BELOW:
$field_id = '_custom_key'; // HERE below set your field Id (or field key)
$options = array( // HERE below set your radio button options in the array:
__('First Option', 'woocommerce'),
__('Second Option', 'woocommerce'),
__('Third Option', 'woocommerce'),
);
$default = reset($options); // HERE set default checked option (The first one is set in here)
echo '<div id="custom-radio-buttons">';
echo '<h3>' . __("Your section sub-title (optional)", "woocommerce") . '</h3>';
echo '<p class="form-row some-class validate-required" id="'.$field_id.'_field">
<span class="woocommerce-input-wrapper">';
$value = WC()->checkout->get_value( $field_id );
$value = empty($value) ? $default : $value;
// Loop through defined options array
foreach( $options as $option ) {
$checked = $option === $value ? ' checked="checked"' : '';
echo '<label for="'.$field_id.'_'.$option.'"><input type="radio" class="input-radio " name="'.$field_id.'" id="'.$field_id.'_'.$option.'" value="'.$option.'"'.$checked.'> ' . $option . '</label>';
}
echo '</span></p></div>';
}
Related thread: Show/Hide WooCommerce Shipping Rates Based on Radio Buttons