Ir para o conteúdo
DedicatedPHP Contato

Campos personalizados no checkout do WooCommerce: da compra ao backoffice

Aprenda a adicionar campos ao checkout clássico ou ao Checkout Block, validar os dados no servidor e confirmar que chegam ao pedido e ao backoffice.

Campo personalizado do checkout do WooCommerce guardado num pedido e consultado no backoffice

Um campo adicionado ao checkout não está resolvido só por aparecer no ecrã. Para ser útil, tem de responder a uma necessidade concreta, ser validado no servidor, ser guardado associado ao pedido e chegar às pessoas ou aos processos que dele precisam. Cada etapa pode falhar de forma independente.

A implementação também depende do fluxo de checkout ativo. Os hooks do checkout clássico não adicionam, por si só, campos ao Checkout Block. Antes de programar, identifica qual é usado pela loja e planeia o percurso completo dos dados.

Decidir se o dado pertence ao checkout

Decidir se o dado pertence ao checkout — guía visual de DedicatedPHP

Identifica que tarefa requer o dado e quando este tem de estar disponível. Se for indispensável para calcular o pedido, determinar a sua elegibilidade ou preparar a entrega, pode ser necessário pedi-lo antes de confirmar a compra. Se apenas facilitar uma gestão posterior, considera recolhê-lo mais tarde para não criar atrito desnecessário.

Documenta a finalidade, quem utiliza o campo, se é obrigatório e durante quanto tempo deve ser conservado. Verifica se o WooCommerce já tem um campo padrão para essa informação: duplicar um endereço ou um número de telefone sem definir qual prevalece cria discrepâncias. Para dados sensíveis ou de grande impacto, limita a recolha e o acesso e verifica as obrigações de privacidade aplicáveis.

Identificar o fluxo e adicionar o campo

Verifica na página de finalização da compra se é usado o shortcode clássico [woocommerce_checkout] ou o Checkout Block. Analisa também os templates e as extensões que modificam essa página. Não basta reconhecer o design: uma extensão pode alterar o fluxo ou o processamento. Implementa e testa o mecanismo correspondente e não pressuponhas que um campo criado para um fluxo funcionará no outro.

Checkout clássico: hooks de campos e pedidos

O checkout clássico permite modificar os campos com woocommerce_checkout_fields, validar com woocommerce_after_checkout_validation e guardar durante a criação do pedido com woocommerce_checkout_create_order. Este exemplo regista um campo opcional, rejeita entradas que não sejam escalares e limita o texto a 120 caracteres Unicode:

add_filter('woocommerce_checkout_fields', function ($fields) {
    $fields['order']['delivery_instructions'] = [
        'type'      => 'text',
        'label'     => 'Instruções de entrega',
        'required'  => false,
        'priority'  => 25,
        'maxlength' => 120,
        'class'     => ['form-row-wide'],
    ];
    return $fields;
});

add_action('woocommerce_after_checkout_validation', function ($data, $errors) {
    $raw = $data['delivery_instructions'] ?? '';
    if (! is_scalar($raw)) {
        $errors->add('delivery_instructions', 'O valor tem de ser texto.');
        return;
    }

    $value = trim(sanitize_text_field((string) $raw));
    if (preg_match_all('/./us', $value, $matches) === false) {
        $errors->add('delivery_instructions', 'O texto não tem um formato válido.');
        return;
    }
    if (count($matches[0]) > 120) {
        $errors->add('delivery_instructions', 'O texto não pode exceder 120 caracteres.');
    }
}, 10, 2);

add_action('woocommerce_checkout_create_order', function ($order, $data) {
    $raw = $data['delivery_instructions'] ?? '';
    if (! is_scalar($raw)) {
        return;
    }
    $value = trim(sanitize_text_field((string) $raw));
    if ($value !== '') {
        $order->update_meta_data('_delivery_instructions', $value);
    }
}, 10, 2);

O atributo maxlength impõe uma restrição no navegador; não substitui a validação no servidor. O exemplo conta pontos de código Unicode com uma expressão compatível com UTF-8; alguns caracteres, como determinados emojis, ocupam mais de uma unidade UTF-16 no navegador. Se tiverem de ser aceites, define e testa expressamente a regra de comprimento para que a experiência do cliente e o servidor não divirjam.

O exemplo guarda apenas um valor válido e não vazio. Se o campo passar a ser obrigatório, valida também a sua ausência e devolve um erro antes de criar o pedido. Usa um nome interno estável e não o alteres sem planear a migração dos dados existentes.

Checkout Block: API de campos adicionais

Para o Checkout Block, usa a API de campos adicionais do WooCommerce em vez de injetar HTML no formulário. Regista o campo a partir de um plugin ou tema compatível, por exemplo, durante woocommerce_init:

add_action('woocommerce_init', function () {
    if (! function_exists('woocommerce_register_additional_checkout_field')) {
        return;
    }

    woocommerce_register_additional_checkout_field([
        'id'       => 'mi-plugin/delivery-instructions',
        'label'    => 'Instruções de entrega',
        'location' => 'order',
        'type'     => 'text',
        'required' => false,
    ]);
});

A API integra o campo no fluxo de blocos e no respetivo armazenamento associado ao pedido. Se precisares de regras específicas, consulta as opções de sanitização e validação suportadas pela API na instalação concreta e testa o erro de ponta a ponta. Não guardes o mesmo valor em paralelo com outro mecanismo sem decidir qual é a fonte de verdade.

Antes de colocar em produção, verifica se a função de registo existe e consulta a documentação correspondente à versão instalada. Se não estiver disponível, não simules compatibilidade com JavaScript: atualiza ou escolhe uma alternativa compatível com o checkout utilizado e testa num ambiente de staging.

