API do WhatsApp com PHP: O Guia Completo de Integração

Guia da API do WhatsApp em PHP

API do WhatsApp com PHP: O Guia Completo de Integração

Chamadas Guzzle e cURL para conectar uma conta do WhatsApp, enviar e receber mensagens, gerenciar grupos e executar tudo isso dentro de um Laravel aplicativo, sem registrar um aplicativo Meta Business. Essa é a API do WhatsApp em PHP ponta a ponta: conexão, webhooks, SaaS multi-tenant e o custo real por mensagem.
Sem verificação do Meta Business
Guzzle e cURL, sem SDK descontinuado
connect-whatsapp.php
usar GuzzleHttp\Client; $client = new Cliente([ 'base_uri' => 'https://api1.unipile.com:13111', 'headers' => ['X-API-KEY' => $apiKey], ]); // Provedor WHATSAPP: sem aplicativo Meta, sem WABA $res = $client->postagem('/api/v1/accounts', [ 'json' => ['provider' => 'WHATSAPP'], ]);
201 Criado, account_id retornado
Mesmo padrão para LinkedIn Gmail Perspectivas IMAP
Definição

O que é a API do WhatsApp em PHP?

O API do WhatsApp em PHP é a prática de chamar uma API REST do WhatsApp a partir de um runtime PHP, PHP-FPM, um script CLI ou um worker de fila, usando um cliente HTTP como Guzzle ou cURL. Não há uma API do WhatsApp construída especificamente para PHP: a Meta e os provedores de API expõem JSON puro sobre HTTPS, e o PHP é simplesmente a linguagem fazendo a requisição, da mesma forma que faria para qualquer outra API web.
Na prática, uma integração de API do WhatsApp em PHP é uma chamada HTTP normal: um método, uma URL, um corpo JSON ou multipart e um X-API-KEY Cabeçalho. Nada aqui depende de um recurso exclusivo do PHP ou de um endpoint exclusivo do PHP. O que muda entre a Cloud API, um Provedor de Soluções de Negócios (BSP) e uma conta vinculada não é a linguagem, mas sim quem é o proprietário do número do WhatsApp e se a verificação do Meta Business fica entre você e sua primeira mensagem. Para ver uma análise completa desse ecossistema, consulte o Guia de integração da API do WhatsApp.
JSON simples sobre HTTPS
Cada chamada é um ciclo de requisição/resposta que o Guzzle ou o cURL já sabem como fazer.
Auth é um cabeçalho estático
Um X-API-KEY valor, sem dança OAuth, sem loop de atualização de token para escrever.
Independente de runtime
Funciona da mesma forma no PHP-FPM, em um comando de console do Symfony ou em um job de fila do Laravel.
Decisão

Qual API do WhatsApp você deve usar a partir do PHP?

Existem três maneiras de chamar o WhatsApp a partir de um backend em PHP: Cloud API da Meta diretamente, a Provedor de Soluções de Negócios revendendo acesso a ele, ou um Conta vinculada por meio de uma API unificada como o Unipile. Todas as três retornam JSON que seu código PHP analisa da mesma forma, o que muda é o tempo de configuração, se a verificação do Meta Business fica antes da sua primeira mensagem e se você obtém um histórico de conversas existente ou começa do zero.
Critérios
API de Nuvem (direto)
BSP
Conta vinculada
Verificação da Meta for Business
Obrigatório
Obrigatório
Não é necessário
Tempo para a primeira mensagem
Dias a algumas semanas
Integração mais rápida, mesmos requisitos por trás
Minutos
Número de telefone
Novo número registrado em uma WABA
Novo número provisionado pelo BSP
O próprio número de WhatsApp do usuário
Acesso a conversas existentes
Não, começa vazio
Não, começa vazio
Sim, histórico completo
Melhor ajuste
Um número de telefone comercial transmitindo para muitos clientes
O mesmo, com uma camada de integração gerenciada
Um produto onde cada usuário vincula a conta do WhatsApp que ele já tem
Se o seu aplicativo PHP é um produto SaaS onde cada cliente conecta seu próprio WhatsApp, uma conta vinculada remove totalmente a etapa de verificação da Meta. Se você está fazendo transmissões a partir de um único número da empresa, a Cloud API ou um BSP é o ponto de partida correto.
Criar com uma conta vinculada
Configuração

