Integração

API de WhatsApp para WordPress e WooCommerce

Avise o cliente pelo WhatsApp quando o pedido do WooCommerce mudar de status.

<?php
// functions.php do tema filho ou plugin próprio

function zapixo_enviar($numero, $texto) {
    $resposta = wp_remote_post(
        "https://zapixo.com.br/api/v1/messages/text",
        [
            "timeout" => 30,
            "headers" => [
                "Authorization" => "Bearer " . ZAPIXO_API_KEY,
                "Content-Type"  => "application/json",
            ],
            "body" => wp_json_encode([
                "instance" => "loja",
                "number"   => $numero,
                "text"     => $texto,
            ]),
        ]
    );

    if (is_wp_error($resposta)) {
        error_log("Zapixo: " . $resposta->get_error_message());
    }
}

// dispara quando o pedido é concluído
add_action("woocommerce_order_status_completed", function ($order_id) {
    $pedido  = wc_get_order($order_id);
    $telefone = preg_replace("/\D/", "", $pedido->get_billing_phone());

    // telefone digitado sem o código do país (comum no Brasil)
    if (strlen($telefone) <= 11) {
        $telefone = "55" . $telefone;
    }

    zapixo_enviar(
        $telefone,
        "Pedido #{$order_id} concluído! Obrigado pela compra."
    );
});

// defina a chave no wp-config.php, nunca no functions.php versionado:
// define("ZAPIXO_API_KEY", "zpx_...");

No WordPress, a integração com o Zapixo usa o que o próprio WordPress já tem: wp_remote_post para enviar, a REST API (/wp-json/) para receber o webhook e, no WooCommerce, os ganchos de status do pedido. Não precisa de plugin de terceiros.

O código vai num plugin pequeno seu — de preferência um mu-plugin, em wp-content/mu-plugins —, e não no functions.php do tema: trocar ou atualizar o tema apaga o que estiver lá.

O que dá para fazer com WordPress e WooCommerce e WhatsApp

  • Aviso de pedido no WooCommerce

    Pagamento aprovado, pedido enviado, pedido concluído: cada mudança de status vira uma mensagem para o cliente.

  • Contato do site para o vendedor

    O envio do formulário avisa o vendedor pelo WhatsApp, com nome, telefone e interesse.

  • Lembrete de agendamento

    O plugin de agenda dispara o lembrete na véspera, pelo mesmo gancho que já usa para e-mail.

  • Resposta do cliente dentro do pedido

    O webhook grava o que o cliente respondeu como nota do pedido, onde a equipe já trabalha.

