{
 "openapi": "3.0.3",
 "info": {
  "title": "API PayVip",
  "version": "1.0.0",
  "description": "Porta única para parceiros (ERPs, software houses) integrarem cobranças, assinaturas, split de pagamentos e contas a pagar da PayVip.\n\n**Autenticação**: `Authorization: Bearer sk_live_...` (chave gerada no console, painel API). **Todo POST exige** header `Idempotency-Key` — repetir a mesma chave devolve a resposta anterior sem duplicar. Limite: 120 req/min por chave.\n\n**Erros** sempre no formato `{\"erro\": {\"tipo\", \"mensagem\", \"detalhe\"}}` — tipos: unauthorized(401), forbidden(403), not_found(404), conflict(409), rate_limit(429), upstream_error(502).",
  "contact": {
   "name": "PayVip",
   "email": "suporte@payvip.com.br"
  }
 },
 "servers": [
  {
   "url": "https://payvip-api.io",
   "description": "Produção"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  }
 ],
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "sk_live_..."
   }
  },
  "parameters": {
   "Idem": {
    "name": "Idempotency-Key",
    "in": "header",
    "required": true,
    "schema": {
     "type": "string"
    },
    "description": "Obrigatória em todo POST"
   }
  }
 },
 "tags": [
  {
   "name": "Clientes"
  },
  {
   "name": "Cobranças"
  },
  {
   "name": "Assinaturas"
  },
  {
   "name": "Itens de split (catálogo)"
  },
  {
   "name": "Parceiros"
  },
  {
   "name": "Pedidos e transações"
  },
  {
   "name": "Split manual"
  },
  {
   "name": "Contas a pagar (Flows)"
  },
  {
   "name": "Webhooks"
  }
 ],
 "paths": {
  "/v1/ping": {
   "get": {
    "summary": "Testa a credencial",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "tags": [
     "Clientes"
    ]
   }
  },
  "/v1/clientes": {
   "post": {
    "summary": "Cadastra cliente",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `clientes:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "nome": {
          "type": "string",
          "description": "obrigatório"
         },
         "documento": {
          "type": "string",
          "description": "CPF/CNPJ (com ou sem máscara)"
         },
         "email": {
          "type": "string",
          "description": "opcional"
         },
         "telefone": {
          "type": "string",
          "description": "opcional"
         },
         "endereco": {
          "type": "object",
          "description": "logradouro, numero, complemento, bairro, cidade, uf, cep"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Clientes"
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Idem"
     }
    ]
   },
   "get": {
    "summary": "Busca por documento (sem filtro: lista 50)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `clientes:read`",
    "parameters": [
     {
      "name": "documento",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Clientes"
    ]
   }
  },
  "/v1/clientes/{id}": {
   "get": {
    "summary": "Detalhe do cliente",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `clientes:read`",
    "tags": [
     "Clientes"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/cobrancas": {
   "post": {
    "summary": "Cria cobrança avulsa ou recorrente (com ou sem split)",
    "responses": {
     "200": {
      "description": "201 — cobrança + fatura com link/PIX + rateios[]"
     }
    },
    "description": "Escopo: `cobrancas:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "cliente_id": {
          "type": "string",
          "description": "OU documento"
         },
         "documento": {
          "type": "string",
          "description": "OU cliente_id (cria com `nome`)"
         },
         "valor_centavos": {
          "type": "integer",
          "description": "total, em centavos"
         },
         "metodo": {
          "type": "string",
          "description": "pix | boleto | pix_boleto | card"
         },
         "vencimento": {
          "type": "string",
          "description": "AAAA-MM-DD"
         },
         "parcelas": {
          "type": "integer"
         },
         "descricao": {
          "type": "string",
          "description": "livre"
         },
         "recorrente": {
          "type": "object",
          "description": "{frequencia: monthly..., intervalo}"
         },
         "itens": {
          "type": "array",
          "description": "SPLIT: [{item_split_id, quantity, unitary_value?}] do catálogo"
         },
         "emitir_nfse": {
          "type": "boolean"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Cobranças"
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Idem"
     }
    ]
   }
  },
  "/v1/cobrancas/{id}": {
   "get": {
    "summary": "Status + faturas + rateios",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `cobrancas:read`",
    "tags": [
     "Cobranças"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/cobrancas/{id}/cancelar": {
   "post": {
    "summary": "Cancela a cobrança",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `cobrancas:write`",
    "tags": [
     "Cobranças"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/faturas": {
   "get": {
    "summary": "Faturas do período",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `cobrancas:read`",
    "parameters": [
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "de",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "ate",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Cobranças"
    ]
   }
  },
  "/v1/assinaturas": {
   "get": {
    "summary": "Lista assinaturas (tem_split, rateios)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `cobrancas:read`",
    "parameters": [
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Assinaturas"
    ]
   }
  },
  "/v1/assinaturas/{id}/pausar": {
   "post": {
    "summary": "Pausar assinatura",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `cobrancas:write`",
    "tags": [
     "Assinaturas"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/assinaturas/{id}/reativar": {
   "post": {
    "summary": "Reativar assinatura",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `cobrancas:write`",
    "tags": [
     "Assinaturas"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/itens-split": {
   "get": {
    "summary": "Catálogo de itens (preço + comissão do parceiro)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `parceiros:read`",
    "parameters": [
     {
      "name": "busca",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "incluir_inativos",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Itens de split (catálogo)"
    ]
   },
   "post": {
    "summary": "Cria item — comissao é SEMPRE percentual",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `parceiros:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "descricao": {
          "type": "string",
          "description": "obrigatório"
         },
         "parceiro_people_id": {
          "type": "string",
          "description": "recebedor credenciado"
         },
         "valor_unitario": {
          "type": "number",
          "description": "PREÇO do serviço (R$)"
         },
         "comissao": {
          "type": "number",
          "description": "% do repasse (45 = 45%)"
         },
         "custo_unitario": {
          "type": "number",
          "description": "desconta da base antes da comissão"
         },
         "taxa_ec": {
          "type": "boolean"
         },
         "taxa_parceiro": {
          "type": "boolean"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Itens de split (catálogo)"
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Idem"
     }
    ]
   }
  },
  "/v1/itens-split/{id}": {
   "delete": {
    "summary": "Inativa item (histórico preservado)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `parceiros:write`",
    "tags": [
     "Itens de split (catálogo)"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/parceiros": {
   "get": {
    "summary": "Lista/busca parceiros",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `parceiros:read`",
    "parameters": [
     {
      "name": "busca",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Parceiros"
    ]
   },
   "post": {
    "summary": "Cadastra parceiro de split",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `parceiros:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "nome": {
          "type": "string",
          "description": "obrigatório"
         },
         "documento": {
          "type": "string",
          "description": "CPF/CNPJ"
         },
         "people_id_parceiro": {
          "type": "string",
          "description": "cadastro do recebedor (com seller na adquirente)"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Parceiros"
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Idem"
     }
    ]
   }
  },
  "/v1/pedidos": {
   "get": {
    "summary": "Pedidos com rateios",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `pedidos:read`",
    "parameters": [
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "de",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "ate",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "limite",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Pedidos e transações"
    ]
   }
  },
  "/v1/pedidos/{id}": {
   "get": {
    "summary": "Detalhe do pedido",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `pedidos:read`",
    "tags": [
     "Pedidos e transações"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/transacoes": {
   "get": {
    "summary": "Transações da empresa",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `transacoes:read`",
    "parameters": [
     {
      "name": "de",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "ate",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "limite",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Pedidos e transações"
    ]
   }
  },
  "/v1/transacoes/{id}": {
   "get": {
    "summary": "Transação + pernas do split",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `transacoes:read`",
    "tags": [
     "Pedidos e transações"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/transacoes/{id}/split": {
   "get": {
    "summary": "Split valendo na adquirente (fonte externa)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `split:read`",
    "tags": [
     "Pedidos e transações"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/splits": {
   "post": {
    "summary": "Cria RASCUNHO de split p/ transação capturada",
    "responses": {
     "200": {
      "description": "201 — rascunho com cálculo (líquido, taxa, restante_ec)"
     }
    },
    "description": "Escopo: `split:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "transaction_id": {
          "type": "string",
          "description": "transação da empresa"
         },
         "cliente_documento": {
          "type": "string",
          "description": "OU cliente_id"
         },
         "descricao": {
          "type": "string",
          "description": "livre"
         },
         "rateios": {
          "type": "array",
          "description": "[{parceiro_id|people_id_parceiro, valor (bruto R$), assume_taxa, descricao?}]"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Split manual"
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Idem"
     }
    ]
   },
   "get": {
    "summary": "Lista rascunhos/splits",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `split:read`",
    "parameters": [
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Split manual"
    ]
   }
  },
  "/v1/splits/{id}": {
   "get": {
    "summary": "Estado atual (reflete a fila de execução)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `split:read`",
    "tags": [
     "Split manual"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "put": {
    "summary": "Edita rateios (só rascunho)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `split:write`",
    "tags": [
     "Split manual"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "delete": {
    "summary": "Exclui (só rascunho)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `split:write`",
    "tags": [
     "Split manual"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/splits/{id}/confirmar": {
   "post": {
    "summary": "CONFIRMA → fila → adquirente (202; acompanhe pelo GET)",
    "responses": {
     "200": {
      "description": "202 — processando"
     }
    },
    "description": "Escopo: `split:write`",
    "tags": [
     "Split manual"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/contas-pagar": {
   "get": {
    "summary": "Contas a pagar",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `contas_pagar:read`",
    "parameters": [
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "de",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "ate",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "tags": [
     "Contas a pagar (Flows)"
    ]
   },
   "post": {
    "summary": "Lança despesa (entra no fluxo de aprovação — a API não paga)",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `contas_pagar:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "fornecedor": {
          "type": "string",
          "description": "obrigatório"
         },
         "valor": {
          "type": "number"
         },
         "vencimento": {
          "type": "string",
          "description": "AAAA-MM-DD"
         },
         "documento_fornecedor": {
          "type": "string",
          "description": "opcional"
         },
         "codigo_barras": {
          "type": "string",
          "description": "boleto"
         },
         "pix_chave": {
          "type": "string",
          "description": "pix manual"
         },
         "categoria": {
          "type": "string",
          "description": "código DRE"
         },
         "descricao": {
          "type": "string",
          "description": "livre"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Contas a pagar (Flows)"
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Idem"
     }
    ]
   }
  },
  "/v1/contas-pagar/{id}": {
   "get": {
    "summary": "Detalhe",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "description": "Escopo: `contas_pagar:read`",
    "tags": [
     "Contas a pagar (Flows)"
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ]
   }
  },
  "/v1/webhooks": {
   "post": {
    "summary": "Registra endpoint (segredo whsec_ mostrado UMA vez)",
    "responses": {
     "200": {
      "description": "201 — {id, url, eventos, segredo}"
     }
    },
    "description": "Escopo: `webhooks:write`",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "https obrigatório"
         },
         "eventos": {
          "type": "array",
          "description": "cobranca.criada|paga|vencida|cancelada, assinatura.criada"
         }
        }
       }
      }
     }
    },
    "tags": [
     "Webhooks"
    ]
   },
   "get": {
    "summary": "Lista webhooks registrados",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "tags": [
     "Webhooks"
    ]
   }
  }
 }
}