paytour

Crates.iopaytour
lib.rspaytour
version0.1.3
created_at2025-12-09 14:37:29.465985+00
updated_at2025-12-10 22:22:37.595738+00
descriptionCliente Rust para autenticação e consumo da API Paytour (login e passeios)
homepage
repositoryhttps://github.com/nextlw/cratesIO
max_upload_size
id1975583
size646,041
William (willy3087)

documentation

README

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

cargo add paytour --git https://github.com/nextlw/cratesIO --package paytour

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 paytour::{
    auth::{AuthStrategy, PaytourAuthenticator},
    client::{PaytourClient, PasseioQuery},
    config::EnvManager,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    dotenv::dotenv().ok();
    env_logger::init();

    let env = EnvManager::load()?;
    let authenticator = PaytourAuthenticator::new(&env);
    let token = authenticator.authenticate(env.auth_strategy()).await?;

    let client = PaytourClient::new(env.api_base_url.clone(), token.access_token);
    let passeios = client.list_passeios(&PasseioQuery::default()).await?;
    println!("Total de passeios: {}", passeios.itens.len());
    Ok(())
}

Exemplo: Listar todos os passeios com filtros

use paytour::client::{PaytourClient, PasseioQuery};

// Listar todos os passeios de uma página específica
let query = PasseioQuery::default()
    .pagina(1)
    .quantidade(50)
    .busca("buggy")
    .destino_id("123")
    .intervalo_datas("2025-01-01", "2025-01-31")
    .minimal_response(false);

let response = client.list_passeios(&query).await?;

// Percorrer todas as páginas automaticamente
let todos_passeios = client.list_all_passeios(&query).await?;
println!("Total acumulado: {}", todos_passeios.len());

Exemplo: Detalhar um passeio específico

use paytour::client::PaytourClient;

// Buscar detalhes com disponibilidade estendida (até 12 meses)
let detalhe = client
    .get_passeio_detail(2527834, Some(12))
    .await?;

println!("Detalhes: {}", serde_json::to_string_pretty(&detalhe)?);

Exemplo: Consultar disponibilidade de passeios

use paytour::client::PaytourClient;

// Obter dias disponíveis para um passeio em um mês/ano específico
let dias = client.get_dias_disponiveis(42, 9, 2025).await?;
println!("Dias disponíveis em setembro/2025: {:?}", dias);
// 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(42, "2025-09-05").await?;
println!("Horários: {}", serde_json::to_string_pretty(&horarios)?);

// Obter faixas etárias disponíveis para um dia específico
let faixas = client.get_faixas_etarias(42, "2025-09-05").await?;
println!("Faixas etárias: {}", serde_json::to_string_pretty(&faixas)?);

Exemplo: Listar combos

use paytour::client::{PaytourClient, ComboQuery};

let query = ComboQuery::default()
    .pagina(1)
    .quantidade(20)
    .busca("trem")
    .intervalo_datas("2025-01-01", "2025-01-31");

let combos = client.list_combos(&query).await?;
println!("Combos encontrados: {}", combos.itens.len());

Exemplo: Trabalhar com atividades

use paytour::client::{PaytourClient, AtividadeQuery};

// Listar atividades por intervalo de datas
let query = AtividadeQuery::default()
    .intervalo_datas("2025-11-18", "2025-11-18");

let atividades = client.list_atividades(&query).await?;
for atividade in atividades.itens {
    println!(
        "Voucher: {} | Cliente: {} | Utilizado: {}",
        atividade.voucher.as_deref().unwrap_or("-"),
        atividade.atividade_cliente_nome.as_deref().unwrap_or("-"),
        if atividade.utilizado.unwrap_or(false) { "✓" } else { "✗" }
    );
}

// Buscar atividades de um pedido específico
let query_pedido = AtividadeQuery::default()
    .pedido_id("3820377");

let atividades_pedido = client.list_atividades(&query_pedido).await?;

// Detalhar uma atividade pelo voucher
let detalhe = client
    .get_atividade_detail("123373820377769161341")
    .await?;

// Registrar check-in
let check_in = client
    .check_in_atividade("123373820377769161341", Some("MyApp".to_string()))
    .await?;

Exemplo: Trabalhar com cupons

use paytour::client::{PaytourClient, CupomQuery};
use serde_json::json;

// Listar todos os cupons
let query = CupomQuery::new()
    .page(1)
    .per_page(20);

let cupons = client.list_cupons(&query).await?;
println!("Cupons encontrados: {}", cupons.itens.len());

// Buscar um cupom específico pelo código
let query_cupom = CupomQuery::new()
    .cupom("CARNAVAL10")
    .page(1)
    .per_page(1);

