# Sunize — API de Pagamentos v2 (guia para integração via IA) > Este arquivo é um guia único e autocontido da API de pagamentos v2 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, todos os endpoints > (transações avulsas, estorno e assinaturas), webhooks 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/v2.html > Índice de versões da API: https://docs.sunize.com.br/llms.txt ## 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 v2 (formato Markdown). Implemente em [SUA LINGUAGEM/FRAMEWORK] um client que: 1. Cria uma transação PIX ou cartão de crédito (POST /v2/transactions) 2. Consulta o status de uma transação (GET /v2/transactions/:id) 3. Recebe e valida o webhook de status de transação 4. [opcional] Cria e cancela uma assinatura recorrente 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/v2` - **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. - **Valor mínimo de transação:** R$ 5,00. - **Onde obter credenciais:** painel da conta Sunize → Integrações → API → Nova credencial, escolhendo a versão **v2**. - **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 v2 não funciona em `/v1/*`, e vice-versa. Não é possível trocar a versão de uma credencial já criada. - **Padrão de nomes:** o valor monetário é chamado de `amount` em todos os endpoints (corpo de criação, resposta, consulta e webhook). - **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 avulsas ### Criar transação `POST /v2/transactions` Corpo da requisição: ```json { "external_id": "string (seu identificador único do pedido)", "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 } ], "tracking": { "utm_source": "string", "utm_medium": "string", "utm_campaign": "string", "utm_content": "string", "utm_term": "string" } } ``` Notas de campo: - `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`). - `tracking` é opcional — todos os campos são strings opcionais. Os valores enviados voltam no payload do webhook. Resposta (`200`): ```json { "id": "string", "external_id": "string", "status": "AUTHORIZED | PENDING | CHARGEBACK | REFUNDED | FAILED | IN_DISPUTE", "amount": 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 /v2/transactions` de novo com o **mesmo `external_id`** (dentro da sua própria credencial), o **mesmo `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 /v2/transactions/:transaction_id` Resposta (`200`): ```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)" } ``` ### Estornar transação `POST /v2/transactions/:transaction_id/refund` Sem corpo de requisição. Resposta (`200`): ```json { "id": "string", "status": "REFUNDED" } ``` Pré-condições (retornam `400` se não atendidas): a venda precisa estar `AUTHORIZED`, ter sido criada por esta mesma API, e todos os participantes (produtor e coprodutores/afiliados de split) precisam ter saldo suficiente para devolver o valor. --- ## Assinaturas (vendas recorrentes) Dois trilhos suportados, no mesmo endpoint: - **`CREDIT_CARD`** — cobrança automática recorrente no cartão salvo na 1ª cobrança. - **`PIX`** (Pix Automático) — débito automático via Pix, autorizado **uma única vez** pelo comprador (escaneando um QR code / abrindo um link); cobranças seguintes acontecem sem novo QR. Toda credencial v2 já pode criar assinaturas por Pix Automático — vem habilitado por padrão. Cartão recorrente não vem habilitado por padrão; entre em contato com a nossa equipe para ativar essa funcionalidade na sua conta. ### Criar assinatura `POST /v2/subscriptions` Corpo da requisição: ```json { "external_id": "string", "amount": 97.00, "payment_method": "PIX | CREDIT_CARD", "membership_period": "SEMANAL | MENSAL | BIMESTRAL | SEMESTRAL | ANUAL", "items": [ /* mesmo formato de items da transação avulsa */ ], "ip": "string", "customer": { /* mesmo formato de customer da transação avulsa */ }, "card": { "card_number": "string", "card_holder_name": "string", "card_expiration_date": "string (MM/AAAA)", "card_cvv": "string", "installment": 1 }, "splits": [ /* opcional, mesmo formato da transação avulsa */ ], "tracking": { /* opcional, mesmo formato da transação avulsa */ } } ``` Notas de campo: - `card` é obrigatório apenas quando `payment_method` é `CREDIT_CARD`; envie sempre `installment: 1` (assinaturas não usam parcelamento — é o valor cobrado a cada ciclo, não uma divisão do valor total). - `membership_period`: **Pix Automático só aceita `SEMANAL`, `MENSAL` ou `ANUAL`** — `BIMESTRAL`/`SEMESTRAL` só valem para `CREDIT_CARD` (retorna `400` se enviado com PIX). Resposta quando `payment_method = CREDIT_CARD` (`200`): ```json { "id": "string", "external_id": "string", "status": "ACTIVE", "amount": 97, "membership_period": "MENSAL", "payment_method": "CREDIT_CARD", "next_payment_date": "string (ISO 8601)" } ``` Resposta quando `payment_method = PIX` (`200`) — a assinatura nasce aguardando o comprador autorizar: ```json { "id": "string", "external_id": "string", "status": "PENDING_AUTHORIZATION", "amount": 97, "membership_period": "MENSAL", "payment_method": "PIX", "pix": { "qr_code": "string (código copia-e-cola / payload do QR)", "payment_link": "string (opcional, link direto)" } } ``` Mostre `pix.qr_code` (ou `payment_link`) para o comprador escanear/autorizar **uma única vez**. Quando ele autorizar, você recebe o webhook `SUBSCRIPTION_AUTHORIZED` e a assinatura passa a `ACTIVE`. Erros específicos (`400`): cartão recorrente não habilitado para a credencial (fale com a nossa equipe); pagamento com cartão recusado (assinatura não é criada); período incompatível com Pix Automático. ### Consultar assinatura `GET /v2/subscriptions/:subscription_id` Resposta (`200`): ```json { "id": "string", "external_id": "string", "status": "ACTIVE | PENDING_AUTHORIZATION | LATE | PAUSED | CANCELED", "amount": 97, "membership_period": "string", "payment_method": "PIX | CREDIT_CARD", "next_payment_date": "string (ISO 8601)", "last_payment_date": "string (ISO 8601)" } ``` ### Cancelar assinatura `POST /v2/subscriptions/:subscription_id/cancel` Sem corpo de requisição. O comprador mantém acesso até o fim do ciclo já pago. Resposta (`200`): ```json { "id": "string", "status": "CANCELED" } ``` --- ## Webhooks Enviados 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. ### Webhook de transação ```json { "id": "string", "external_id": "string", "amount": 149.90, "status": "AUTHORIZED | PENDING | CHARGEBACK | REFUNDED | FAILED | IN_DISPUTE", "payment_method": "string", "tracking": { "utm_source": "string | null", "utm_medium": "string | null", "utm_campaign": "string | null", "utm_content": "string | null", "utm_term": "string | null" } } ``` `REFUNDED` (estorno) e `CHARGEBACK` (disputa) são sempre status distintos. ### Webhook de assinatura ```json { "event": "SUBSCRIPTION_CREATED | SUBSCRIPTION_AUTHORIZED | SUBSCRIPTION_RENEWED | SUBSCRIPTION_LATE | SUBSCRIPTION_CANCELED | SUBSCRIPTION_RECOVERED", "id": "string", "external_id": "string", "status": "ACTIVE | PENDING_AUTHORIZATION | LATE | CANCELED", "amount": 97, "payment_method": "PIX | CREDIT_CARD", "membership_period": "string", "next_payment_date": "string | null" } ``` Significado de cada `event`: | Evento | Quando dispara | |---|---| | `SUBSCRIPTION_CREATED` | Assinatura criada (cartão: já ativa; Pix: aguardando autorização) | | `SUBSCRIPTION_AUTHORIZED` | Comprador autorizou o Pix Automático — assinatura vira `ACTIVE` | | `SUBSCRIPTION_RENEWED` | Nova cobrança do ciclo aprovada | | `SUBSCRIPTION_LATE` | Cobrança do ciclo falhou | | `SUBSCRIPTION_CANCELED` | Assinatura cancelada (comprador, produtor ou plataforma) | | `SUBSCRIPTION_RECOVERED` | Uma cobrança que havia falhado foi recuperada | --- ## 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 (corpo malformado, regra de negócio violada — a mensagem de erro vem no corpo da resposta) | | `500` | Erro interno do servidor |