O que você precisa antes de escrever qualquer código PHP?

Você precisa PHP 8.1 ou mais recente, Compositores, o Guzzle Cliente HTTP e uma chave de API do Unipile. Nenhum SDK PHP mantido ativamente existe para o Unipile hoje, então cada exemplo neste guia se comunica com o /api/v1 API REST diretamente.
PHP 8.1+
Propriedades tipadas e argumentos nomeados mantêm o código do cliente curto.
Compositores
Gerenciador de dependências padrão, necessário para incluir o Guzzle.
Guzzle 7
Cliente HTTP para requisições JSON e multipart, com fallback para cURL.
Chave de API do Unipile
Enviado como X-API-KEY em cada solicitação, gerada a partir do seu painel.
terminal
composer require guzzlehttp/guzzle:^7.0
Existe um SDK em PHP? Nenhum que você precise instalar.
Um pacote da comunidade, unipile/unipile-php-sdk, existe no Packagist, mas está listado como abandonado: nenhum commit desde 17 de outubro de 2023, 5 estrelas no GitHub e aponta para uma URL base de API antiga. Não execute composer require unipile/unipile-php-sdk. O SDK do Node.js (unipile-node-sdk) é mantido oficialmente e está atualizado, mas para PHP, o Guzzle direto na API REST é o caminho confiável, e é o que todos os exemplos abaixo usam. Veja Documentação do Guzzle para as opções do cliente usadas aqui.
Implementação

Como conectar uma conta do WhatsApp a partir do PHP?

