Something like that:
// 1. Display multiple upload file field
add_action( 'woocommerce_after_order_notes', 'add_custom_checkout_field' );
function add_custom_checkout_field($checkout) {
echo '<div class="woocommerce-additional-fields__field-wrapper">';
woocommerce_form_field('certificate', array(
'type' => 'file',
'class' => array('form-row-wide'),
'label' => __('Files', 'woocommerce'),
'required' => false,
'multiple' => 'multiple',
'name' => 'certificate[]', // as array
'accept' => '.pdf,.doc,.docx,.rtf,.txt',
), '');
echo '</div>';
}
// 2. Save multiple uploaded files URL and name to order meta
add_action( 'woocommerce_checkout_create_order', 'save_checkout_uploaded_files', 10, 2 );
function save_checkout_uploaded_files( $order, $data ){
if( !empty($_FILES['certificate']['name'][0]) ) {
$uploaded_files = array();
foreach ($_FILES['certificate']['name'] as $key => $value) {
if ($_FILES['certificate']['error'][$key] === UPLOAD_ERR_OK) {
$file = array(
'name' => $_FILES['certificate']['name'][$key],
'type' => $_FILES['certificate']['type'][$key],
'tmp_name' => $_FILES['certificate']['tmp_name'][$key],
'error' => $_FILES['certificate']['error'][$key],
'size' => $_FILES['certificate']['size'][$key]
);
// Handle upload safely using WP functions
$upload = wp_handle_upload($file, array('test_form' => false));
if (!isset($upload['error'])) {
$uploaded_files[] = array(
'file_url' => $upload['url'],
'file_name' => $file['name']
);
}
}
}
if (!empty($uploaded_files)) {
$order->update_meta_data( '_checkout_upload', $uploaded_files );
}
}
}
// 3. Helper function to display uploaded files as links
function display_uploaded_files_list($files) {
if (!empty($files) && is_array($files)) {
echo '<p>' . __("Files Uploaded:", 'woocommerce') . '</p><ul>';
foreach ($files as $file) {
printf('<li><a href="%s" target="_blank" rel="noopener noreferrer">%s</a></li>', esc_url($file['file_url']), esc_html($file['file_name']));
}
echo '</ul>';
}
}
// 4. Display uploaded files in admin order page
add_action('woocommerce_admin_order_data_after_billing_address', 'display_uploaded_files_in_admin_orders');
function display_uploaded_files_in_admin_orders( $order ) {
$uploaded_files = $order->get_meta( '_checkout_upload' );
display_uploaded_files_list($uploaded_files);
}
// 5. Display uploaded files on thank you page
add_action('woocommerce_order_details_after_order_table', 'display_uploaded_files_in_thankyou');
function display_uploaded_files_in_thankyou( $order ) {
$uploaded_files = $order->get_meta( '_checkout_upload' );
display_uploaded_files_list($uploaded_files);
}
// 6. Display uploaded files in WooCommerce emails
add_action('woocommerce_email_customer_details', 'display_uploaded_files_in_email');
function display_uploaded_files_in_email( $order ) {
$uploaded_files = $order->get_meta( '_checkout_upload' );
display_uploaded_files_list($uploaded_files);
}