let resultado = client.list_cupons(&query_cupom).await?;

// Criar um novo cupom
let novo_cupom = json!({
    "codigo": "TESTE10",
    "tipo": "percentual",
    "valor": 10.0,
    "valido_de": "2025-01-01",
    "valido_ate": "2025-12-31"
});

let cupom_criado = client.create_cupom(&novo_cupom).await?;

// Atualizar um cupom existente
let atualizacao = json!({
    "valor": 15.0
});

let cupom_atualizado = client.update_cupom(42, &atualizacao).await?;

// Apagar um cupom
client.delete_cupom(42).await?;

// Validar um cupom e obter o desconto
let validacao = json!({
    "cupom": "CARNAVAL10",
    "itens": [
        {
            "passeio_id": 2527834,
            "quantidade": 2,
            "preco": 100.0
        }
    ]
});

let resultado_validacao = client.validate_cupom(&validacao).await?;

// Extrair valores de desconto
let desconto_com = resultado_validacao
    .get("_desconto_sobre_total_com_desconto_por_metodo_de_pagamento")
    .and_then(|v| v.as_f64());
let desconto_sem = resultado_validacao
    .get("_desconto_sobre_total_sem_desconto_por_metodo_de_pagamento")
    .and_then(|v| v.as_f64());

println!("Desconto (com método): R${:.2}", desconto_com.unwrap_or(0.0));
println!("Desconto (sem método): R${:.2}", desconto_sem.unwrap_or(0.0));

Exemplo: Trabalhar com destinos

use paytour::client::{DestinoQuery, PaytourClient};

// Nota: Destinos não requerem autenticação
let client = PaytourClient::new(api_base_url, String::new());

// Listar todos os destinos
let query = DestinoQuery::new().page(1);
let destinos = client.list_destinos(&query).await?;

// Buscar destinos por nome/cidade/estado
let query_busca = DestinoQuery::new()
    .page(1)
    .busca("Natal");

let destinos_busca = client.list_destinos(&query_busca).await?;

// Buscar destinos por localização (latitude/longitude)
let query_local = DestinoQuery::new()
    .page(1)
    .localizacao("-5.79448", "-35.211")
    .range(100); // 100 metros de raio

let destinos_local = client.list_destinos(&query_local).await?;

// Detalhar um destino específico
let detalhe = client.get_destino_detail(42).await?;

Exemplo: Trabalhar com carrinhos

use paytour::client::{CarrinhoQuery, PaytourClient};

// Listar carrinhos da loja
let query = CarrinhoQuery::new()
    .page(1)
    .per_page(20);

let carrinhos = client.list_carrinhos(&query).await?;

// Detalhar um carrinho específico
let detalhe = client.get_carrinho_detail(42).await?;

// Criar um novo carrinho (form-data)
let form_data = vec![
    ("passeio_id", "2527834"),
    ("quantidade", "2"),
    ("data", "2025-01-15"),
    ("faixa_etaria_id", "1"),
    ("valido_ate", "2025-01-15 23:59:59"),
];

let carrinho = client.create_carrinho(&form_data).await?;

// Apagar um carrinho
client.delete_carrinho(42).await?;

Exemplo: Trabalhar com pedidos

use paytour::client::{PedidoQuery, PaytourClient};

// Listar pedidos da loja com filtros
let query = PedidoQuery::new()
    .page(1)
    .per_page(30)
    .include_items(true)
    .include_logs_status(true)
    .include_obs(true)
    .created_at_min("2022-03-28 00:00:00")
    .created_at_max("2022-04-01 23:59:59");

let pedidos = client.list_pedidos(&query).await?;

// Detalhar um pedido específico
let detalhe = client.get_pedido_detail(42).await?;

// Criar um novo pedido (form-data)
let form_data = vec![
    ("cliente_nome", "João Silva"),
    ("cliente_email", "joao@example.com"),
    ("cliente_telefone", "84999999999"),
    ("cliente_cpf", "12345678900"),
    ("metodo_pagamento", "PAYMENT_LINK"),
    // ... outros campos do pedido
];

let pedido = client.create_pedido(&form_data).await?;

// Atualizar o status de um pedido (ex: aprovar)
let pedido_atualizado = client.update_pedido_status(5496, "aprovado").await?;

Exemplo: Trabalhar com ícones

use paytour::client::PaytourClient;

// Listar todos os ícones disponíveis
let icones = client.list_icones().await?;

for icone in icones.itens {
    println!("Ícone: {} | URL: {}",
        icone.nome.unwrap_or_default(),
        icone.url.unwrap_or_default()
    );
}

