PHPackages                             sixtec/wbapi - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. sixtec/wbapi

ActiveLibrary[API Development](/categories/api)

sixtec/wbapi
============

PHP 8.1+ library for WhatsApp Business Cloud API (Meta) integration

v1.0.0(1w ago)2471MITPHPPHP ^8.1CI passing

Since Apr 30Pushed 1w agoCompare

[ Source](https://github.com/sixtec/wbapi)[ Packagist](https://packagist.org/packages/sixtec/wbapi)[ RSS](/packages/sixtec-wbapi/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (8)Versions (3)Used By (0)

sixtec/wbapi
============

[](#sixtecwbapi)

Biblioteca PHP 8.1+ para integração com a **Meta Cloud API (WhatsApp Business)**.

Construída com Clean Architecture, Fluent Interface, DTOs e client HTTP desacoplado — sem expor nenhum payload bruto da Meta ao consumidor da biblioteca.

> **Autor:** Mário Lucas
> **Criação:** 12 de abril de 2026
> **Licença:** MIT

---

Requisitos
----------

[](#requisitos)

RequisitoVersãoPHP^8.1Guzzle^7.0---

Instalação
----------

[](#instalação)

```
composer require sixtec/wbapi
```

---

Configuração
------------

[](#configuração)

### Cliente instanciável

[](#cliente-instanciável)

Use `WBMetaClient` quando sua aplicação precisa de injeção de dependência, múltiplos números, multi-tenant ou workers long-running:

```
use Sixtec\WBApi\Config\WBMetaConfig;
use Sixtec\WBApi\WBMetaClient;

$client = WBMetaClient::fromConfig(new WBMetaConfig(
    accessToken:        'EAAxxxxxxxxxxxxxxx',
    phoneNumberId:      '123456789012345',
    apiVersion:         'v19.0',
    webhookVerifyToken: 'meu-token-secreto',
));

$client->to('+5511999999999')
    ->text('Olá, tudo bem?')
    ->send();
```

### Facade estática

[](#facade-estática)

A facade continua disponível para aplicações simples:

```
use Sixtec\WBApi\WBMeta;
use Sixtec\WBApi\Config\WBMetaConfig;

WBMeta::configure(new WBMetaConfig(
    accessToken:        'EAAxxxxxxxxxxxxxxx',
    phoneNumberId:      '123456789012345',
    apiVersion:         'v19.0',           // opcional, padrão: v19.0
    webhookVerifyToken: 'meu-token-secreto', // necessário para webhooks
    retryAttempts:      3,                 // opcional, padrão: 3
    timeout:            30.0,              // opcional, padrão: 30s
));
```

---

Envio de Mensagens
------------------

[](#envio-de-mensagens)

### Texto simples

[](#texto-simples)

```
WBMeta::to('+5511999999999')
    ->text('Olá, tudo bem?')
    ->send();
```

### Texto com preview de URL

[](#texto-com-preview-de-url)

```
WBMeta::to('+5511999999999')
    ->text('Acesse: https://example.com', previewUrl: true)
    ->send();
```

### Imagem

[](#imagem)

```
WBMeta::to('+5511999999999')
    ->image('https://example.com/foto.jpg', 'Legenda opcional')
    ->send();
```

### Vídeo

[](#vídeo)

```
WBMeta::to('+5511999999999')
    ->video('https://example.com/video.mp4', 'Legenda opcional')
    ->send();
```

### Áudio

[](#áudio)

```
WBMeta::to('+5511999999999')
    ->audio('https://example.com/audio.ogg')
    ->send();
```

### Documento

[](#documento)

```
WBMeta::to('+5511999999999')
    ->document('https://example.com/relatorio.pdf', 'relatorio.pdf', 'Relatório Q1')
    ->send();
```

### Sticker

[](#sticker)

```
WBMeta::to('+5511999999999')
    ->sticker('https://example.com/sticker.webp')
    ->send();
```

### Responder uma mensagem

[](#responder-uma-mensagem)

```
WBMeta::to('+5511999999999')
    ->replyTo('wamid.HBgLNTUx...')
    ->text('Resposta vinculada à mensagem original')
    ->send();
```

### Reação

[](#reação)

```
WBMeta::to('+5511999999999')
    ->reaction('wamid.HBgLNTUx...', '👍')
    ->send();

WBMeta::to('+5511999999999')
    ->removeReaction('wamid.HBgLNTUx...')
    ->send();
```

### Localização

[](#localização)

```
WBMeta::to('+5511999999999')
    ->location(-8.0476, -34.8770, 'Recife', 'Recife, PE')
    ->send();
```

### Contato

[](#contato)

```
WBMeta::to('+5511999999999')
    ->contact('Maria Silva', '+55 11 99999-9999', 'Maria')
    ->send();
```

Para contatos completos, informe diretamente os objetos no formato da Meta:

```
WBMeta::to('+5511999999999')
    ->contacts([
        [
            'name' => [
                'formatted_name' => 'Maria Silva',
                'first_name' => 'Maria',
            ],
            'phones' => [
                ['phone' => '5511999999999', 'type' => 'CELL'],
            ],
        ],
    ])
    ->send();
```

### Botões interativos

[](#botões-interativos)

```
WBMeta::to('+5511999999999')
    ->buttons('Escolha uma opção', [
        ['id' => 'confirm', 'title' => 'Confirmar'],
        ['id' => 'cancel', 'title' => 'Cancelar'],
    ])
    ->send();
```

### Lista interativa

[](#lista-interativa)

```
WBMeta::to('+5511999999999')
    ->list('Escolha um item', 'Ver opções', [
        [
            'title' => 'Produtos',
            'rows' => [
                ['id' => 'sku-1', 'title' => 'Produto 1'],
                ['id' => 'sku-2', 'title' => 'Produto 2'],
            ],
        ],
    ])
    ->send();
```

### Produto de catálogo

[](#produto-de-catálogo)

```
WBMeta::to('+5511999999999')
    ->product('Veja este produto', '1234567890', 'sku-1')
    ->send();
```

### Lista de produtos de catálogo

[](#lista-de-produtos-de-catálogo)

```
WBMeta::to('+5511999999999')
    ->productList('Veja estes produtos', '1234567890', [
        [
            'title' => 'Produtos',
            'product_items' => [
                ['product_retailer_id' => 'sku-1'],
                ['product_retailer_id' => 'sku-2'],
            ],
        ],
    ])
    ->send();
```

### Payload interativo avançado

[](#payload-interativo-avançado)

```
WBMeta::to('+5511999999999')
    ->interactive([
        'type' => 'button',
        'body' => ['text' => 'Escolha uma opção'],
        'action' => [
            'buttons' => [
                [
                    'type' => 'reply',
                    'reply' => ['id' => 'yes', 'title' => 'Sim'],
                ],
            ],
        ],
    ])
    ->send();
```

### Marcar mensagem como lida

[](#marcar-mensagem-como-lida)

```
WBMeta::markAsRead('wamid.HBgLNTUx...');
```

### Template

[](#template)

```
use Sixtec\WBApi\DTOs\TemplateComponentDTO;
use Sixtec\WBApi\DTOs\TemplateParameterDTO;

WBMeta::to('+5511999999999')
    ->template('hello_world', 'pt_BR', [
        new TemplateComponentDTO(
            type: 'body',
            parameters: [
                new TemplateParameterDTO(type: 'text', value: 'João'),
            ],
        ),
    ])
    ->send();
```

### Retorno

[](#retorno)

Todos os métodos `send()` retornam um `MessageResponseDTO`:

```
use Sixtec\WBApi\DTOs\MessageResponseDTO;

$response = WBMeta::to('+5511999999999')->text('Olá!')->send();

echo $response->messageId->getValue(); // wamid.HBgLNTUxMTk...
echo $response->status;               // accepted
echo $response->to;                   // 5511999999999
```

---

Webhooks
--------

[](#webhooks)

### 1. Verificação do Desafio (GET)

[](#1-verificação-do-desafio-get)

```
$handler   = WBMeta::webhook();
$challenge = $handler->verify(
    $_GET['hub_mode'],
    $_GET['hub_verify_token'],
    $_GET['hub_challenge'],
);

http_response_code(200);
echo $challenge;
```

### 2. Recebimento de Eventos (POST)

[](#2-recebimento-de-eventos-post)

```
use Sixtec\WBApi\Webhook\Events\MessageReceivedEvent;
use Sixtec\WBApi\Webhook\Events\MessageDeliveredEvent;
use Sixtec\WBApi\Webhook\Events\MessageReadEvent;
use Sixtec\WBApi\Webhook\Events\MessageTypingEvent;

$payload = json_decode(file_get_contents('php://input'), true);
$events  = WBMeta::webhook()->handle($payload);

foreach ($events as $event) {
    match (true) {
        $event instanceof MessageReceivedEvent  => handleReceived($event),
        $event instanceof MessageDeliveredEvent => handleDelivered($event),
        $event instanceof MessageReadEvent      => handleRead($event),
        $event instanceof MessageTypingEvent    => handleTyping($event),
    };
}

function handleReceived(MessageReceivedEvent $event): void
{
    // $event->messageId, $event->from, $event->type
    // $event->textBody  — preenchido quando type === 'text'
    // $event->mediaData — preenchido para tipos de mídia
}

function handleTyping(MessageTypingEvent $event): void
{
    // $event->contactId, $event->timestamp, $event->messageId
}
```

---

Arquitetura
-----------

[](#arquitetura)

```
src/
├── WBMeta.php                          # Facade estática (ponto de entrada)
├── WBMetaClient.php                    # Cliente instanciável para DI/multi-tenant
├── Config/
│   └── WBMetaConfig.php                # DTO de configuração
├── Contracts/
│   ├── HttpClientInterface.php         # Contrato do client HTTP
│   └── TokenStorageInterface.php       # Contrato de armazenamento de token
├── Domain/
│   ├── Entities/                       # Message, Contact, Conversation, Template
│   └── ValueObjects/                   # PhoneNumber, MessageId, MediaUrl
├── DTOs/                               # Objetos de transferência (entrada/saída)
│   ├── SendTextMessageDTO.php
│   ├── SendTemplateMessageDTO.php
│   ├── SendMediaMessageDTO.php
│   ├── MessageResponseDTO.php
│   ├── TemplateComponentDTO.php
│   ├── TemplateParameterDTO.php
│   └── MediaType.php  (enum)
├── Http/
│   ├── GuzzleHttpClient.php            # Adapter Guzzle + retry automático
│   └── HttpResponse.php
├── Auth/
│   ├── TokenManager.php
│   └── InMemoryTokenStorage.php
├── Mappers/                            # Convertem DTOs → payload Meta
│   ├── TextMessageMapper.php
│   ├── TemplateMessageMapper.php
│   └── MediaMessageMapper.php
├── Services/
│   └── MessagingService.php            # Orquestra envio, desacoplado via interface
├── Builders/
│   └── MessageBuilder.php             # Fluent interface
├── Webhook/
│   ├── WebhookHandler.php             # verify() + handle()
│   ├── WebhookPayloadParser.php
│   └── Events/
│       ├── MessageReceivedEvent.php
│       ├── MessageDeliveredEvent.php
│       ├── MessageReadEvent.php
│       └── MessageTypingEvent.php
└── Exceptions/
    ├── WBMetaException.php
    ├── HttpException.php
    └── WebhookVerificationException.php

```

### Princípios aplicados

[](#princípios-aplicados)

PrincípioAplicação**Clean Architecture**Domain isolado de infraestrutura (HTTP, Auth)**Fluent Interface**`WBMetaClient::fromConfig($config)->to()->text()->send()` e `WBMeta::to()->text()->send()`**DTOs**Nunca expostos payloads brutos da Meta**Mappers**Conversão DTO → payload em classes dedicadas**Dependency Inversion**`HttpClientInterface` e `TokenStorageInterface`**PSR-4**Autoload `Sixtec\WBApi\` → `src/`---

Injeção de Dependências / Frameworks
------------------------------------

[](#injeção-de-dependências--frameworks)

Para integrar em um container DI (Laravel, Symfony, etc.), registre `WBMetaClient`:

```
use Sixtec\WBApi\Config\WBMetaConfig;
use Sixtec\WBApi\WBMetaClient;

$client = WBMetaClient::fromConfig(
    new WBMetaConfig(accessToken: env('WA_TOKEN'), phoneNumberId: env('WA_PHONE_ID')),
);

// Registrar no container e injetar onde necessário
```

Se precisar controlar o transporte HTTP, injete um client compatível com `HttpClientInterface`:

```
use Sixtec\WBApi\Config\WBMetaConfig;
use Sixtec\WBApi\Tests\Fakes\FakeHttpClient;
use Sixtec\WBApi\WBMetaClient;

$config  = new WBMetaConfig(accessToken: env('WA_TOKEN'), phoneNumberId: env('WA_PHONE_ID'));
$client = WBMetaClient::fromConfig($config, new FakeHttpClient());

// Registrar no container e injetar onde necessário
```

---

Testes
------

[](#testes)

```
# Todos os testes
./vendor/bin/phpunit

# Apenas unitários
./vendor/bin/phpunit --testsuite Unit

# Apenas integração
./vendor/bin/phpunit --testsuite Integration
```

A suite usa `FakeHttpClient` — sem chamadas reais à API.

Para testar com sua própria lógica, injete um `FakeHttpClient` em `WBMetaClient::fromConfig()`:

```
use Sixtec\WBApi\Tests\Fakes\FakeHttpClient;
use Sixtec\WBApi\WBMetaClient;

$fake = new FakeHttpClient();
$fake->addResponse(200, [
    'contacts' => [['input' => '5511999999999']],
    'messages' => [['id' => 'wamid.test01', 'message_status' => 'accepted']],
]);

$client = WBMetaClient::fromConfig($config, $fake);
```

---

Exceções
--------

[](#exceções)

ClasseQuando é lançada`WBMetaException`Base — erros gerais da biblioteca`HttpException`Resposta HTTP não-2xx ou falha de rede`WebhookVerificationException`Token ou mode inválido no desafio do webhook---

Licença
-------

[](#licença)

MIT © Mário Lucas

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance98

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~29 days

Total

2

Last Release

10d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/14020978?v=4)[Mário Lucas](/maintainers/mariolucasdev)[@mariolucasdev](https://github.com/mariolucasdev)

---

Top Contributors

[![mariolucasdev](https://avatars.githubusercontent.com/u/14020978?v=4)](https://github.com/mariolucasdev "mariolucasdev (11 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sixtec-wbapi/health.svg)

```
[![Health](https://phpackages.com/badges/sixtec-wbapi/health.svg)](https://phpackages.com/packages/sixtec-wbapi)
```

###  Alternatives

[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3751.2M45](/packages/tencentcloud-tencentcloud-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

1.9k496.1k32](/packages/neuron-core-neuron-ai)[avalara/avataxclient

Client library for Avalara's AvaTax suite of business tax calculation and processing services. Uses the REST v2 API.

528.3M7](/packages/avalara-avataxclient)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

232.5k](/packages/eslazarev-wildberries-sdk)[files.com/files-php-sdk

Files.com PHP SDK

2478.1k](/packages/filescom-files-php-sdk)[aimeos/prisma

A powerful PHP package for integrating media related Large Language Models (LLMs) into your applications

1772.4k4](/packages/aimeos-prisma)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
