# Sunize — API de Pagamentos v1 (guia para integração via IA) > Este arquivo é um guia único e autocontido da API de pagamentos v1 da Sunize, > pensado para ser colado inteiro em uma IA (ChatGPT, Claude, Copilot etc.) junto > com um pedido de integração. Ele cobre autenticação, os endpoints de > transação, webhook e erros — não é necessário abrir nenhum outro link para > gerar uma integração completa. > > Doc navegável (com exemplos em cURL/Node.js/PHP/Python): https://docs.sunize.com.br/index.html > Índice de versões da API: https://docs.sunize.com.br/llms.txt > > Precisa de estorno, assinaturas (Pix Automático/cartão recorrente) ou UTM na > criação da transação? Esses recursos só existem na API v2 — veja > https://docs.sunize.com.br/llms-v2.txt (é preciso criar uma credencial v2 > separada, ver seção "Autenticação" abaixo). ## Prompt sugerido Copie o bloco abaixo (ou este arquivo inteiro) e cole numa IA, adaptando a linguagem/framework: ``` Aqui está a documentação completa da API de pagamentos Sunize v1 (formato Markdown). Implemente em [SUA LINGUAGEM/FRAMEWORK] um client que: 1. Cria uma transação PIX ou cartão de crédito (POST /v1/transactions) 2. Consulta o status de uma transação (GET /v1/transactions/:id) 3. Recebe e valida o webhook de status de transação Use variáveis de ambiente para as credenciais (SUNIZE_API_KEY, SUNIZE_API_SECRET) e trate os erros documentados. ``` --- ## Visão geral - **URL base:** `https://api.sunize.com.br/v1` - **Formato:** JSON (`Content-Type: application/json`) - **Autenticação:** dois headers em toda requisição — `x-api-key` e `x-api-secret` (ambos obrigatórios; um request sem eles, ou com o valor errado, retorna `401`). - **Moeda:** sempre reais (BRL), como número decimal (ex: `149.90`), nunca em centavos. - **Onde obter credenciais:** painel da conta Sunize → Integrações → API → Nova credencial, escolhendo a versão **v1**. - **Credencial é por versão:** cada chave (`x-api-key`/`x-api-secret`) só funciona nos endpoints da versão em que foi criada. Uma credencial v1 não funciona em `/v2/*`, e vice-versa. Não é possível trocar a versão de uma credencial já criada. - **Atenção ao nome do campo de valor:** o valor da transação tem nomes diferentes dependendo do endpoint — `total_amount` no corpo de criação, `total_value` na resposta de criação, e `amount` na consulta e no webhook. Use exatamente o nome indicado em cada seção abaixo. - **Reenviar o mesmo pedido não gera PIX duplicado:** veja "Reaproveitamento de PIX pendente" na seção de transações — use sempre o mesmo `external_id` por pedido para não sujar sua taxa de conversão com PIX pendente repetido. ## Autenticação ``` x-api-key: SEU_API_KEY x-api-secret: SEU_API_SECRET Content-Type: application/json ``` Envie os dois headers em toda requisição, incluindo `GET`s. --- ## Transações ### Criar transação `POST /v1/transactions` Corpo da requisição: ```json { "external_id": "string (seu identificador único do pedido)", "total_amount": 149.90, "payment_method": "PIX | CREDIT_CARD", "items": [ { "id": "string", "title": "string", "description": "string", "price": 149.90, "quantity": 1, "is_physical": false } ], "ip": "string (IP do comprador)", "customer": { "name": "string", "email": "string", "phone": "string (formato E.164, ex: +5511999999999)", "document_type": "CPF | CNPJ", "document": "string (CPF ou CNPJ válido, só dígitos)" }, "card": { "card_number": "string", "card_holder_name": "string", "card_expiration_date": "string (MM/AAAA)", "card_cvv": "string", "installment": 1 }, "splits": [ { "user_id": "string", "type": "percentage | fixed", "value": 25 } ] } ``` Notas de campo: - O campo do valor aqui é **`total_amount`** (não `amount`). - `card` é **obrigatório** quando `payment_method` é `CREDIT_CARD`; omita quando for `PIX`. - `splits` é opcional — cada item divide parte do valor com outro usuário Sunize (`user_id`), como percentual (`percentage`, ex: `25` = 25%) ou valor fixo em reais (`fixed`). Resposta (`200`) — aqui o campo do valor é **`total_value`**: ```json { "id": "string", "external_id": "string", "status": "AUTHORIZED | PENDING | CHARGEBACK | FAILED | IN_DISPUTE", "total_value": 149.90, "customer": { "email": "string", "name": "string" }, "payment_method": "string", "pix": { "payload": "string (só presente quando payment_method=PIX; é o código copia-e-cola)" }, "hasError": false, "reused": "boolean (opcional — só aparece como true quando esta é uma resposta reaproveitada, ver abaixo)" } ``` ### Reaproveitamento de PIX pendente Se você chamar `POST /v1/transactions` de novo com o **mesmo `external_id`** (dentro da sua própria credencial), o **mesmo `total_amount`** e o **mesmo `customer.document`** de uma transação PIX que você mesmo acabou de criar e que ainda está pendente (até 6 horas depois de criada), a API devolve **o mesmo PIX** — mesmo `id`, mesmo `pix.payload` — em vez de gerar um novo. A resposta vem com `"reused": true`; numa transação nova esse campo não aparece. Isso existe pra proteger sua taxa de conversão: se o seu sistema reprocessa o mesmo pedido (retry de rede, usuário atualizando a página, redelivery de fila) sem controlar isso, cada tentativa gera um PIX pendente novo que nunca é pago — inflando artificialmente o número de vendas "pendentes" e derrubando sua taxa de conversão real, mesmo quando o cliente pagou o primeiro PIX gerado. **Ao integrar, use sempre o mesmo `external_id` para o mesmo pedido** (nunca gere um novo `external_id` a cada tentativa/retry do mesmo pedido) e deixe a API decidir se reaproveita ou gera um PIX novo. Só vale para `payment_method: "PIX"` — `CREDIT_CARD` sempre processa uma nova tentativa de cobrança, já que cada envio de cartão é uma ação explícita do comprador. ### Consultar transação `GET /v1/transactions/:transaction_id` Resposta (`200`) — aqui o campo do valor é **`amount`**: ```json { "id": "string", "external_id": "string", "status": "string", "amount": 149.90, "payment_method": "string", "customer": { "name": "string", "email": "string", "phone": "string", "document": "string", "address": { "cep": "string", "city": "string", "state": "string", "number": "string", "street": "string", "complement": "string", "neighborhood": "string" } }, "created_at": "string (ISO 8601)" } ``` --- ## Webhook Enviado por `POST` para a URL configurada na credencial de API, com o header `x-api-secret` (valide-o para confirmar que a chamada veio da Sunize). Responda `200` rapidamente e processe de forma assíncrona. ```json { "id": "string", "external_id": "string", "total_amount": 149.90, "status": "AUTHORIZED | PENDING | CHARGEBACK | FAILED | IN_DISPUTE", "payment_method": "string" } ``` Notas: - Aqui o campo do valor é **`total_amount`**. - Estorno e disputa de cartão chegam com o mesmo status, `CHARGEBACK` — a v1 não distingue os dois casos. --- ## Erros Todos os endpoints podem retornar: | Código | Quando | |---|---| | `401` | `x-api-key`/`x-api-secret` ausentes, inválidos, ou de uma credencial de outra versão da API | | `400` | Dados inválidos na requisição | | `500` | Erro interno do servidor |