Imprimir automaticamente os pedidos WooCommerce: o guia completo

O WooCommerce pode imprimir um pedido assim que é pago: com um plugin, um hook ou algumas linhas de código. Cada via e o que custa.

O WooCommerce traz uma lista de pedidos, uma ficha de detalhe e um botão de impressão do navegador. O que não traz é um talão que aparece na cozinha no segundo em que um cliente paga.

Resposta curta: ligue-se ao woocommerce_order_status_processing, construa o texto do talão e envie-o por POST para uma impressora acessível a partir da internet. Um plugin faz isso por si; vinte linhas num pequeno plugin próprio fazem-no exatamente como quer. Nenhum dos dois precisa de um computador ligado na loja.

Que via escolher

Via Esforço Paginação Sobrevive a mudanças de tema Adequada a
Plugin conector Instalar e configurar Definições de template Sim A maioria das lojas
Hook próprio ~20 linhas Total Sim, se num plugin Lógica específica, multi-vendedor
Sondagem WP-Cron Maior Total Sim Lojas com hooks pouco fiáveis

A via do plugin

O conector WooCommerce instala-se como qualquer extensão: ative-o, cole as suas credenciais de API, escolha a impressora e os estados de pedido que desencadeiam a impressão. A documentação do plugin percorre as definições.

Se a sua loja é uma loja normal, pare aqui. O resto é para os casos que não o são.

A via do hook

<?php
/**
 * Plugin Name: Imprimir pedidos ao pagamento
 * Colocar em wp-content/plugins/, não no functions.php do tema:
 * uma atualização de tema pararia a impressão sem aviso.
 */

add_action( 'woocommerce_order_status_processing', 'my_print_order', 10, 2 );

function my_print_order( $order_id, $order ) {
    if ( $order->get_meta( '_printed_at' ) ) {
        return; // evita o segundo talão se o estado for aplicado duas vezes
    }

    $linhas = array( 'PEDIDO #' . $order->get_order_number(), $order->get_date_created()->date( 'd/m/Y H:i' ), '' );

    foreach ( $order->get_items() as $item ) {
        $linhas[] = $item->get_quantity() . 'x ' . $item->get_name();
    }

    $linhas[] = '';
    $linhas[] = 'TOTAL: ' . $order->get_total() . ' ' . $order->get_currency();

    wp_remote_post(
        'https://www.expedy.fr/api/v2/printers/' . MY_PRINTER_UID . '/print',
        array(
            'timeout'  => 5,
            'blocking' => false, // o cliente não deve esperar pela impressora
            'headers'  => array(
                'Authorization' => MY_API_SID . ':' . MY_API_TOKEN,
                'Content-Type'  => 'application/json',
            ),
            'body' => wp_json_encode( array(
                'printer_msg' => implode( "\n", $linhas ),
                'origin'      => 'woo-' . $order_id,
            ) ),
        )
    );

    $order->update_meta_data( '_printed_at', current_time( 'mysql' ) );
    $order->save();
}

Três elementos do código são deliberados.

'blocking' => false. Sem ele, o pedido de compra do cliente espera pela resposta da API de impressão. Numa ligação lenta é uma página de agradecimento visivelmente mais lenta, e se a impressora estiver inacessível pode parecer uma falha de compra.

O guardião _printed_at. Um pedido pode entrar em processing mais do que uma vez: um callback de gateway que chega duas vezes, uma mudança manual, um plugin que volta a gravar o pedido. Sem o guardião, cada um destes produz mais um talão.

Um plugin, não functions.php. O código no tema morre com o tema. Todas as agências herdaram pelo menos um site em que a impressão parou no dia da mudança de tema.

Onde o WooCommerce morde

Os estados não são universais. As lojas com transferência bancária ou pagamento à cobrança não passam por processing da mesma forma. Se os seus pedidos ficam em on-hold, ligue-se a esse estado, ou use woocommerce_order_status_changed e decida dentro da função.

O WP-Cron não é um cron. Só corre quando alguém visita o site. Numa loja de pouco tráfego, um pedido pode esperar uma hora pelo seu talão. Use um cron de sistema real a chamar wp-cron.php.

Multi-vendedor. Num marketplace WCFM ou Dokan cada vendedor precisa da sua impressora: o printer_uid vem dos metadados do vendedor, não de uma constante: ver a documentação WCFM.

Codificação de caracteres. O WordPress guarda de bom grado emojis nos nomes dos produtos. As impressoras térmicas não os imprimem, e em alguns modelos uma sequência inesperada derruba a ligação. Translitere antes de construir o talão.

Começar

Crie uma conta gratuita e imprima um talão com um curl simples antes de tocar no WooCommerce. Isolar a cadeia de impressão da cadeia WordPress poupa uma quantidade surpreendente de depuração.

FAQ

Que hook do WooCommerce deve desencadear a impressão?

woocommerce_order_status_processing na maioria das lojas: dispara assim que o pagamento é confirmado. Lojas com transferência bancária ou pagamento à cobrança podem precisar de on-hold, ou de woocommerce_order_status_changed com a decisão dentro da função.

É possível imprimir pedidos WooCommerce sem plugin?

Sim. Um pequeno plugin próprio com uma ação no hook de estado e uma chamada wp_remote_post ao endpoint de impressão são cerca de vinte linhas. Coloque-o em wp-content/plugins/, nunca no functions.php do tema.

Porque é que a compra ficou mais lenta desde que imprimo?

Porque a chamada HTTP à API de impressão bloqueia o pedido de compra. Passe 'blocking' => false ao wp_remote_post para que o cliente nunca espere por uma impressora.

Como evito que um pedido seja impresso duas vezes?

Guarde um meta como _printed_at no pedido e saia da função se já estiver definido. Os estados podem ser aplicados mais do que uma vez por callbacks de gateway ou alterações manuais.