Documentação Webhooks Atualização de Status

Webhook - Atualização de Status

Este webhook é enviado sempre que o status de pagamento de uma venda é atualizado.

🔔 Quando é Disparado: Este webhook é enviado quando:
• Um pagamento PIX é confirmado
• Um pagamento é recusado
• Um pagamento é estornado
• Um chargeback é recebido

Estrutura do Payload

Campo Tipo Descrição
transaction_token string Código interno da transação (retornado na criação)
external_code string Código externo informado por você na criação
transaction_amount integer Valor total da transação em centavos
freight_amount integer Valor do frete em centavos
automatic_discount integer Valor do desconto em centavos
payment_status string Status do pagamento (ver tabela abaixo)
payment_type string Tipo de pagamento ('pix')
date_created datetime Data de criação da transação (ISO 8601)
date_approved datetime|null Data de aprovação do pagamento
date_refunded datetime|null Data de estorno/chargeback

Customer (cliente)

Campo Tipo Descrição
customer.full_name string Nome completo do cliente
customer.email string E-mail do cliente
customer.cellphone string Telefone do cliente
customer.identification_number string CPF do cliente

Customer Address (endereço)

Campo Tipo Descrição
customer_address.zip_code string CEP formatado (00000-000)
customer_address.street string Logradouro
customer_address.number string Número
customer_address.neighborhood string Bairro
customer_address.city string Cidade
customer_address.state string Estado (UF)
customer_address.complement string Complemento
customer_address.country string País (código ISO)

Products (produtos)

Array com os produtos da venda

Campo Tipo Descrição
products[x].title string|null Nome do produto
products[x].code string Código externo do produto (do seu sistema)
products[x].amount integer Valor do produto em centavos
products[x].quantity integer Quantidade
products[x].original_amount integer Valor original antes de descontos

UTMs (rastreamento)

Campo Tipo Descrição
utms.src string Origem do tráfego
utms.utm_medium string UTM Medium
utms.utm_source string UTM Source
utms.utm_campaign string UTM Campaign
utms.utm_content string UTM Content
utms.utm_term string UTM Term

Status de Pagamento

Status Descrição
pending Pagamento pendente, aguardando confirmação
approved Pagamento aprovado e confirmado
refused Pagamento recusado
in_process Pagamento em processamento
chargeback Chargeback recebido
refunded Pagamento estornado

Exemplo de Webhook - Pagamento Aprovado

JSON Payload
{
  "transaction_token": "VCP1O8SB9GJ",
  "external_code": "EX001",
  "transaction_amount": 12000,
  "freight_amount": 2000,
  "automatic_discount": 1000,
  "products": [
    {
      "title": "Camiseta Azul",
      "code": "SKU123",
      "amount": 5000,
      "quantity": 2,
      "original_amount": 5000
    },
    {
      "title": "Seguro",
      "code": "SKU456",
      "amount": 1000,
      "quantity": 1,
      "original_amount": 1000
    }
  ],
  "customer": {
    "full_name": "Teste da Silva",
    "email": "teste.silva@example.com",
    "cellphone": "+5511999999999",
    "identification_number": "74600027043"
  },
  "customer_address": {
    "zip_code": "01310-922",
    "street": "Av. Paulista",
    "number": "1000",
    "neighborhood": "Bela Vista",
    "city": "São Paulo",
    "state": "SP",
    "complement": "Conj. 101",
    "country": "BR"
  },
  "utms": {
    "src": "checkout_web",
    "utm_medium": "cpc",
    "utm_source": "google",
    "utm_campaign": "verao2025",
    "utm_content": "banner_home",
    "utm_term": "camiseta azul"
  },
  "payment_status": "approved",
  "payment_type": "pix",
  "date_created": "2024-10-07T14:20:30Z",
  "date_approved": "2024-10-07T14:21:02Z",
  "date_refunded": null
}

Exemplo de Webhook - Pagamento Estornado

JSON Payload
{
  "transaction_token": "VCP1O8SB9GJ",
  "external_code": "EX001",
  "transaction_amount": 12000,
  "freight_amount": 2000,
  "automatic_discount": 1000,
  "products": [
    {
      "title": "Camiseta Azul",
      "code": "SKU123",
      "amount": 5000,
      "quantity": 2,
      "original_amount": 5000
    }
  ],
  "customer": {
    "full_name": "Teste da Silva",
    "email": "teste.silva@example.com",
    "cellphone": "+5511999999999",
    "identification_number": "74600027043"
  },
  "customer_address": {
    "zip_code": "01310-922",
    "street": "Av. Paulista",
    "number": "1000",
    "neighborhood": "Bela Vista",
    "city": "São Paulo",
    "state": "SP",
    "complement": "Conj. 101",
    "country": "BR"
  },
  "utms": {
    "src": "checkout_web",
    "utm_medium": "cpc",
    "utm_source": "google",
    "utm_campaign": "verao2025",
    "utm_content": "banner_home",
    "utm_term": "camiseta azul"
  },
  "payment_status": "refunded",
  "payment_type": "pix",
  "date_created": "2024-10-07T14:20:30Z",
  "date_approved": "2024-10-07T14:21:02Z",
  "date_refunded": "2024-10-08T10:15:45Z"
}

Exemplo de Implementação

PHP
<?php

// Recebe o payload
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);

// Log para debug
error_log("Webhook recebido: " . json_encode($data));

// Extrai informações importantes
$transactionToken = $data['transaction_token'];
$externalCode = $data['external_code'];
$paymentStatus = $data['payment_status'];
$transactionAmount = $data['transaction_amount'];

// Verifica se já processou este webhook
if (webhookJaProcessado($transactionToken)) {
    http_response_code(200);
    echo json_encode(['status' => 'already_processed']);
    exit;
}

// Processa baseado no status
switch ($paymentStatus) {
    case 'approved':
        // Marca pedido como pago
        atualizarPedido($externalCode, [
            'status' => 'paid',
            'transaction_token' => $transactionToken,
            'paid_at' => $data['date_approved']
        ]);

        // Envia e-mail de confirmação
        enviarEmailConfirmacao($externalCode);

        // Libera produtos digitais
        liberarProdutosDigitais($externalCode);
        break;

    case 'refunded':
    case 'chargeback':
        // Marca pedido como estornado
        atualizarPedido($externalCode, [
            'status' => 'refunded',
            'refunded_at' => $data['date_refunded']
        ]);

        // Notifica o cliente
        enviarEmailEstorno($externalCode);

        // Remove acesso a produtos digitais
        revogarAcessoProdutos($externalCode);
        break;

    case 'refused':
        // Marca pedido como recusado
        atualizarPedido($externalCode, [
            'status' => 'refused'
        ]);
        break;
}

// Marca webhook como processado
marcarWebhookComoProcessado($transactionToken);

// Retorna sucesso
http_response_code(200);
echo json_encode(['status' => 'success']);

⚠️ Importante: Sempre valide e sanitize os dados recebidos antes de processar. Implemente controles de idempotência para evitar processar o mesmo webhook múltiplas vezes.

💡 Dica: Você pode usar o external_code para identificar o pedido no seu sistema. Certifique-se de armazenar também o transaction_token para referência futura e suporte.