API Overview — FDPlay Streaming Platform¶
Versão da API: v1
Base URL: /api/v1
Autenticação: OAuth2 Password Bearer (JWT)
📋 Sumário¶
Esta API fornece endpoints para gerenciamento completo de uma plataforma de streaming com assinaturas recorrentes via Stripe e Asaas.
Principais Recursos¶
- Autenticação — Login com JWT tokens
- Usuários — Admins e Customers (STI - Single Table Inheritance)
- Assinaturas — Signup, gerenciamento e webhooks (Stripe + Asaas)
- Planos — Listagem pública e gerenciamento admin
- Vídeos — CRUD com controle de acesso por assinatura
- Conteúdo — Categorias, tags, grupos, flows
- Webhooks — Notificações Stripe e Asaas, logs de auditoria
- Stripe Billing — Gateway com rotas isoladas
🔐 Autenticação¶
Obter Token JWT¶
POST /api/v1/token
Content-Type: application/x-www-form-urlencoded
username=admin_user&password=secret123
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"id_token": "507f1f77bcf86cd799439011",
"expiration": "2026-01-19T04:30:00Z",
"archive_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Usar Token nas Requisições¶
📨 Headers Obrigatórios¶
Para Todas as Requisições Autenticadas¶
| Header | Valor | Obrigatório | Descrição |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Sim* | Token JWT obtido via /token |
Content-Type |
application/json |
✅ Sim** | Tipo de conteúdo do body |
Obrigatório em rotas protegidas (não necessário em rotas públicas)
*Obrigatório em requisições POST/PUT com body JSON
Exemplo Completo¶
POST /api/v1/customers/me/subscribe
Host: fdplay-api.infraifd.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"plan_id": "plan-basic",
"payment_method": "credit_card",
"encrypted_card": "...",
"card_security_code": "123"
}
Erros Comuns de Headers
401 Unauthorized — Header Authorization ausente ou token inválido/expirado
415 Unsupported Media Type — Header Content-Type ausente em POST/PUT
422 Unprocessable Entity — Body JSON malformado
👥 Tipos de Usuários (STI - Single Table Inheritance)¶
A API utiliza Single Table Inheritance (STI) para gerenciar usuários. Todos os usuários são armazenados na collection users do MongoDB, diferenciados pelo campo user_type.
Arquitetura STI¶
Collection: users
├── user_type: "admin" → Endpoint: GET /api/v1/users
└── user_type: "customer" → Endpoint: GET /api/v1/customers
Admin (user_type: "admin")¶
- Acesso: Completo (CRUD em todos os recursos)
- Bypass: Não precisa de assinatura ativa
- Uso: Gerenciamento da plataforma
- Endpoint:
GET /api/v1/users(retorna apenas admins)
Customer (user_type: "customer")¶
- Acesso: Vídeos e gerenciamento de própria conta
- Requer: Assinatura ativa para acessar vídeos
- Uso: Consumo de conteúdo
- Endpoint:
GET /api/v1/customers(retorna apenas customers)
🎯 Fluxos Principais¶
1. Signup de Customer (Freemium com Verificação de Email)¶
graph LR
A[Frontend] -->|"POST /customers/signup (sem código)"| B[API]
B -->|Cria customer email_verified=false| D[(MongoDB)]
B -->|Envia código 6 dígitos| E[Resend Email]
E -->|Email com código| A
A -->|"POST /customers/signup (com código)"| B
B -->|email_verified=true| D
B -->|Return JWT| A
Endpoint: POST /api/v1/customers/signup (2 passos no mesmo endpoint)
- Passo 1 (sem
verification_code): Cria customer + envia código por email - Passo 2 (com
verification_code): Valida código + retorna JWT
Ver detalhes em Customer Signup
2. Acesso a Vídeos (Customer)¶
graph LR
A[Frontend] -->|GET /videos| B[Middleware]
B -->|Check subscription| C{Active?}
C -->|Yes| D[Return videos]
C -->|No| E[403 Forbidden]
Endpoint: GET /api/v1/videos
Nota de contrato: O payload de vídeo inclui is_show_in_slide_carousel para o frontend identificar quais vídeos devem aparecer no slide carousel.
Ver detalhes em Videos API
3. Webhook Stripe¶
graph LR
A[Stripe] -->|POST /webhooks/stripe| B[API]
B -->|Validate Stripe-Signature| C{Valid?}
C -->|Yes| D[Process event]
C -->|No| E[401 Unauthorized]
D -->|Update subscription| F[(Database)]
D -->|Save log| F
Endpoint: POST /webhooks/stripe
Ver detalhes em Webhooks
4. Assinatura via Stripe¶
graph LR
A[Flutter] -->|Stripe SDK| B[createPaymentMethod]
B -->|pm_xxx| C[POST /stripe/subscribe]
C -->|Create subscription| D[Stripe API]
D -->|sub_xxx| C
C -->|Save MongoDB| E[(Database)]
C -->|Return| A
Endpoints Stripe: Ver Integração Stripe
📚 Documentação por Recurso¶
| Recurso | Descrição | Link |
|---|---|---|
| Authentication | Login, tokens, OAuth2 | Docs |
| Customers | Signup, perfil, assinatura | Docs |
| Plans | Planos públicos e admin | Docs |
| Admin Dashboard | Subscriptions e logs | Docs |
| Videos | CRUD e streaming | Docs |
| Categories, Tags & Groups | Categorização, tags e grupos | Docs |
| Perfil | Avatar e histórico de reprodução | Docs |
| Webhooks | Stripe + Asaas + Logs | Docs |
| Stripe Billing | Subscribe, cancel, payment method | Docs |
| Asaas Billing | Subscribe, cancel, credit card | Docs |
| Finance Dashboard | Visao geral financeira, receita, inadimplencia, churn | Docs |
| Search | Busca generica por collection | Docs |
| Contact | Formulario de contato | Docs |
| Streaming | URLs de streaming de video | Docs |
| Refund | Reembolso de assinaturas | Docs |
| Events & Tickets | Eventos e ingressos | Docs |
| Ticket Store | Loja de ingressos (compra avulsa) | Docs |
| Events Dashboard | Dashboard admin de eventos | Docs |
| Promo Codes | Codigos promocionais e ingressos | Docs |
| Platform Config | Gateway padrão (admin set, frontend query) | Docs |
🛡️ Controle de Acesso¶
Rotas Públicas (Sem Autenticação)¶
POST /api/v1/token— LoginPOST /api/v1/customers/signup— Cadastro de customer (2 passos com verificação de email)GET /api/v1/customers/check-availability— Verificar disponibilidade de email/CPFGET /api/v1/plans— Listar planos ativosPOST /api/v1/auth/forgot-password— Solicitar reset de senhaPOST /api/v1/auth/reset-password— Resetar senha com tokenPOST /api/v1/auth/resend-verification— Reenviar código de verificação de emailPOST /webhooks/stripe— Webhook Stripe (autenticado via Stripe-Signature)GET /api/v1/avatars/{file_id}— Download de avatar (público)GET /api/v1/config/payment-gateway— Gateway de pagamento padrão (frontend consulta)GET /api/v1/config/pix-billing-mode— Modo de cobrança PIXGET /api/v1/stripe/config— Stripe publishable keyGET /api/v1/customers/validate-promo-code— Validar código promo (auth opcional)POST /webhooks/asaas— Webhook Asaas (autenticado via token)
Rotas Protegidas (Requer JWT)¶
GET /api/v1/videos— Requer assinatura ativa (customers) ou adminGET /api/v1/customers/me— Customer autenticadoPUT /api/v1/customers/me— Atualizar próprio perfilPOST /api/v1/customers/me/subscribe— Criar assinaturaGET /api/v1/customers/me/subscription— Status da assinaturaDELETE /api/v1/customers/me/subscription— Cancelar assinaturaPUT /api/v1/customers/me/subscription/renew— Renovar assinatura ⚠️ HTTP 501 (Not Implemented)
Nota: Este endpoint retorna HTTP 501 (Not Implemented). O fluxo de renovacao ainda nao foi implementado para o gateway Asaas. -
DELETE /api/v1/customers/me— Deletar conta (cascade) -POST /api/v1/auth/change-password— Alterar senha -POST /api/v1/auth/refresh-archive-token— Renovar archive token -POST /api/v1/stripe/subscribe— Criar assinatura Stripe (cartao) -POST /api/v1/stripe/subscribe/pix— Criar assinatura Stripe PIX (anual) -GET /api/v1/stripe/subscription— Status da assinatura Stripe -PUT /api/v1/stripe/subscription/payment-method— Trocar método de pagamento Stripe -DELETE /api/v1/stripe/subscription— Cancelar assinatura Stripe -POST /api/v1/me/avatar— Upload de avatar (Admin ou Customer) -DELETE /api/v1/me/avatar— Remover avatar -PUT /api/v1/me/watch-history— Atualizar progresso de vídeo -GET /api/v1/me/watch-history— Consultar histórico de reprodução -DELETE /api/v1/me/watch-history— Limpar histórico de reprodução -GET /api/v1/me/tickets— Meus ingressos -GET /api/v1/me/ticket-orders— Meus pedidos de ingressos -GET /api/v1/me/ticket-orders/{order_id}— Detalhe de pedido -GET /api/v1/me/tickets/{ticket_id}/qr— QR code do ingresso -GET /api/v1/customers/validate-promo-code— Validar codigo promo (auth opcional) -PUT /api/v1/customers/me/redeem-promo-code— Resgatar codigo promo -GET /api/v1/customers/me/promo-codes— Listar codigos promo do customer -POST /api/v1/customers/me/change-email— Solicitar alteracao de email -POST /api/v1/customers/me/confirm-email— Confirmar alteração de email -POST /api/v1/asaas/subscribe— Criar assinatura Asaas (cartão) -POST /api/v1/asaas/subscribe/pix— Criar assinatura Asaas PIX -GET /api/v1/asaas/subscription— Status da assinatura Asaas -PUT /api/v1/asaas/subscription/credit-card— Atualizar cartão Asaas -DELETE /api/v1/asaas/subscription— Cancelar assinatura Asaas -GET /api/v1/store/events— Listar eventos na loja -GET /api/v1/store/events/{event_id}— Detalhe de evento na loja -POST /api/v1/store/purchase/asaas/card— Comprar ingresso via Asaas cartao -POST /api/v1/store/purchase/asaas/pix— Comprar ingresso via Asaas PIX -POST /api/v1/store/purchase/stripe/card— Comprar ingresso via Stripe cartao -POST /api/v1/store/purchase/stripe/pix— Comprar ingresso via Stripe PIX -GET /api/v1/search/{collection_name}— Busca generica por collection
Rotas Admin (Requer JWT + user_type='admin')¶
Usuarios e Customers
GET /api/v1/users— Listar adminsPOST /api/v1/users— Criar adminPUT /api/v1/users— Atualizar adminDELETE /api/v1/users— Deletar adminGET /api/v1/my-user— Dados do admin autenticadoPUT /api/v1/my-user— Atualizar dados do admin autenticadoGET /api/v1/customers— Listar customersPUT /api/v1/customers— Atualizar customer (admin)DELETE /api/v1/customers— Deletar customer com cascade (admin)POST /api/v1/admin/customers/{id}/verify-email— Verificar email de customer (admin)POST /api/v1/admin/customers/{id}/toggle-active— Ativar/desativar customer (admin)
Videos
GET /api/v1/videos— Listar videosPOST /api/v1/videos— Criar videoPUT /api/v1/videos— Atualizar videoDELETE /api/v1/videos— Deletar videoGET /api/v1/videos/{video_id}/stream-url— URL de streaming
Planos
GET /api/v1/plans— Listar planos ativos (publica)GET /api/v1/plans/admin— Listar todos os planosPOST /api/v1/plans— Criar planoPUT /api/v1/plans— Atualizar planoDELETE /api/v1/plans— Deletar planoPOST /api/v1/plans/{plan_id}/inactivate— Inativar planoPOST /api/v1/plans/{plan_id}/activate— Ativar planoPOST /api/v1/plans/{plan_id}/sync-stripe— Sincronizar plano com Stripe
Subscriptions (Genericas)
GET /api/v1/subscriptions— Dashboard de assinaturasGET /api/v1/subscriptions/stats— Estatisticas de assinaturasGET /api/v1/subscriptions/{id}/payments— Pagamentos de assinaturaPOST /api/v1/subscriptions/{id}/cancel— Cancelar assinaturaPUT /api/v1/subscriptions— Atualizar assinaturasPOST /api/v1/subscriptions/{id}/refund— Solicitar reembolsoGET /api/v1/subscriptions/{id}/refunds— Historico de reembolsosPOST /api/v1/subscriptions/{id}/chargeback— Gerenciar chargebackPOST /api/v1/admin/subscriptions/{id}/extend— Estender assinaturaPOST /api/v1/admin/subscriptions/{id}/activate— Ativar assinatura
Admin Stripe
GET /api/v1/admin/stripe/subscriptions— Listar assinaturas StripeGET /api/v1/admin/stripe/subscriptions/stats— Estatisticas StripePOST /api/v1/admin/stripe/subscriptions/{id}/cancel— Cancelar assinatura StripeGET /api/v1/admin/stripe/subscriptions/{id}/payments— Pagamentos StripePOST /api/v1/admin/stripe/subscriptions/{id}/refund— Reembolso StripeGET /api/v1/admin/stripe/subscriptions/{id}/refunds— Historico de reembolsos Stripe
Admin Asaas
GET /api/v1/admin/asaas/subscriptions— Listar assinaturas AsaasGET /api/v1/admin/asaas/subscriptions/stats— Estatisticas AsaasPOST /api/v1/admin/asaas/subscriptions/{id}/cancel— Cancelar assinatura AsaasGET /api/v1/admin/asaas/subscriptions/{id}/payments— Pagamentos AsaasPOST /api/v1/admin/asaas/subscriptions/{id}/refund— Reembolso AsaasGET /api/v1/admin/asaas/subscriptions/{id}/refunds— Historico de reembolsos Asaas
Codigos Promocionais (Admin)
POST /api/v1/admin/promo-codes— Criar codigo promoGET /api/v1/admin/promo-codes— Listar codigos promoGET /api/v1/admin/promo-codes/stats— Estatisticas de codigos promoGET /api/v1/admin/promo-codes/{id}— Detalhe de codigo promoPUT /api/v1/admin/promo-codes/{id}— Atualizar codigo promoDELETE /api/v1/admin/promo-codes/{id}— Remover codigo promoPOST /api/v1/admin/promo-codes/{id}/image— Upload de imagem de codigo promoDELETE /api/v1/admin/promo-codes/{id}/image— Remover imagem de codigo promo
Conteudo e Organizacao
GET /api/v1/categories— Listar categoriasPOST /api/v1/categories— Criar categoriaPUT /api/v1/categories— Atualizar categoriaDELETE /api/v1/categories— Deletar categoriaGET /api/v1/tags— Listar tagsPOST /api/v1/tags— Criar tagPUT /api/v1/tags— Atualizar tagDELETE /api/v1/tags— Deletar tagGET /api/v1/groups— Listar gruposPOST /api/v1/groups— Criar grupoPUT /api/v1/groups— Atualizar grupoDELETE /api/v1/groups— Deletar grupoGET /api/v1/flows— Listar flowsPOST /api/v1/flows— Criar flowPUT /api/v1/flows— Atualizar flowDELETE /api/v1/flows— Deletar flowGET /api/v1/seasons— Listar temporadasPOST /api/v1/seasons— Criar temporadaPUT /api/v1/seasons— Atualizar temporadaDELETE /api/v1/seasons— Remover temporadaGET /api/v1/status— Listar statusPOST /api/v1/status— Criar statusPUT /api/v1/status— Atualizar statusDELETE /api/v1/status— Deletar status
Eventos e Ingressos
GET /api/v1/events— Listar eventosPOST /api/v1/events— Criar eventoPUT /api/v1/events— Atualizar eventoDELETE /api/v1/events— Remover eventoGET /api/v1/tickets— Listar ingressosPOST /api/v1/tickets— Criar ingressoPUT /api/v1/tickets— Atualizar ingressoDELETE /api/v1/tickets— Remover ingressoPUT /api/v1/tickets/{ticket_id}/consume— Consumir ingressoPOST /api/v1/tickets/validate-qr— Validar QR code de ingressoPOST /api/v1/tickets/consume-qr— Consumir ingresso via QR code
Ticket Store (Compra Avulsa)
GET /api/v1/store/events— Listar eventos disponiveis na lojaGET /api/v1/store/events/{event_id}— Detalhe de evento na lojaPOST /api/v1/store/purchase/asaas/card— Comprar ingresso via Asaas cartaoPOST /api/v1/store/purchase/asaas/pix— Comprar ingresso via Asaas PIXPOST /api/v1/store/purchase/stripe/card— Comprar ingresso via Stripe cartaoPOST /api/v1/store/purchase/stripe/pix— Comprar ingresso via Stripe PIXGET /api/v1/me/ticket-orders— Meus pedidos de ingressosGET /api/v1/me/ticket-orders/{order_id}— Detalhe de pedidoGET /api/v1/me/tickets/{ticket_id}/qr— QR code do ingresso
Events Dashboard (Admin)
GET /api/v1/admin/events-dashboard/overview— Visao geral de eventosGET /api/v1/admin/events-dashboard/events— Listagem de eventos (dashboard)GET /api/v1/admin/events-dashboard/promo-codes— Codigos promo por eventoGET /api/v1/admin/events-dashboard/orders— Pedidos de ingressosGET /api/v1/admin/events-dashboard/events/export— Exportar eventos (?format=xlsx|csv|json, defaultxlsx— ADR-059)
Finance Dashboard (Admin)
GET /api/v1/admin/finance/overview— Visao geral financeiraGET /api/v1/admin/finance/revenue— Receita detalhadaGET /api/v1/admin/finance/overdue— InadimplenciaGET /api/v1/admin/finance/churn— Churn de assinantesGET /api/v1/admin/finance/export— Exportar dados financeiros (?format=xlsx|csv|json, defaultxlsx— ADR-059)
Webhooks e Logs
GET /api/v1/webhook-logs— Logs de webhooksGET /api/v1/webhook-logs/stats— Estatisticas de webhooksPOST /webhooks/stripe— Webhook Stripe (autenticado via Stripe-Signature)POST /webhooks/asaas— Webhook Asaas (autenticado via token)
Configuracao da Plataforma
GET /api/v1/config/payment-gateway— Gateway de pagamento padraoPUT /api/v1/admin/config/payment-gateway— Definir gateway de pagamento padraoGET /api/v1/config/pix-billing-mode— Modo de cobranca PIXPUT /api/v1/admin/config/pix-billing-mode— Definir modo de cobranca PIX
Search
GET /api/v1/search/{collection_name}— Busca generica por collection
Contact
POST /api/v1/contact— Enviar formulario de contato
Tipos e Registros
GET /api/v1/users-type— Listar tipos de usuarioPOST /api/v1/users-type— Criar tipo de usuarioPUT /api/v1/users-type— Atualizar tipo de usuarioDELETE /api/v1/users-type— Deletar tipo de usuarioGET /api/v1/types-of-registers— Listar tipos de registrosPOST /api/v1/types-of-registers— Criar tipo de registroPUT /api/v1/types-of-registers— Atualizar tipo de registroDELETE /api/v1/types-of-registers— Deletar tipo de registro
Archive Records (Arquivos)
GET /api/v1/archive-records— Listar arquivosPOST /api/v1/archive-records— Criar registro de arquivoPOST /api/v1/archive-records-new-version— Nova versao de arquivoPUT /api/v1/archive-records— Atualizar arquivoDELETE /api/v1/archive-records— Deletar arquivoPOST /api/v1/upload-file/archive-records/{id}— Upload de arquivoPUT /api/v1/upload-file/archive-records/{id}/{file_id}— Atualizar uploadDELETE /api/v1/upload-file/archive-records/{id}/{file_id}— Deletar uploadGET /api/v1/archive-records/{file_id}— Download de arquivo (auth)GET /api/v1/archive-records-public/{token}— Download de arquivo (publico via token)GET /api/v1/qrcode/{file_id}/{is_public}— Gerar QR code para arquivoGET /api/v1/qrcode/{text}— Gerar QR code de textoGET /api/v1/exemple— Exemplo
📦 Formatos de Resposta¶
Sucesso (200 OK) — Listagem com Paginação¶
{
"docs": [...],
"info": {},
"links": [
{"link_type": "GET", "rel": "self", "href": "..."},
{"link_type": "GET", "rel": "get document", "href": ".../{id}"},
{"link_type": "DELETE", "rel": "delete document", "href": ".../{id}"},
{"link_type": "POST", "rel": "insert document", "href": "..."},
{"link_type": "PUT", "rel": "update document", "href": ".../{id}"}
],
"msg": "ok",
"pagination": {
"current_page": 0,
"qty_docs_page": 10,
"qty_of_pages": 15,
"qty_total_docs": 150
}
}
Nota: Alguns endpoints (config, ações de perfil, cancelamento, etc.) retornam JSON simples sem o envelope HATEOAS (
docs,links,pagination).
Erro (4xx/5xx) — Formato Padronizado (ADR-025)¶
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Descrição legível do erro",
"details": [...],
"field": "campo",
"timestamp": "2026-01-24T12:00:00Z"
}
}
Códigos de erro disponíveis:
| Código | HTTP | Uso |
|---|---|---|
VALIDATION_ERROR |
400/422 | Dados inválidos |
UNAUTHORIZED |
401 | Token ausente/inválido |
INVALID_CREDENTIALS |
401 | Login falhou |
FORBIDDEN |
403 | Sem permissão |
NOT_FOUND |
404 | Recurso não existe |
CONFLICT |
409 | Conflito de estado |
DUPLICATE_KEY |
422 | Chave duplicada MongoDB |
REFUND_FAILED |
502 | Falha ao processar reembolso no gateway |
REFUND_NOT_ALLOWED |
422 | Status da subscription não permite reembolso |
CHARGEBACK_DETECTED |
200 | Chargeback processado automaticamente via webhook |
Ver ErrorPresenter para uso detalhado.
🔗 Links Úteis¶
- Swagger UI:
/docs(OpenAPI interativo) - ReDoc:
/redoc(Documentação alternativa)
📞 Suporte¶
- GitHub Issues: fdplay-api/issues