Enviar mensagens pelo WordPress e WooCommerce

  1. Guarde a chave no wp-config.php

    Defina a chave no wp-config.php, fora do repositório do tema. Ela nunca vai para o JavaScript do site: quem abrir o código-fonte da página conseguiria ler.

    define( 'ZAPIXO_API_KEY', 'zpx_...' );
  2. Função de envio

    O timeout padrão do WordPress é de 5 segundos; 15 dá folga sem prender a página. A função limpa o número e acrescenta o DDI quando o cliente não digitou:

    function zapixo_enviar( string $numero, string $texto ): bool {
        $numero = preg_replace( '/\D/', '', $numero );
        if ( strlen( $numero ) <= 11 ) {
            $numero = '55' . $numero; // telefone digitado sem o DDI
        }
    
        $resposta = wp_remote_post( 'https://zapixo.com.br/api/v1/messages/text', [
            'timeout' => 15,
            'headers' => [
                'Authorization' => 'Bearer ' . ZAPIXO_API_KEY,
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode( [
                'instance' => 'loja',
                'number'   => $numero,
                'text'     => $texto,
            ] ),
        ] );
    
        if ( is_wp_error( $resposta ) ) {
            error_log( 'Zapixo: ' . $resposta->get_error_message() );
            return false;
        }
        return wp_remote_retrieve_response_code( $resposta ) === 200;
    }
  3. Aviso de pedido sem travar o checkout

    Enviar dentro do gancho do pedido faz o cliente esperar a resposta da API. O WooCommerce já traz o Action Scheduler: o gancho só agenda, e o envio roda logo depois, fora da requisição.

    add_action( 'woocommerce_order_status_processing', function ( $order_id ) {
        as_enqueue_async_action( 'zapixo_avisar_pedido', [ $order_id ] );
    } );
    
    add_action( 'zapixo_avisar_pedido', function ( $order_id ) {
        $pedido = wc_get_order( $order_id );
        if ( ! $pedido ) {
            return;
        }
    
        zapixo_enviar(
            $pedido->get_billing_phone(),
            sprintf(
                'Oi %s, recebemos o pagamento do pedido #%s.',
                $pedido->get_billing_first_name(),
                $pedido->get_order_number()
            )
        );
    } );

Receber mensagens no WordPress e WooCommerce

  1. Registre a rota na REST API

    A verificação do segredo vai no permission_callback: se falhar, o próprio WordPress recusa a chamada antes de rodar o seu código.

    add_action( 'rest_api_init', function () {
        register_rest_route( 'zapixo/v1', '/webhook', [
            'methods'             => 'POST',
            'callback'            => 'zapixo_receber',
            'permission_callback' => function ( WP_REST_Request $req ) {
                return defined( 'ZAPIXO_WEBHOOK_SECRET' )
                    && ZAPIXO_WEBHOOK_SECRET !== ''
                    && hash_equals( ZAPIXO_WEBHOOK_SECRET, (string) $req->get_param( 'chave' ) );
            },
        ] );
    } );
  2. Cole a URL no painel

    Em Webhook de mensagens, com o segredo no fim: https://seusite.com.br/wp-json/zapixo/v1/webhook?chave=SEU_SEGREDO. O Zapixo não assina as requisições; o segredo na URL é a proteção.

  3. Trate a mensagem fora da requisição

    A rota responde na hora e entrega ao Action Scheduler só o que interessa. Sem WooCommerce, instale o Action Scheduler como plugin:

    function zapixo_receber( WP_REST_Request $req ) {
        $payload = $req->get_json_params();
        $data    = $payload['data'] ?? [];
        $key     = $data['key'] ?? [];
    
        if ( ( $payload['event'] ?? '' ) === 'messages.upsert' && empty( $key['fromMe'] ) ) {
            $msg = $data['message'] ?? [];
            as_enqueue_async_action( 'zapixo_processar_mensagem', [
                $key['id'] ?? '',
                explode( '@', $key['remoteJid'] ?? '' )[0],
                $msg['conversation'] ?? ( $msg['extendedTextMessage']['text'] ?? '' ),
            ] );
        }
    
        return new WP_REST_Response( null, 200 );
    }

Erros comuns e como resolver

Troquei o tema e a integração sumiu
O código estava no functions.php. Mova para um mu-plugin, que não depende do tema ativo.
Webhook recusado com 401
O permission_callback recusou o segredo, ou ZAPIXO_WEBHOOK_SECRET não está definido no wp-config.php. Confira também se algum plugin de segurança bloqueia /wp-json/.
Envio agendado que atrasa
O WP-Cron só roda quando alguém visita o site, e o Action Scheduler depende dele. Em loja com pouco movimento, configure um cron de verdade no servidor chamando o wp-cron.php.
Mensagem processada duas vezes
Se a rota não devolver 2xx em até 10 segundos, o Zapixo tenta de novo, até 3 vezes. No processamento, guarde o id da mensagem num transient por um dia e ignore o que já estiver lá.
Número sem DDI
O WooCommerce grava o telefone do jeito que o cliente digitou. A função de envio acima acrescenta o 55 quando o número tem 11 dígitos ou menos.
Erros 401, 404 e 502 no envio
401: chave errada ou sem o Bearer na frente. 404: instance não bate com o nome no painel. 502: a entrega ao WhatsApp falhou, e o motivo vem em details.

Perguntas frequentes

Precisa de plugin para ligar o WordPress ao WhatsApp pelo Zapixo?

Não. wp_remote_post e a REST API do WordPress resolvem; o código cabe num plugin pequeno seu.

Funciona sem WooCommerce?

Funciona. Sem WooCommerce, use os ganchos do plugin de formulário ou de agenda, e instale o Action Scheduler se quiser o envio fora da requisição.

O aviso deixa o checkout mais lento?

Não, se o gancho só agendar o envio pelo Action Scheduler. Enviar direto dentro do gancho faz o cliente esperar a resposta da API.

O webhook do Zapixo tem assinatura?

Não. Proteja a rota com um segredo na URL, conferido no permission_callback.

O trial tem limite de mensagens?

Tem. Ao atingir o limite, a API responde 402 com o link para assinar.

Leia também