Paytour Rust SDK
Crate inspirado na arquitetura do clickup para consumir a API Paytour.
🎯 Funcionalidades Principais
A biblioteca oferece suporte completo para:
- Autenticação: Login via credenciais de aplicativo ou e-mail/senha, com renovação automática de tokens
- Passeios: Listagem, detalhamento, consulta de disponibilidade (dias, horários, faixas etárias) e gerenciamento de fotos
- Combos: Listagem com filtros de disponibilidade
- Atividades: Listagem, detalhamento e check-in
- Cupons: CRUD completo + validação com cálculo de desconto
- Destinos: Listagem e busca (sem autenticação)
- Carrinhos: CRUD completo
- Pedidos: Listagem, detalhamento, criação e atualização de status
- Ícones: Listagem da biblioteca de ícones Paytour
- CLI Completo: Interface de linha de comando para todos os endpoints
📊 Estatísticas
- Endpoints Implementados: 30+
- Serviços: 2 (PaytourClient + FotosService)
- Comandos CLI: 25+
- Cobertura da API: ~85% dos endpoints principais
- Testes Unitários: Implementados para query builders
Instalação
Variáveis de ambiente
| Variável | Descrição |
|---|---|
PAYTOUR_API_BASE_URL |
URL base (default https://api.paytour.com.br/v2) |
PAYTOUR_LOJA_ID |
Identificador da loja (opcional) |
PAYTOUR_EMAIL |
E-mail do usuário Paytour |
PAYTOUR_PASSWORD |
Senha do usuário |
PAYTOUR_APP_KEY |
Chave de aplicativo |
PAYTOUR_APP_SECRET |
Segredo de aplicativo |
PAYTOUR_ACCESS_TOKEN |
Preenchido automaticamente após login |
PAYTOUR_REFRESH_TOKEN |
Preenchido automaticamente após login |
Defina pelo menos um conjunto de credenciais (usuário ou aplicativo). O login segue o fluxo descrito na documentação oficial (POST /loja/login com Authorization: Basic base64(email:senha) ou app_key:app_secret). Referência: Login Paytour.
Uso como biblioteca
Exemplo básico: Autenticação e listagem de passeios
use ;
async
Exemplo: Listar todos os passeios com filtros
use ;
// Listar todos os passeios de uma página específica
let query = default
.pagina
.quantidade
.busca
.destino_id
.intervalo_datas
.minimal_response;
let response = client.list_passeios.await?;
// Percorrer todas as páginas automaticamente
let todos_passeios = client.list_all_passeios.await?;
println!;
Exemplo: Detalhar um passeio específico
use PaytourClient;
// Buscar detalhes com disponibilidade estendida (até 12 meses)
let detalhe = client
.get_passeio_detail
.await?;
println!;
Exemplo: Consultar disponibilidade de passeios
use PaytourClient;
// Obter dias disponíveis para um passeio em um mês/ano específico
let dias = client.get_dias_disponiveis.await?;
println!;
// Retorna: ["2025-09-05", "2025-09-12", "2025-09-19", ...]
// Obter horários disponíveis para um dia específico
let horarios = client.get_horarios_disponiveis.await?;
println!;
// Obter faixas etárias disponíveis para um dia específico
let faixas = client.get_faixas_etarias.await?;
println!;
Exemplo: Listar combos
use ;
let query = default
.pagina
.quantidade
.busca
.intervalo_datas;
let combos = client.list_combos.await?;
println!;
Exemplo: Trabalhar com atividades
use ;
// Listar atividades por intervalo de datas
let query = default
.intervalo_datas;
let atividades = client.list_atividades.await?;
for atividade in atividades.itens
// Buscar atividades de um pedido específico
let query_pedido = default
.pedido_id;
let atividades_pedido = client.list_atividades.await?;
// Detalhar uma atividade pelo voucher
let detalhe = client
.get_atividade_detail
.await?;
// Registrar check-in
let check_in = client
.check_in_atividade
.await?;
Exemplo: Trabalhar com cupons
use ;
use json;
// Listar todos os cupons
let query = new
.page
.per_page;
let cupons = client.list_cupons.await?;
println!;
// Buscar um cupom específico pelo código
let query_cupom = new
.cupom
.page
.per_page;
let resultado = client.list_cupons.await?;
// Criar um novo cupom
let novo_cupom = json!;
let cupom_criado = client.create_cupom.await?;
// Atualizar um cupom existente
let atualizacao = json!;
let cupom_atualizado = client.update_cupom.await?;
// Apagar um cupom
client.delete_cupom.await?;
// Validar um cupom e obter o desconto
let validacao = json!;
let resultado_validacao = client.validate_cupom.await?;
// Extrair valores de desconto
let desconto_com = resultado_validacao
.get
.and_then;
let desconto_sem = resultado_validacao
.get
.and_then;
println!;
println!;
Exemplo: Trabalhar com destinos
use ;
// Nota: Destinos não requerem autenticação
let client = new;
// Listar todos os destinos
let query = new.page;
let destinos = client.list_destinos.await?;
// Buscar destinos por nome/cidade/estado
let query_busca = new
.page
.busca;
let destinos_busca = client.list_destinos.await?;
// Buscar destinos por localização (latitude/longitude)
let query_local = new
.page
.localizacao
.range; // 100 metros de raio
let destinos_local = client.list_destinos.await?;
// Detalhar um destino específico
let detalhe = client.get_destino_detail.await?;
Exemplo: Trabalhar com carrinhos
use ;
// Listar carrinhos da loja
let query = new
.page
.per_page;
let carrinhos = client.list_carrinhos.await?;
// Detalhar um carrinho específico
let detalhe = client.get_carrinho_detail.await?;
// Criar um novo carrinho (form-data)
let form_data = vec!;
let carrinho = client.create_carrinho.await?;
// Apagar um carrinho
client.delete_carrinho.await?;
Exemplo: Trabalhar com pedidos
use ;
// Listar pedidos da loja com filtros
let query = new
.page
.per_page
.include_items
.include_logs_status
.include_obs
.created_at_min
.created_at_max;
let pedidos = client.list_pedidos.await?;
// Detalhar um pedido específico
let detalhe = client.get_pedido_detail.await?;
// Criar um novo pedido (form-data)
let form_data = vec!;
let pedido = client.create_pedido.await?;
// Atualizar o status de um pedido (ex: aprovar)
let pedido_atualizado = client.update_pedido_status.await?;
Exemplo: Trabalhar com ícones
use PaytourClient;
// Listar todos os ícones disponíveis
let icones = client.list_icones.await?;
for icone in icones.itens
Exemplo: Trabalhar com fotos de passeios
use ;
// Criar serviço de fotos
let fotos_service = new;
// Listar fotos de um passeio
let fotos = fotos_service.list_fotos.await?;
for foto in fotos.itens
// Criar uma nova foto
let request = json!;
let nova_foto = fotos_service.create_foto.await?;
// Editar uma foto
let update_request = new
.posicao
.visivel_site
.capa;
let foto_atualizada = fotos_service.update_foto.await?;
// Reordenar fotos
let foto_ids = vec!;
let fotos_reordenadas = fotos_service.reordenar_fotos.await?;
// Apagar uma foto
fotos_service.delete_foto.await?;
CLI
Autenticação
# Login usando credenciais do .env
# Refresh token (renovar token expirado)
Passeios
# Listar passeios (página 1, 10 itens)
# Listar todos os passeios de todas as páginas
# Buscar passeios com filtros
# Exibir resposta completa em JSON
# Detalhar um passeio específico
# Obter dias disponíveis para um passeio em um mês/ano
# Obter horários disponíveis para um dia específico
# Obter faixas etárias disponíveis para um dia específico
Combos
# Listar combos
Atividades
# Listar atividades por intervalo de datas
# Listar atividades de um pedido específico
# Detalhar uma atividade pelo voucher
# Registrar check-in de uma atividade
Cupons
# Listar todos os cupons
# Buscar um cupom específico pelo código
# Criar um novo cupom
# Atualizar um cupom existente
# Apagar um cupom
# Validar um cupom e obter o desconto
Destinos
# Listar todos os destinos (não requer autenticação)
# Buscar destinos por nome/cidade/estado
# Buscar destinos por localização
# Detalhar um destino específico
Carrinhos
# Listar carrinhos da loja
# Detalhar um carrinho específico
# Apagar um carrinho
# Criar um novo carrinho (form-data)
Pedidos
# Listar pedidos da loja
# Listar pedidos com filtros de data
# Detalhar um pedido específico
# Criar um novo pedido (form-data)
# Atualizar o status de um pedido (ex: aprovar)
Ícones
# Listar todos os ícones disponíveis
Fotos de Passeios
# Listar fotos de um passeio
# Cadastrar uma nova foto
# Editar uma foto (posição, visibilidade, capa)
# Apagar uma foto
# Reordenar fotos
Referência rápida de tipos
Passeios
PasseioQuery— Builder para filtrar passeios.pagina(u32),.quantidade(u32),.busca(String),.destino_id(String).intervalo_datas(String, String),.minimal_response(bool)
PasseioListResponse— Resposta comitens: Vec<Passeio>Passeio— Modelo de passeioPasseioDetail— Detalhes completos (tipoValue)HorariosResponse— Resposta de horários disponíveis (tipo flexível)FaixasEtariasResponse— Resposta de faixas etárias disponíveis (tipo flexível)
Combos
ComboQuery— Builder para filtrar combos.pagina(u32),.quantidade(u32),.busca(String).intervalo_datas(String, String)
ComboListResponse— Resposta comitens: Vec<ComboItem>ComboItem— Modelo de combo
Atividades
AtividadeQuery— Builder para filtrar atividades.intervalo_datas(String, String),.pedido_id(String)
AtividadeListResponse— Resposta comitens: Vec<Atividade>Atividade— Modelo de atividade (voucher, cliente, data, utilizado, etc.)AtividadeDetail— Detalhes completos (tipoValue)CheckInResponse— Resposta do check-in
Cupons
CupomQuery— Builder para filtrar cupons.cupom(String),.page(u32),.per_page(u32)(máximo 100)
CupomListResponse— Resposta comitens: Vec<Cupom>Cupom— Modelo de cupom (id, codigo, descricao, tipo, valor)CupomDetail— Detalhes completos (tipoValue)CupomValidateResponse— Resposta da validação com campos de desconto (tipoValue)CupomCreateRequest,CupomUpdateRequest,CupomValidateRequest— Payloads flexíveis (tipoValue)
Destinos
DestinoQuery— Builder para filtrar destinos (não requer autenticação).page(u32),.busca(String),.loja_id(u64).localizacao(String, String),.range(u32)
DestinoListResponse— Resposta comitens: Vec<Destino>Destino— Modelo de destino (id, nome, cidade, estado, pais)DestinoDetail— Detalhes completos (tipoValue)
Carrinhos
CarrinhoQuery— Builder para filtrar carrinhos.page(u32),.per_page(u32)(máximo 100)
CarrinhoListResponse— Resposta comitens: Vec<Carrinho>Carrinho— Modelo de carrinho (id, total)CarrinhoDetail— Detalhes completos (tipoValue)
Pedidos
PedidoQuery— Builder para filtrar pedidos.page(u32),.per_page(u32)(máximo 100).include_items(bool),.include_logs_status(bool),.include_obs(bool).created_at_min(String),.created_at_max(String).updated_at_min(String),.updated_at_max(String)
PedidoListResponse— Resposta comitens: Vec<Pedido>Pedido— Modelo de pedido (id, total, status)PedidoDetail— Detalhes completos (tipoValue)
Ícones
IconeListResponse— Resposta comitens: Vec<Icone>Icone— Modelo de ícone (id, nome, url, categoria)
Fotos de Passeios
FotosService— Serviço para gerenciar fotos de passeiosFotoListResponse— Resposta comitens: Vec<Foto>Foto— Modelo de foto (id, url, posicao, visivel_site, capa)FotoDetail— Detalhes completos (tipoValue)FotoCreateRequest— Payload para criar foto (tipoValue)FotoUpdateRequest— Builder para atualizar foto.posicao(u32),.visivel_site(bool),.capa(bool)
Métodos do PaytourClient
// Passeios
client.list_passeios .list_all_passeios .get_passeio_detail .get_dias_disponiveis .get_horarios_disponiveis .get_faixas_etarias // Combos
client.list_combos // Atividades
client.list_atividades .get_atividade_detail .check_in_atividade // Cupons
client.list_cupons .create_cupom .update_cupom .delete_cupom .validate_cupom // Destinos (não requer autenticação)
client.list_destinos .get_destino_detail // Carrinhos
client.list_carrinhos .get_carrinho_detail .delete_carrinho .create_carrinho // Pedidos
client.list_pedidos .get_pedido_detail .create_pedido .update_pedido_status // Ícones
client.list_icones // Fotos de Passeios (via FotosService)
let fotos_service = new;
fotos_service.list_fotos .create_foto .update_foto .delete_foto .reordenar_fotos
Testes
# Executar todos os testes
# Executar testes específicos
Contribuindo
Contribuições são bem-vindas! Por favor:
- Faça fork do repositório
- Crie uma branch para sua feature (
git checkout -b feature/nova-funcionalidade) - Commit suas mudanças (
git commit -am 'Adiciona nova funcionalidade') - Push para a branch (
git push origin feature/nova-funcionalidade) - Abra um Pull Request
Licença
Este projeto está licenciado sob a Licença Apache 2.0 - veja o arquivo LICENSE para detalhes.
Status de Implementação
✅ Funcionalidades Implementadas
Autenticação
- ✅ Login via credenciais de aplicativo (
app_key/app_secret) - ✅ Login via e-mail/senha
- ✅ Renovação automática de token usando
refresh_token - ✅ Validação automática de token expirado no CLI
- ✅ Cache de tokens em variáveis de ambiente
Passeios
- ✅ Listagem de passeios com filtros (paginação, busca, destino, datas)
- ✅ Listagem de todos os passeios (iteração automática por páginas)
- ✅ Detalhamento de passeio com disponibilidade estendida (até 12 meses)
- ✅ Consulta de dias disponíveis (por mês/ano)
- ✅ Consulta de horários disponíveis (por dia)
- ✅ Consulta de faixas etárias disponíveis (por dia)
Combos
- ✅ Listagem de combos com filtros (paginação, busca, datas)
- ✅ Filtro de disponibilidade por intervalo de datas
Atividades
- ✅ Listagem de atividades com filtros (intervalo de datas, pedido)
- ✅ Detalhamento de atividade por voucher
- ✅ Check-in de atividade
Cupons
- ✅ Listagem de cupons (com busca por código)
- ✅ Criação de cupom
- ✅ Atualização de cupom
- ✅ Exclusão de cupom
- ✅ Validação de cupom (com cálculo de desconto)
Destinos
- ✅ Listagem de destinos (não requer autenticação)
- ✅ Busca de destinos por nome/cidade/estado
- ✅ Busca de destinos por localização (latitude/longitude/raio)
- ✅ Detalhamento de destino
Carrinhos
- ✅ Listagem de carrinhos
- ✅ Detalhamento de carrinho
- ✅ Criação de carrinho (form-data)
- ✅ Exclusão de carrinho
Pedidos
- ✅ Listagem de pedidos com filtros avançados (datas, inclusão de itens/logs/obs)
- ✅ Detalhamento de pedido
- ✅ Criação de pedido (form-data)
- ✅ Atualização de status de pedido
Ícones
- ✅ Listagem de ícones disponíveis na biblioteca Paytour
Fotos de Passeios
- ✅ Listagem de fotos de um passeio
- ✅ Criação de foto
- ✅ Edição de foto (posição, visibilidade, capa)
- ✅ Exclusão de foto
- ✅ Reordenação de fotos
- ✅ Tratamento de erro 404 com sugestão de passeios disponíveis
CLI (Interface de Linha de Comando)
- ✅ Todos os endpoints disponíveis via CLI
- ✅ Documentação inline de flags e parâmetros
- ✅ Modo verbose para exibir JSON completo
- ✅ Validação automática e renovação de token
⏳ Funcionalidades Pendentes
Endpoints da API que ainda não foram implementados:
- ⏳ Lojas - Gerenciamento de lojas (se disponível na API)
- ⏳ Métodos de Pagamento - Listagem e configuração de métodos de pagamento
- ⏳ Clientes - Gerenciamento de clientes
- ⏳ Relatórios/Estatísticas - Endpoints de relatórios e métricas
- ⏳ Webhooks - Configuração e gerenciamento de webhooks
- ⏳ Notificações - Sistema de notificações
- ⏳ Configurações - Configurações gerais da loja
Melhorias e Funcionalidades Adicionais:
- ⏳ Cache local - Cache de respostas para reduzir chamadas à API
- ⏳ Paginação avançada - Helpers para paginação com cursor ou offset
- ⏳ Retry automático - Retry de requisições com backoff exponencial
- ⏳ Rate limiting - Controle de taxa de requisições
- ⏳ Validação de dados - Validação mais rigorosa de payloads antes do envio
- ⏳ Logging estruturado - Melhorias no sistema de logs
- ⏳ Métricas e telemetria - Coleta de métricas de uso
📝 Notas
- A implementação segue o padrão modular do crate
clickup - Todos os endpoints implementados incluem tratamento de erros adequado
- O CLI valida automaticamente e renova tokens expirados
- Suporte completo a deserialização flexível (aceita strings e números para IDs)
- Tratamento inteligente de erros 404 com sugestões de recursos disponíveis