Validar, normalizar e persistir no servidor

A validação no navegador melhora a experiência, mas não é um controlo de segurança. Verifica no servidor a presença quando o campo for obrigatório, o tipo, o comprimento, o formato e a correspondência com as opções permitidas. Para listas fechadas, valida identificadores conhecidos, não texto arbitrário enviado pelo cliente. Se o dado for opcional, define se a ausência e o valor vazio significam o mesmo. Perante um valor inválido, apresenta um erro compreensível e não confirmes o pedido omitindo silenciosamente um dado necessário.

No fluxo clássico, $order->update_meta_data() usa a API CRUD do pedido e evita escrever diretamente nas tabelas ou depender de uma estrutura de armazenamento específica. No Checkout Block, deixa que a API de campos adicionais trate da associação do campo e consulta o valor através da API de pedidos ou do mecanismo documentado para essa integração; não pressuponhas uma chave interna de metadados.

Para verificar a compatibilidade, consulta as definições do WooCommerce e confirma se está ativo o armazenamento de pedidos de alto desempenho (HPOS) ou o armazenamento baseado nas tabelas de publicações. Num ambiente de testes com a mesma configuração, cria um pedido para cada fluxo, lê-o como objeto WC_Order através de wc_get_order($order_id) e verifica o dado com a API CRUD, por exemplo, $order->get_meta('_delivery_instructions') para o campo clássico. Atualiza o pedido e volta a lê-lo; não uses consultas SQL diretas às tabelas internas. Repete as verificações depois de alterar o armazenamento ou atualizar extensões que intervêm no checkout.

Consultar o dado no backoffice

O percurso de verificação operacional consiste em criar um pedido de teste, abrir WooCommerce > Pedidos, entrar na respetiva edição e comparar o valor apresentado com o enviado. Para o checkout clássico, se o metadado não aparecer no ecrã utilizado pela equipa, pode ser apresentada informação administrativa com o seguinte hook de dados do pedido:

add_action('woocommerce_admin_order_data_after_billing_address', function ($order) {
    $value = $order->get_meta('_delivery_instructions');
    if ($value !== '') {
        echo '<p><strong>Instruções de entrega:</strong> '
            . esc_html($value) . '</p>';
    }
});

Este hook e o metadado do exemplo correspondem ao checkout clássico; verifica a sua apresentação no ecrã administrativo ativo na loja. Com HPOS e no ecrã de edição de pedidos baseado em blocos, verifica o resultado real: não pressuponhas que uma extensão do painel clássico abrange automaticamente a nova interface. Usa sempre o objeto do pedido e a API CRUD para ler ou editar dados.

Os campos registados pela API do Checkout Block podem ser integrados nos detalhes do pedido. Confirma-o em WooCommerce > Pedidos com um pedido de teste. Se precisares que outro código consulte o valor, identifica na documentação da API a localização e o mecanismo de leitura para a versão instalada; não adivinhes a chave de metadados. Se não for apresentado, adiciona uma apresentação administrativa compatível com esse ecrã e testa tanto com o armazenamento configurado como com as extensões de administração instaladas.

Se for necessária edição, define os perfis autorizados e guarda as alterações através da API CRUD do pedido. Não apresentes o dado automaticamente em emails, documentos, exportações ou ecrãs públicos: inclui cada destino apenas se existir uma necessidade operacional, limita o acesso e escapa sempre a saída.

Testar o ciclo completo e evitar regressões

Um teste que apenas verifica se o campo é apresentado é insuficiente. Verifica o percurso desde o formulário até à utilização posterior e cobre, no mínimo:

  • Pedido válido com dado preenchido: validar, guardar no pedido correto e consultar no backoffice.
  • Campo opcional vazio e campo obrigatório ausente: verificar o comportamento definido para cada caso.
  • Entrada manipulada, não escalar, demasiado longa ou fora das opções permitidas: confirmar a rejeição no servidor.
  • Texto com acentos e caracteres multibyte, incluindo o limite exato; verifica também a interação com maxlength.
  • Atualização do pedido: verificar o que muda, quem pode alterá-lo e como a alteração se propaga.
  • Checkout clássico e Checkout Block: testar o fluxo ativo e qualquer alteração de modalidade prevista.
  • Permissões e exposição: verificar que só os utilizadores e processos autorizados recebem o valor.

Inclui testes de regressão dos totais, das validações e da criação do pedido. Se uma automatização consumir o campo, testa também o que acontece quando o seu envio falha ou não ocorre. Um sinal de diagnóstico claro é o dado aparecer no navegador, mas não no pedido nem no processo que o deveria utilizar.

Lista de verificação antes da colocação em produção

Lista de verificação antes da colocação em produção — guía visual de DedicatedPHP
  • A finalidade do dado e o momento da recolha estão documentados.
  • O mecanismo corresponde ao checkout ativo: hooks do fluxo clássico ou API de campos adicionais para o Block.
  • O servidor valida o tipo, o formato e o comprimento; entradas não escalares são rejeitadas e a ausência, o valor vazio e o valor inválido têm um tratamento definido.
  • A instalação e o armazenamento de pedidos foram identificados; a leitura e a atualização são testadas com a API CRUD.
  • Um pedido de teste confirma a leitura no ecrã de backoffice utilizado e o acesso está limitado.
  • Os testes abrangem caracteres Unicode, atualizações, erros, integrações e regressões do checkout.
Deseja aplicar essas ideias ao seu projeto?Vamos discutir sua plataforma PHP.
Veja os serviços relacionados