Exemplo: Trabalhar com fotos de passeios

use paytour::client::{FotosService, FotoUpdateRequest};

// Criar serviço de fotos
let fotos_service = FotosService::new(api_base_url, token);

// Listar fotos de um passeio
let fotos = fotos_service.list_fotos(42).await?;
for foto in fotos.itens {
    println!("Foto ID: {:?} | URL: {}",
        foto.id,
        foto.url.unwrap_or_default()
    );
}

// Criar uma nova foto
let request = serde_json::json!({
    "url": "https://example.com/foto.jpg"
});
let nova_foto = fotos_service.create_foto(42, &request).await?;

// Editar uma foto
let update_request = FotoUpdateRequest::new()
    .posicao(1)
    .visivel_site(true)
    .capa(false);
let foto_atualizada = fotos_service.update_foto(42, 123, &update_request).await?;

// Reordenar fotos
let foto_ids = vec![3, 1, 2, 4];
let fotos_reordenadas = fotos_service.reordenar_fotos(42, &foto_ids).await?;

// Apagar uma foto
fotos_service.delete_foto(42, 123).await?;

CLI

Autenticação

# Login usando credenciais do .env
cd paytour
cargo run --bin paytour-cli -- login

# Refresh token (renovar token expirado)
cargo run --bin paytour-cli -- refresh

Passeios

# Listar passeios (página 1, 10 itens)
cargo run --bin paytour-cli -- passeios --pagina 1 --quantidade 10

# Listar todos os passeios de todas as páginas
cargo run --bin paytour-cli -- passeios --todas

# Buscar passeios com filtros
cargo run --bin paytour-cli -- passeios \
  --pagina 1 \
  --quantidade 50 \
  --busca "buggy" \
  --destino-id "123" \
  --data-de "2025-01-01" \
  --data-ate "2025-01-31" \
  --minimal-response

# Exibir resposta completa em JSON
cargo run --bin paytour-cli -- passeios --pagina 1 --verbose

# Detalhar um passeio específico
cargo run --bin paytour-cli -- passeio-detalhe \
  --id 2527834 \
  --disponibilidade-ate 12 \
  --verbose

# Obter dias disponíveis para um passeio em um mês/ano
cargo run --bin paytour-cli -- passeio-dias \
  --id 42 \
  --mes 9 \
  --ano 2025 \
  --verbose

# Obter horários disponíveis para um dia específico
cargo run --bin paytour-cli -- passeio-horarios \
  --id 42 \
  --dia "2025-09-05" \
  --verbose

# Obter faixas etárias disponíveis para um dia específico
cargo run --bin paytour-cli -- passeio-faixas-etarias \
  --id 42 \
  --dia "2025-09-05" \
  --verbose

Combos

# Listar combos
cargo run --bin paytour-cli -- combos \
  --pagina 1 \
  --quantidade 50 \
  --busca "trem" \
  --data-de "2025-01-01" \
  --data-ate "2025-01-31" \
  --verbose

Atividades

# Listar atividades por intervalo de datas
cargo run --bin paytour-cli -- atividades \
  --data-de "2025-11-18" \
  --data-ate "2025-11-18" \
  --verbose

# Listar atividades de um pedido específico
cargo run --bin paytour-cli -- atividades \
  --pedido-id "3820377" \
  --verbose

# Detalhar uma atividade pelo voucher
cargo run --bin paytour-cli -- atividade-detalhe \
  --voucher "123373820377769161341" \
  --verbose

# Registrar check-in de uma atividade
cargo run --bin paytour-cli -- atividade-checkin \
  --voucher "123373820377769161341" \
  --nome-app "MyApp"

Cupons

# Listar todos os cupons
cargo run --bin paytour-cli -- cupons \
  --page 1 \
  --per-page 20 \
  --verbose

# Buscar um cupom específico pelo código
cargo run --bin paytour-cli -- cupons \
  --cupom "CARNAVAL10" \
  --page 1 \
  --per-page 1 \
  --verbose

# Criar um novo cupom
cargo run --bin paytour-cli -- cupom-criar \
  --json '{"codigo":"TESTE10","tipo":"percentual","valor":10.0,"valido_de":"2025-01-01","valido_ate":"2025-12-31"}'

# Atualizar um cupom existente
cargo run --bin paytour-cli -- cupom-atualizar \
  --id 42 \
  --json '{"valor":15.0}'

# Apagar um cupom
cargo run --bin paytour-cli -- cupom-apagar --id 42

# Validar um cupom e obter o desconto
cargo run --bin paytour-cli -- cupom-validar \
  --json '{"cupom":"CARNAVAL10","itens":[{"passeio_id":2527834,"quantidade":2,"preco":100.0}]}' \
  --verbose