Conectar uma conta do WhatsApp a partir do PHP leva um POST solicitação com o provedor definido para WHATSAPP, então uma ação do usuário: o usuário final escaneia o código QR retornado em WhatsApp > Aparelhos conectados, ou digita um código de pareamento no celular se você solicitou um em vez disso. Sem aplicativo de desenvolvedor da Meta, sem WABA, sem etapa de verificação.
1
Solicitar um ponto de controle, QR code por padrão
Chame o endpoint de contas apenas com provider conjunto. O Unipile retorna um account_id além de uma carga útil de ponto de verificação criada para o fluxo de QR.
connect-qr.php
$response = $client->postagem('/api/v1/accounts', [ 'json' => ['provider' => 'WHATSAPP'], ]); $payload = json_decode($response->obterCorpo()->obterConteúdo(), true); $accountId = $payload['id_da_conta']; // A carga útil $ também transporta o ponto de verificação a ser renderizado no o QR code para escanear no WhatsApp > Aparelhos conectados // dispositivos. var_dump($payload) mais uma vez com sua própria chave // para ver o formato exato antes de conectar o frontend.
2
Ou solicite um código de pareamento em vez disso
Passar pareamento_de_numero_de_telefone em dígitos E.164, sem o sinal de mais, quando a leitura de um QR code não é prática, por exemplo, um agente de suporte integrado a um cliente por telefone.
connect-pairing.php
$response = $client->postagem('/api/v1/accounts', [ 'json' => [ 'provider' => 'WHATSAPP', 'pairing_phone_number' => '33612345678', ], ]); $payload = json_decode($response->obterCorpo()->obterConteúdo(), true); $accountId = $payload['id_da_conta']; // O ponto de verificação aqui é o código que sua interface mostra ao usuário // para digitar no WhatsApp > Aparelhos conectados > Conectar com // em vez disso, use o número de telefone.
3
Faça polling até que a conta esteja totalmente vinculada
A conta fica em uma CONEXÃO mantenha-se neste estado até que o código QR seja escaneado ou o código de pareamento seja inserido. Verifique sources[0].status por conta.
poll-status.php
$response = $client->obter(""/api/v1/accounts/{$accountId}""); $account = json_decode($response->obterCorpo()->obterConteúdo(), true); $status = $account['fontes'][0]['status'] ?? nulo; se ($status === 'OK') { // é seguro enviar, receber e listar conversas na conta $accountId }
Pesquisar em loop funciona, mas desperdiça requisições. Se a sua aplicação PHP já possui um endpoint de webhook, registre um em status_da_conta" em vez disso e reaja no momento em que o status mudar para OK. A configuração do webhook em si é abordada mais abaixo para mensagens recebidas; o mesmo endpoint aceita eventos de status da conta.
Fluxo principal

Como enviar uma mensagem do WhatsApp com PHP e Guzzle?

Enviar uma mensagem a partir do PHP é um POST para o endpoint de mensagens do chat com um text campo em um corpo multipart. A chamada retorna um id_da_mensagem assim que o WhatsApp aceitar.
enviar-mensagem.php
$response = $client->postagem(""/api/v1/chats/{$chatId}/messages"", [ 'multipart' => [ ['nome' => 'texto', 'conteúdos' => 'Olá! Seu pedido foi enviado.'], ], ]); $result = json_decode($response->obterCorpo()->obterConteúdo(), true); $messageId = $result['message_id'];
O mesmo multipartes a matriz também carrega anexos, a mensagem_de_voz arquivo, ou um id_da_cotacao para responder a uma mensagem específica, o Guzzle as anexa como campos multipart adicionais ao lado de text. Para a análise completa de cada tipos de mensagem que a API do WhatsApp suporta, incluindo modelos e a janela de atendimento de 24 horas, consulte nosso guia dedicado.
Fluxo principal

Como você inicia uma nova conversa a partir do PHP?

Iniciar uma conversa que ainda não existe significa chamar o endpoint de chats com um account_id e um attendees_ids vetor em vez de um existente chat_id. A Unipile cria o chat e, se você incluir um text campo, envia a primeira mensagem na mesma chamada.
iniciar-conversa.php
$response = $client->postagem('/api/v1/chats', [ 'multipart' => [ ['nome' => 'id_da_conta', 'conteúdos' => [$accountId], ['nome' => 'attendees_ids[]', 'conteúdos' => '33612345678@s.whatsapp.net'], ['nome' => 'texto', 'conteúdos' => 'Olá, aqui é o suporte da Acme.'], ], ]); $result = json_decode($response->obterCorpo()->obterConteúdo(), true); $chatId = $result['chat_id'];
O destinatário é identificado por {phone_number}@s.whatsapp.net, dígitos internacionais, sem sinal de mais à frente, sem espaços. Armazene o retornado chat_id ao lado desse registro de usuário: cada mensagem após a primeira passa pelo endpoint de mensagens da seção anterior, e não por este.
Fluxo principal

Como você recupera chats e mensagens em PHP?

A maioria dos tutoriais da API do WhatsApp para por aí, no envio. Um backend em PHP geralmente também precisa listar as conversas existentes de um usuário, paginar seu histórico e ver quem está em um chat. Três endpoints cobrem isso: GET /api/v1/chats, GET /api/v1/chats/{chat_id}/messagese GET /api/v1/chats/{chat_id}/attendees, todas paginadas com um cursor.
Listar todas as conversas do WhatsApp em uma conta
listar-chats.php
$response = $client->obter('/api/v1/chats', [ 'query' => [ ''account_id' => $accountId, 'account_type' => 'WHATSAPP', 'limit' => 50, ], ]); $data = json_decode($response->obterCorpo()->obterConteúdo(), true); $chats = $data['itens']; $nextCursor = $data['cursor'];
Folhear o histórico de um chat
list-messages.php
$cursor = nulo; $all = []; faça { $res = $client->obter(""/api/v1/chats/{$chatId}/messages"", [ 'query' => array_filter(['cursor' => $cursor, 'limite' => 100]), ]); $page = json_decode($res->obterCorpo()->obterConteúdo(), true); $all = array_merge($all, $page['itens']); $cursor = $page['cursor']; } enquanto ($cursor !== nulo);
Todo endpoint de lista segue o mesmo contrato de cursor: passe o da resposta anterior cursor entre de ré, pare quando voltar nulo. Para ver quem está realmente em uma conversa, chame GET /api/v1/chats/{chat_id}/attendees: ele retorna o de cada participante id, provider_id e o nome de exibição, que é o que você precisa antes de poder chamar adicionarParticipante ou removerParticipante em um grupo mais adiante neste guia.
Produção

Como você recebe mensagens do WhatsApp com um webhook em PHP?

Um webhook do WhatsApp em PHP é um endpoint HTTPS público que o Unipile chama com um payload JSON em eventos como message_received. O seu script lê o corpo bruto, confirma que a chamada é legítima, responde rapidamente e entrega o trabalho real para uma fila. Polling GET /api/v1/chats para novas mensagens funciona para uma demonstração, não para um produto com mais do que alguns poucos usuários.
1. Registre o webhook, com um segredo compartilhado em um cabeçalho personalizado
register-webhook.php
$client->postagem('/api/v1/webhooks', [ 'json' => [ 'source' => 'Mensagens', 'request_url' => 'https://example.com/webhooks/whatsapp', 'events' => ['mensagem_recebida'], 'headers' => [ ['chave' => 'X-Webhook-Secret', 'valor' => [$webhookSecret], ], ], ]);
2. Verifique, responda e processe
public/webhooks/whatsapp.php
$rawBody = file_get_contents('php://input'); $provided = $_SERVER['HTTP_X_WEBHOOK_SECRET'] ?? ''; se (!hash_equals($expectedSecret, $provided)) { código_de_resposta_http(401); sair; } código_de_resposta_http(200); se (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } $payload = json_decode($rawBody, true); se (($payload['evento'] ?? nulo) === 'mensagem_recebida') { // inserir a carga útil $ em uma tabela de fila ou em uma lista do Redis, // nunca processe um webhook de forma síncrona enfileirar_mensagem_whatsapp($payload); }
A Unipile não assina o corpo do webhook com um segredo HMAC que você possa recalcular, o endpoint create-webhook expõe cabeçalhos matriz em vez disso. Anexe seu próprio segredo como um cabeçalho personalizado ao registrar o webhook e, em seguida, verifique-o com hash_equals(), uma comparação de strings segura contra temporização, antes de confiar no payload. Todos os campos em $cargaútil, account_id, tipo de conta, evento, chat_id, id_da_mensagem, message e sender.attendee_provider_id, corresponde aos documentos JSON da Unipile para o webhook de mensagens.
Produção

Como você integra a API do WhatsApp em uma aplicação Laravel?

O Laravel substitui três coisas dos exemplos em PHP puro acima: o HTTP uma fachada em vez de um cliente Guzzle implementado manualmente, um job em fila em vez de processamento em linha, e uma rota mais um controller em vez de análise sintática php://input manualmente. As chamadas do WhatsApp abaixo são idênticas a todos os exemplos já presentes neste guia.
1. ConfiguraçãoUma entrada em services.php, valores do .env
config/services.php
return [ // ...serviços existentes 'unipile' => [ 'base_uri' => env('UNIPILE_BASE_URI', 'https://api1.unipile.com:13111'), 'api_key' => env('UNIPILE_API_KEY'), 'webhook_secret' => env('UNIPILE_WEBHOOK_SECRET'), ], ];
2. Uma classe de serviço leve sobre a fachada Http
app/Services/WhatsappService.php
namespace App\Services; usar Illuminate\Support\Facades\Http; aula WhatsappService { protegido função client() { return Http::baseUrl(configuração('services.unipile.base_uri')) ->comCabeçalhos(['X-API-KEY' => configuração('services.unipile.api_key')]); } público função sendMessage(string $chatId, string $text): vetor { return $isso->client() ->comoMultipart() ->postagem(""/api/v1/chats/{$chatId}/messages"", [ ['nome' => 'texto', 'conteúdos' => [$text], ]) ->json(); } }
3. Controlador de rota e webhook
routes/api.php
Route::postagem('/webhooks/whatsapp', [WhatsappWebhookController::aula, 'cabo']);
app/Http/Controllers/WhatsappWebhookController.php
public function handle(Request $request) { $provided = $request->header('X-Webhook-Secret', ''); if (!hash_equals(config('services.unipile.webhook_secret'), $provided)) { abort(401); } if ($request->input('event') === 'message_received') { ProcessWhatsappMessage::dispatch($request->all()); } return response()->json(['status' => 'received']); }
4. Um job em fila, para que a rota do webhook permaneça rápida
app/Jobs/ProcessWhatsappMessage.php
aula ProcessarMensagemWhatsapp implementa ShouldQueue { usar Dispatchable, InteractsWithQueue, Queueable, SerializesModels; público função __construct(público vetor $payload) {} público função maçaneta(): vazio { // consultar o locatário por $this->payload['account_id'], // armazene a mensagem, notifique o usuário correto } }
A rota nunca toca o Guzzle diretamente, ela passa através de WhatsappService, o que torna as chamadas do WhatsApp simuláveis em testes da mesma forma que qualquer outra integração HTTP do Laravel é. Veja Documentação do cliente HTTP do Laravel para simular essas requisições em sua suíte de testes.
Construa isso em Laravel
Produção

Como você gerencia grupos do WhatsApp a partir do PHP?

Gerenciar um grupo do WhatsApp a partir do PHP é uma tarefa simples PATCH chamada para o endpoint do chat com um ação campo adicionarParticipante, removerParticipanteou obterLinkDeConvite. O recurso de grupos da própria API de Nuvem da Meta limita um grupo a 8 participantes e não expõe nenhum endpoint para adicionar alguém diretamente, apenas um link de convite para compartilhar.
Adicionar um participante
adicionar-participante.php
$client->patch(""/api/v1/chats/{$groupChatId}"", [ 'json' => [ 'action' => 'adicionarParticipante', 'value' => '33612345678@s.whatsapp.net', ], ]);
Obter o link de convite
invite-link.php
$res = $client->patch(""/api/v1/chats/{$groupChatId}"", [ 'json' => ['action' => 'obterLinkDeConvite'], ]); $link = json_decode($res->obterCorpo()->obterConteúdo(), true)['link_de_convite'];
removerParticipante assume a mesma forma que adicionarParticipante, com o ID do WhatsApp do participante em valor. Esta é a única ação que a própria API de Grupos da Meta não expõe de forma alguma; a adição de alguém ocorre apenas através do link de convite do lado deles. Para ver cada limite, o teto de 10.000 grupos por número e o que ainda não é suportado, consulte o API de Grupo do WhatsApp referência.
Gerenciamento de grupo de construção
Escala

Como você gerencia muitas contas de usuário a partir de uma única aplicação PHP?

Um produto SaaS em PHP não tem uma conta do WhatsApp, ele tem uma por cliente. Há apenas um Unipile X-API-KEY para toda a sua aplicação, mas um distinto account_id para cada usuário final que vincula seu WhatsApp. O padrão é armazenar isso account_id ao lado da sua própria linha de inquilino e passe-a explicitamente em todas as chamadas que poderiam, de outra forma, cruzar contas.
route-by-tenant.php
// Dentro do manipulador de webhook: encontrar qual inquilino este // a mensagem pertence a antes de fazer qualquer coisa com ela. $stmt = $pdo->preparar('SELECT id FROM tenants WHERE unipile_account_id = ?'); $stmt->executar([$payload['id_da_conta']]); $tenantId = $stmt->buscarColuna(); se ($tenantId === falso) { // account_id desconhecido, rejeitar em vez de adivinhar o locatário código_de_resposta_http(404); sair; } // Outbound: passe account_id para que um chat_id desatualizado ou reutilizado possa // nunca envie pelo número de WhatsApp do inquilino errado. $client->postagem(""/api/v1/chats/{$chatId}/messages"", [ 'multipart' => [ ['nome' => 'texto', 'conteúdos' => [$text], ['nome' => 'id_da_conta', 'conteúdos' => [$expectedAccountId], ], ]);
O opcional account_id o campo no endpoint de mensagens existe especificamente para evitar o envio em um chat fora dessa conta, trate-o como obrigatório em uma base de código multi-tenant, mesmo que a API não o exija. Cripte o armazenado account_id valores em repouso como qualquer outra credencial de cliente: eles não são secretos por si só, mas são a chave de junção entre sua tabela de usuários e as conversas reais do WhatsApp de alguém.
Armadilhas

Quais são os erros mais comuns específicos do PHP?

A maioria dos bugs da API do WhatsApp em uma base de código PHP vem do próprio PHP, e não da API. Estes cinco aparecem repetidamente em integrações de produção.
Truncar uma mensagem com substr() em vez de mb_substr()
do PHP substr() conta bytes, não caracteres. Um emoji é uma sequência UTF-8 de vários bytes; corte-o ao metade e você enviará um caractere quebrado ou JSON inválido. Sempre use as funções de múltiplos bytes em texto do WhatsApp gerado pelo usuário.
Consertar
$safe = mb_substr($text, 0, 4096, 'UTF-8');
Erro cURL 60 no Windows e XAMPP
"Problema de certificado SSL: não foi possível obter o certificado do emissor local. As compilações do PHP para Windows e o XAMPP frequentemente vêm sem um pacote CA atual configurado no php.ini, fazendo com que as chamadas HTTPS do Guzzle falhem, mesmo que o código esteja correto.
Corrigir, php.ini
curl.cainfo = "C:\php\extras\cacert.pem" openssl.cafile = "C:\php\extras\cacert.pem"
max_execution_time encerrando o webhook antes de ele responder
Um padrão de 30 segundos é mais do que suficiente até que o manipulador faça uma chamada de saída lenta antes de responder. Se o Unipile não obtiver uma resposta rápida, ele tenta novamente, e um manipulador lento começa a processar a mesma mensagem duas vezes. Responda primeiro, trabalhe depois, conforme mostrado na seção de webhook acima.
Sem atraso exponencial em respostas 429 ou 5xx
Um apertado enquanto um loop que tenta novamente imediatamente após uma falha transforma um limite de taxa em uma interrupção autoinfligida. Espere, and aumente o tempo de espera a cada falha consecutiva.
Consertar
para ($attempt = 1; $attempt <= 5; $attempt++) { tentar { return $client->postagem($uri, $options); } captura (ConnectException | ServerException $e) { usleep((2 ** $attempt) * 100_000); // 0,2s, 0,4s, 0,8s... } }
Registrar a resposta crua e chamar isso de depuração
Se você construir um corpo JSON manualmente em vez de deixar o do Guzzle json opção lidar com isso, adicionar JSON_UNESCAPED_UNICODE para json_encode(). Sem ele, emojis e nomes com acentos aparecem como escapados \u sequências nos seus logs, o que é tecnicamente um JSON válido, mas ilegível quando você está tentando depurar uma conversa real.
Custo

Quanto custa para enviar mensagens do WhatsApp a partir do PHP?

Nada no código PHP altera o preço. A Meta cobra por mensagem desde 1º de julho de 2025, não por conversa. A única coisa que o seu código controla é o timing: uma resposta enviada dentro da janela de atendimento de 24 horas após a mensagem de um usuário ainda é gratuita, a chamada idêntica enviada uma hora depois é taxável.
Modelos de utilitários e autenticação fique gratuito dentro de uma janela de serviço aberta, cobrado fora dela.
Modelos de marketing são cobrados independentemente da janela.
As taxas por mensagem variam de acordo com o país do destinatário e a categoria da mensagem, e não com a biblioteca de cliente usada para enviá-las.
Carimbo de data/hora em cada mensagem de entrada que seu webhook PHP receber e mantenha um valor de "janela aberta até" por conversa, essa é a única entrada de que sua lógica de faturamento realmente precisa. Para a atual preço por mensagem do WhatsApp por país e categoria, veja o detalhamento completo de preços.

API do WhatsApp com PHP - FAQ

Respostas diretas sobre conexão, envio, Laravel e o SDK PHP abandonado.
Crie um cliente Guzzle apontando para a API REST do Unipile, chame POST /api/v1/accounts com provedor WHATSAPP para obter um código QR ou código de pareamento, peça ao usuário para concluí-lo no telefone e, em seguida, use o mesmo cliente para OBTER, POST e PATCH chamadas para enviar mensagens, listar chats e gerenciar grupos. Não há endpoint específico para PHP, cada chamada é uma requisição HTTP normal com um X-API-KEY cabeçalho. O conectar uma conta do WhatsApp a seção acima explica o código exato passo a passo.
Sim. Um único POST para /api/v1/chats/{chat_id}/mensagens with a text campo em um corpo multipart envia a mensagem e retorna um id_da_mensagem, veja o enviar seção acima para a chamada exata do Guzzle.
Somente se você acessar a Cloud API da Meta diretamente ou um Provedor de Soluções de Negócios construído sobre ela. Conectar uma conta do WhatsApp através do Unipile vincula o número de WhatsApp existente do usuário por código QR ou código de pareamento e não exige nenhuma verificação do Meta Business.
Não há nenhum mantido ativamente. Um pacote da comunidade, unipile/unipile-php-sdk, está no Packagist mas marcado abandonado, sem nenhum commit desde 17 de outubro de 2023 e 5 estrelas no GitHub. Todos os exemplos deste guia chamam a API REST diretamente por meio do Guzzle, o que também é o que o SDK abandonado fazia internamente.
Você não pode receber webhooks sem uma URL HTTPS publicamente acessível, é assim que funcionam os retornos de chamada HTTP. Durante o desenvolvimento local, crie um túnel para uma porta local com um serviço como o ngrok e aponte o webhook request_url no endereço HTTPS do túnel. Consultando o endpoint de mensagens é o plano de fundo quando um endpoint público genuinamente não é possível, ao custo de latência e solicitações extras.
Sim, nada disso é específico de um framework. O Seção Laravel acima encapsula as mesmas chamadas equivalentes ao Guzzle no HTTP fachada, um job em fila e uma rota e controller de webhook, que é a forma idiomática de estruturá-lo em uma base de código Laravel.
Sim, esse é o formato normal de SaaS. Uma chave de API da Unipile cobre todo o aplicativo, enquanto cada usuário final obtém a sua própria account_id após conectar o WhatsApp deles. Armazene esse ID junto ao registro do seu tenant e passe-o em chamadas de saída para evitar envios entre tenants, consulte o seção multilocatária Acima.
PATCH /api/v1/chats/{chat_id} com {"action": "addParticipant", "value": "@s.whatsapp.net"}. O recurso de grupos da própria Cloud API da Meta não possui um endpoint equivalente, apenas um link de convite, o que é uma das diferenças mais claras entre construir diretamente na Meta e usar o Unipile. Detalhes no seção de grupos Acima.
Quase sempre porque uma string foi truncada com substr() em vez de mb_substr(). As funções de string nativas do PHP contam bytes, e um emoji é uma sequência UTF-8 de múltiplos bytes; cortado ao meio, ele se transforma em um caractere inválido ou corrompe a carga útil JSON por completo.
O Guzzle é suficiente, ele é um cliente HTTP construído sobre a extensão cURL do PHP, não um substituto para ela. Cada requisição neste guia usa o Guzzle; um bruto curl_init() call funciona exatamente da mesma forma se um projeto não puder adicionar a dependência; os corpos JSON e multipart são iguais de qualquer maneira.
O mesmo que enviar de qualquer outra forma. A Meta cobra por mensagem desde 1º de julho de 2025, com base na categoria e no país do destinatário, e não na biblioteca cliente usada para chamar a API. Consulte a seção de custos acima e o guia completo de preços para as tarifas atuais.
Sim, isso não vai sumir, apenas determina o que é gratuito em vez do que é tecnicamente permitido. Uma resposta dentro da janela de 24 horas após a última mensagem do usuário é enviada sem ser cobrada como uma mensagem de modelo, e o código em PHP que ignora a janela simplesmente paga por mensagens de que não precisava.

Ainda tem dúvidas sobre como construir isso em PHP? Nossa equipe está aqui para ajudar.

Fale com um especialista
Guia da API do WhatsApp em PHP

Pronto para integrar a API do WhatsApp à sua aplicação PHP?

Cada endpoint neste guia, connect, send, receive, groups, roda na mesma conta Unipile que você pode criar agora mesmo. Sem verificação do Meta Business, sem SDK abandonado, apenas Guzzle e uma API REST que sua aplicação PHP já sabe como chamar.
Automatizar em vez de integrar em um aplicativo existente? Leia a mesma integração em Python.
pt_BRBR