Criando campos customizados no checkout do WooCommerce
Como adicionar um campo personalizado no checkout do WooCommerce na mão, com hooks: criar o campo, validar, salvar no pedido e exibir no painel do admin.
Existem plugins que adicionam campos no checkout do WooCommerce em poucos cliques. Mas quem quer liberdade real de customização — e não ficar refém de plugin — ganha muito aprendendo a fazer isso no código. Aqui vai o passo a passo completo: criar o campo, validar, salvar no pedido e ainda exibir a informação no painel do admin.
Por que fazer isso no código
Grande parte do ecossistema do WordPress trabalha com hooks (ganchos): pontos onde você pode injetar ou remover comportamento em diversos lugares do sistema. O WooCommerce expõe dezenas deles no fluxo de checkout, e é exatamente isso que vamos usar.
Existe muito material em inglês (e algum em português) sobre o assunto, mas a ideia aqui é explicar de forma simples e direta. Se você é novato no código do WordPress, este é um bom primeiro contato com hooks.
Dominar os hooks dá mais liberdade do que qualquer plugin de checkout pronto.
Criando o campo customizado
Campos customizados geralmente entram depois dos campos padrão do checkout. Na prática, o último campo padrão é o Order Notes (anotações sobre o pedido). Então vamos supor que queremos adicionar um campo logo depois dele.
Você pode colocar esses códigos no functions.php do seu tema — de preferência no tema filho, para não perder a customização numa atualização do tema principal.
add_action( 'woocommerce_after_order_notes', 'meu_campo_customizado' );
function meu_campo_customizado( $checkout ) {
echo '<div id="meu_campo_customizado"><h3>Meu campo customizado</h3>';
woocommerce_form_field( 'meu_campo_customizado', array(
'type' => 'text',
'class' => array( 'meu-campo-customizado-class form-row-wide' ),
'label' => __( 'Meu campo customizado' ),
'placeholder' => __( 'Meu campo customizado' ),
), $checkout->get_value( 'meu_campo_customizado' ) );
echo '</div>';
}
O add_action chama o hook do WooCommerce woocommerce_after_order_notes e diz qual função executar quando ele rodar — no exemplo, meu_campo_customizado. Dentro da função, pedimos ao WooCommerce um campo do tipo texto, com duas classes de CSS para estilização, uma label “Meu campo customizado” e o mesmo texto como placeholder.

Validando o campo
Agora queremos garantir que exista alguma informação digitada nesse campo antes de registrar o pedido. Dá para fazer isso de forma bem simples:
add_action( 'woocommerce_checkout_process', 'validando_meu_campo_customizado' );
function validando_meu_campo_customizado() {
if ( empty( $_POST['meu_campo_customizado'] ) ) {
wc_add_notice( __( 'Você precisa colocar alguma informação no seu campo customizado' ), 'error' );
}
}
A função diz ao hook: se não houver nada escrito no campo após o envio, exiba a mensagem de erro — no caso, “Você precisa colocar alguma informação no seu campo customizado”.

Observação: ao criar o campo, dá para defini-lo como obrigatório passando 'required' => true no array. Isso força o preenchimento. A validação acima serve para checar, na prática, se o conteúdo foi digitado.
Salvando a informação no pedido
Com o preenchimento garantido, vamos pegar a informação e salvar no pedido dentro do WooCommerce.
add_action( 'woocommerce_checkout_create_order', 'meu_campo_customizado_atualizar_meta_do_pedido', 10, 2 );
function meu_campo_customizado_atualizar_meta_do_pedido( $order, $data ) {
if ( ! empty( $_POST['meu_campo_customizado'] ) ) {
$order->update_meta_data( 'Meu Campo Customizado', sanitize_text_field( wp_unslash( $_POST['meu_campo_customizado'] ) ) );
}
}
Aqui usamos o hook woocommerce_checkout_create_order, que entrega o objeto $order antes de ele ser salvo. Em vez de update_post_meta, gravamos o dado com $order->update_meta_data() — o método CRUD do WooCommerce. Como o salvamento acontece logo depois, não precisamos chamar $order->save() manualmente.
Por que CRUD e não update_post_meta? Porque a partir do WooCommerce moderno os pedidos podem ficar em tabelas próprias (o HPOS — High-Performance Order Storage), e aí as funções de post_meta deixam de funcionar de forma confiável. Os métodos get_meta()/update_meta_data() funcionam nos dois modos.
Repare também no sanitize_text_field combinado com wp_unslash: o WordPress aplica slashes nos dados de $_POST, então removemos isso e limpamos o conteúdo. Se alguém tentar enviar algo como <h2>Meu texto</h2>, só o texto Meu texto é salvo.
Bônus: exibir o campo no dashboard do WooCommerce
Com a informação já no banco, fica simples recuperá-la no painel. E adivinha como? Hooks de novo.
add_action( 'woocommerce_admin_order_data_after_billing_address', 'mostrar_meu_campo_customizado_no_dashboard', 10, 1 );
function mostrar_meu_campo_customizado_no_dashboard( $order ) {
echo '<p><strong>' . esc_html__( 'Meu Campo Customizado' ) . ':</strong> ' . esc_html( $order->get_meta( 'Meu Campo Customizado' ) ) . '</p>';
}
O hook diz: exiba isso depois do endereço de cobrança do cliente. Recebemos o $order como parâmetro, recuperamos o valor com $order->get_meta() (de novo, via CRUD — nada de get_post_meta) e escapamos a saída com esc_html() antes de exibir no painel. O resultado fica assim:

Para fechar
Viu só? Não é tão difícil. De forma resumida, dá para adicionar, validar, salvar e exibir um campo de checkout só com hooks — o que dá muito mais liberdade do que depender de um plugin.
Key takeaways
- Adicione o campo com
woocommerce_after_order_notes. - Valide o conteúdo em
woocommerce_checkout_processantes de salvar. - Salve via CRUD com
$order->update_meta_data()+sanitize_text_fieldemwoocommerce_checkout_create_order(compatível com HPOS). - Exiba no admin com
woocommerce_admin_order_data_after_billing_address.