Destinos

# Listar todos os destinos (não requer autenticação)
cargo run --bin paytour-cli -- destinos \
  --page 1 \
  --verbose

# Buscar destinos por nome/cidade/estado
cargo run --bin paytour-cli -- destinos \
  --page 1 \
  --busca "Natal" \
  --verbose

# Buscar destinos por localização
cargo run --bin paytour-cli -- destinos \
  --page 1 \
  --latitude "-5.79448" \
  --longitude "-35.211" \
  --range 100 \
  --verbose

# Detalhar um destino específico
cargo run --bin paytour-cli -- destino-detalhe \
  --id 42 \
  --verbose

Carrinhos

# Listar carrinhos da loja
cargo run --bin paytour-cli -- carrinhos \
  --page 1 \
  --per-page 20 \
  --verbose

# Detalhar um carrinho específico
cargo run --bin paytour-cli -- carrinho-detalhe \
  --id 42 \
  --verbose

# Apagar um carrinho
cargo run --bin paytour-cli -- carrinho-apagar --id 42

# Criar um novo carrinho (form-data)
cargo run --bin paytour-cli -- carrinho-criar \
  --data "passeio_id=2527834,quantidade=2,data=2025-01-15,faixa_etaria_id=1,valido_ate=2025-01-15 23:59:59"

Pedidos

# Listar pedidos da loja
cargo run --bin paytour-cli -- pedidos \
  --page 1 \
  --per-page 30 \
  --include-items \
  --include-logs-status \
  --include-obs \
  --verbose

# Listar pedidos com filtros de data
cargo run --bin paytour-cli -- pedidos \
  --page 1 \
  --per-page 30 \
  --created-at-min "2022-03-28 00:00:00" \
  --created-at-max "2022-04-01 23:59:59" \
  --updated-at-min "2022-03-28 00:00:00" \
  --updated-at-max "2022-04-01 23:59:59" \
  --verbose

# Detalhar um pedido específico
cargo run --bin paytour-cli -- pedido-detalhe \
  --id 42 \
  --verbose

# Criar um novo pedido (form-data)
cargo run --bin paytour-cli -- pedido-criar \
  --data "cliente_nome=João Silva,cliente_email=joao@example.com,cliente_telefone=84999999999,cliente_cpf=12345678900,metodo_pagamento=PAYMENT_LINK"

# Atualizar o status de um pedido (ex: aprovar)
cargo run --bin paytour-cli -- pedido-atualizar-status \
  --id 5496 \
  --status "aprovado"

Ícones

# Listar todos os ícones disponíveis
cargo run --bin paytour-cli -- icones \
  --verbose

Fotos de Passeios

# Listar fotos de um passeio
cargo run --bin paytour-cli -- fotos-listar \
  --passeio-id 42 \
  --verbose

# Cadastrar uma nova foto
cargo run --bin paytour-cli -- foto-criar \
  --passeio-id 42 \
  --json '{"url":"https://example.com/foto.jpg"}'

# Editar uma foto (posição, visibilidade, capa)
cargo run --bin paytour-cli -- foto-editar \
  --passeio-id 42 \
  --foto-id 123 \
  --posicao 1 \
  --visivel-site true \
  --capa false

# Apagar uma foto
cargo run --bin paytour-cli -- foto-apagar \
  --passeio-id 42 \
  --foto-id 123

# Reordenar fotos
cargo run --bin paytour-cli -- fotos-reordenar \
  --passeio-id 42 \
  --ids "1,2,3,4"

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 com itens: Vec<Passeio>
  • Passeio — Modelo de passeio
  • PasseioDetail — Detalhes completos (tipo Value)
  • 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 com itens: Vec<ComboItem>
  • ComboItem — Modelo de combo

Atividades

  • AtividadeQuery — Builder para filtrar atividades
    • .intervalo_datas(String, String), .pedido_id(String)
  • AtividadeListResponse — Resposta com itens: Vec<Atividade>
  • Atividade — Modelo de atividade (voucher, cliente, data, utilizado, etc.)
  • AtividadeDetail — Detalhes completos (tipo Value)
  • CheckInResponse — Resposta do check-in

Cupons

  • CupomQuery — Builder para filtrar cupons
    • .cupom(String), .page(u32), .per_page(u32) (máximo 100)
  • CupomListResponse — Resposta com itens: Vec<Cupom>
  • Cupom — Modelo de cupom (id, codigo, descricao, tipo, valor)
  • CupomDetail — Detalhes completos (tipo Value)
  • CupomValidateResponse — Resposta da validação com campos de desconto (tipo Value)
  • CupomCreateRequest, CupomUpdateRequest, CupomValidateRequest — Payloads flexíveis (tipo Value)

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 com itens: Vec<Destino>
  • Destino — Modelo de destino (id, nome, cidade, estado, pais)
  • DestinoDetail — Detalhes completos (tipo Value)

Carrinhos

  • CarrinhoQuery — Builder para filtrar carrinhos
    • .page(u32), .per_page(u32) (máximo 100)
  • CarrinhoListResponse — Resposta com itens: Vec<Carrinho>
  • Carrinho — Modelo de carrinho (id, total)
  • CarrinhoDetail — Detalhes completos (tipo Value)

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 com itens: Vec<Pedido>
  • Pedido — Modelo de pedido (id, total, status)
  • PedidoDetail — Detalhes completos (tipo Value)

Ícones

  • IconeListResponse — Resposta com itens: Vec<Icone>
  • Icone — Modelo de ícone (id, nome, url, categoria)

Fotos de Passeios

  • FotosService — Serviço para gerenciar fotos de passeios
  • FotoListResponse — Resposta com itens: Vec<Foto>
  • Foto — Modelo de foto (id, url, posicao, visivel_site, capa)
  • FotoDetail — Detalhes completos (tipo Value)
  • FotoCreateRequest — Payload para criar foto (tipo Value)
  • FotoUpdateRequest — Builder para atualizar foto
    • .posicao(u32), .visivel_site(bool), .capa(bool)

Métodos do PaytourClient

// Passeios
client.list_passeios(&query) -> Result<PasseioListResponse>
client.list_all_passeios(&query) -> Result<Vec<Passeio>>
client.get_passeio_detail(id, disponibilidade_ate) -> Result<PasseioDetail>
client.get_dias_disponiveis(id, mes, ano) -> Result<Vec<String>>
client.get_horarios_disponiveis(id, dia) -> Result<HorariosResponse>
client.get_faixas_etarias(id, dia) -> Result<FaixasEtariasResponse>

// Combos
client.list_combos(&query) -> Result<ComboListResponse>

// Atividades
client.list_atividades(&query) -> Result<AtividadeListResponse>
client.get_atividade_detail(voucher_code) -> Result<AtividadeDetail>
client.check_in_atividade(voucher_code, nome_app) -> Result<CheckInResponse>

// Cupons
client.list_cupons(&query) -> Result<CupomListResponse>
client.create_cupom(&request) -> Result<CupomDetail>
client.update_cupom(id, &request) -> Result<CupomDetail>
client.delete_cupom(id) -> Result<()>
client.validate_cupom(&request) -> Result<CupomValidateResponse>

// Destinos (não requer autenticação)
client.list_destinos(&query) -> Result<DestinoListResponse>
client.get_destino_detail(id) -> Result<DestinoDetail>

// Carrinhos
client.list_carrinhos(&query) -> Result<CarrinhoListResponse>
client.get_carrinho_detail(id) -> Result<CarrinhoDetail>
client.delete_carrinho(id) -> Result<()>
client.create_carrinho(&form_data) -> Result<CarrinhoDetail>

// Pedidos
client.list_pedidos(&query) -> Result<PedidoListResponse>
client.get_pedido_detail(id) -> Result<PedidoDetail>
client.create_pedido(&form_data) -> Result<PedidoDetail>
client.update_pedido_status(id, status) -> Result<PedidoDetail>

// Ícones
client.list_icones() -> Result<IconeListResponse>

// Fotos de Passeios (via FotosService)
let fotos_service = FotosService::new(api_base_url, token);
fotos_service.list_fotos(passeio_id) -> Result<FotoListResponse>
fotos_service.create_foto(passeio_id, &request) -> Result<FotoDetail>
fotos_service.update_foto(passeio_id, foto_id, &request) -> Result<FotoDetail>
fotos_service.delete_foto(passeio_id, foto_id) -> Result<()>
fotos_service.reordenar_fotos(passeio_id, &foto_ids) -> Result<FotoListResponse>

Testes

# Executar todos os testes
cargo test

# Executar testes específicos
cargo test pedido_query_translates_params
cargo test query_builder_translates_params

Contribuindo

Contribuições são bem-vindas! Por favor:

  1. Faça fork do repositório
  2. Crie uma branch para sua feature (git checkout -b feature/nova-funcionalidade)
  3. Commit suas mudanças (git commit -am 'Adiciona nova funcionalidade')
  4. Push para a branch (git push origin feature/nova-funcionalidade)
  5. 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
Commit count: 0

cargo fmt