👉 Acesse o dashboard

Introdução

Recentemente, foi implementado um teste A/B no site para verificar o impacto de uma alteração no fluxo de pagamento da fatura do cartão de crédito via PIX e boleto. Este documento avalia os resultados obtidos e discute pontos que foram observados durante a análise.

Pacotes necessários

  • library(readxl) - para leitura e tratamento dos dados do arquivo Excel
  • library(janitor) - para alteração nos nomes das páginas “Resultados do teste” e “Pagamentos efetivados”
  • library(scales) - para alterar o valor da transação em formato de moeda
  • library(dplyr) - para trabalhar com filtros, combinações entre tabelas, etc.
  • library(ggplot2) - para criação de gráficos
  • library(plotly) - para criação de gráficos interativos
  • library(DT) - para criação de tabelas interativas

Tratamento e Modelagem de Dados

Código utilizado para alterar a forma de pagamento de número para nome

resultados$forma_pgto <- dplyr::recode(resultados$forma_pgto,
                                       `1` = "Boleto",
                                       `2` = "PIX")

Código utilizado para ajustar o campo valor para moeda

resultados$valor_formatado <- paste0(
  "R$ ", format(resultados$valor, big.mark = ".", decimal.mark = ",", nsmall = 2))
resultados$valor <- round(resultados$valor, 2)

Código utilizado para combinar os campos user_id e id_transacao em uma só célula

resultados <- resultados %>%
  mutate(chave = paste(user_id, id_transacao, sep = "-"))

pagamento <- pagamento %>%
  mutate(chave = paste(user_id, id_transacao, sep = "-"))

resultados <- resultados %>%
  mutate(efetivado = chave %in% pagamento$chave)

Usuários por versão do teste

Código desenvolvido para identificar o número de usuários das versões Controle e Variante.

usuarios_por_versao <- resultados %>%
  group_by(grupo) %>%
  summarise(num_usuarios = n())

ggplot(usuarios_por_versao, aes(x = grupo, y = num_usuarios, fill = grupo)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = num_usuarios), vjust = -0.3, color = "black") +
  labs(title = "Número de Usuários por Grupo", x = "Grupo", y = "Número de Usuários") +
  theme_minimal() +
  scale_fill_brewer(palette = "Set3")

Análise de duplicidade de usuários por versão do teste

Código desenvolvido para identificar o mesmo ID de usuário das versões Controle e Variante acessou ambas as versões.

## # A tibble: 0 × 2
## # ℹ 2 variables: user_id <dbl>, n_grupos <int>

Promessa de Pagamento

A promessa de pagamento é uma etapa da jornada que antecede ou não uma transação. O valor 0 foi removido da coluna “promessa_pgto” para calcular a taxa de cancelamento por versão do teste.

Códigos utilizados para aplicação do filtro e desenvolvimento do gráfico de Taxa de Cancelamento

promessa_pagamento_zeros <- resultados %>%
filter(promessa_pgto == 0)

ggplot(promessa_pagamento_zeros, aes(x = grupo, fill = grupo)) +
  geom_bar(stat = "count", color = "black", width = 0.5, position = "dodge") +
  scale_fill_brewer(palette = "Set3") +
  geom_text(stat = "count", aes(label = ..count.., y = ..count../2),
            color = "black", size = 5, position = position_dodge(0.5)) +
  labs(
    title = "Usuários que não avançaram para a etapa Promessa de Pagamento",
    x = "Grupo (Controle vs Variante)",
    y = "Número de Usuários (Valor de Promessa = 0)",
    fill = "Grupo"
  ) +
  theme_minimal()

Taxa de Cancelamento por Versão do Teste

Cálculo utilizado: usuarios que não prosseguiram para a etapa promessa de pagamento por versão / total de usuarios por versão

A versão Controle que recebeu mais usuários durante o teste (636), teve um número menor de clientes que não realizaram ao menos a promessa de pagamento.

taxa_cancelamento <- resultados %>%
  group_by(grupo) %>%
  summarise(
    total_usuarios = n(),
    usuarios_nao_pgto = sum(promessa_pagamento_zeros$grupo == grupo),
    taxa_cancelamento = paste0(
      round((sum(promessa_pagamento_zeros$grupo == grupo) / n()) * 100, 2), "%"
    )
  ) %>%
  rename(
    `Total de Usuarios` = total_usuarios,
    `Usuarios que nao realizaram a promessa de pagamento` = usuarios_nao_pgto,
    `Taxa de Cancelamento por Grupo` = taxa_cancelamento
  )
datatable(taxa_cancelamento, caption = "Taxa de Cancelamento por Grupo")

Códigos utilizados para aplicação do filtro e desenvolvimento do gráfico de Taxa de Promessas de Pagamento

promessa_pagamento_totais <- resultados %>%
filter(promessa_pgto != 0)

ggplot(promessa_pagamento_totais, aes(x = grupo, fill = grupo)) +
 geom_bar(stat = "count", color = "black", width = 0.5, position = "dodge") +
 scale_fill_brewer(palette = "Set3") +
 geom_text(stat = "count", aes(label = ..count.., y = ..count../2),
            color = "black", size = 5, position = position_dodge(0.5)) +
labs(
 title = "Usuarios que avançaram para a etapa Promessa de Pagamento",
  x = "Grupo (Controle vs Variante)",
 y = "Numero de Usuários que Avançaram",
fill = "Grupo"
) +
theme_minimal()

Taxa de Promessa de Pagamento por Versão do Teste

Cálculo utilizado: usuarios com promessa de pagamento por versão / total de usuarios por versão

Este cálculo analisa as versões com maior número de usuários na etapa de promessa de pagamento.

Os dados apresentados na seção de cancelamento mostrou que houve um número menor de usuários que abandoram a etapa de promessa na versão Controle (129474, 87.96%).Esse grupo também é responsável pelo maior conjunto de usuários que realizaram a promessa com 12.04% (17723) contra 11.46% (146561) da versão Variante.

Vale lembrar que a versão Variante recebeu 146561 usuários totais no teste, com uma diferença de 636 em relação ao que foi registrado pela versão Controle e dos usuários recebidos, 88.54% (129767) abandoram a sessão sem seguir para a etapa de promessa de pagamento.

usuarios_totais <- resultados %>%
  group_by(grupo) %>%
  summarise(total_de_usuarios = length(user_id), .groups = "drop")

usuarios_promessa <- promessa_pagamento_totais %>%
  group_by(grupo) %>%
  summarise(total_realizaram_promessa_pgto = length(user_id), .groups = "drop")

taxa_promessa_pagamento <- usuarios_totais %>%
  left_join(usuarios_promessa, by = "grupo") %>%
  mutate(
    taxa_promessa_pagamento = (total_realizaram_promessa_pgto / total_de_usuarios) * 100
  ) %>%
  mutate(
    taxa_promessa_pagamento = paste0(round(taxa_promessa_pagamento, 2), "%")
  ) %>%
  rename(
    `Total de Usuários` = total_de_usuarios,
    `Usuários que realizaram promessa de pagamento` = total_realizaram_promessa_pgto,
    `Taxa de Promessa de Pagamento por Grupo (%)` = taxa_promessa_pagamento
  )
datatable(taxa_promessa_pagamento, caption = "Taxa de Promessa de Pagamento por Grupo (%)")

Modalidade de Pagamento Selecionada nas Promessas de Pagamento

Das 16794 promessas de pagamento registradas na versão Variante, 59,94% são pagamentos em formato PIX contra 40,06% de pagamentos por boleto.

Já na versão Controle, existe certo equilíbrio quanto ao tipo de pagamento selecionado, uma vez que 50,36% dos usuários optaram por PIX e 49,64% seguiram com o boleto.

Este comportamento pode nos revelar que a versão Variante trouxe usuários mais interessados em efetivarem o pagamento de forma mais rápida.

formas_pagamento_grupo <- promessa_pagamento_totais %>%
  group_by(grupo, forma_pgto) %>%
  summarise(total_usuarios = n(), .groups = "drop")

grafico <- ggplot(formas_pagamento_grupo, aes(x = grupo, y = total_usuarios, fill = forma_pgto)) +
  geom_bar(stat = "identity", position = "stack") +
  labs(
    title = "Formas de Pagamento por Grupo (Controle vs Variante)",
    x = "Grupo",
    y = "Número de Usuários",
    fill = "Forma de Pagamento"
  ) +
  theme_minimal() +
  scale_fill_manual(values = c("Boleto" = "steelblue", "Pix" = "tomato"))
ggplotly(grafico)

Receita Obtida por Promessas de Pagamento

Na análise comparativa entre as versões do teste que avalia o valor total de receita por forma de pagamento na versão Variante, observou-se que R$ 15.207.645,00 (59,83%) correspondem a pagamentos via Pix, enquanto R$ 10.211.527,00 (40,17%) referem-se a pagamentos por boleto bancário. Ao analisar a distribuição de métodos de pagamento por número de transações nessa mesma versão, verificou-se que 59,94% (10.066) dos pagamentos foram realizados via Pix, enquanto 40,06% (6.728) foram feitos por boleto. Isso indica que o valor médio por transação foi de R$ 905,54 para pagamentos via Pix, e R$ 1.517,77 para pagamentos por boleto bancário.

Na vesão Controle, PIX domina 50,06% (R$ 13.365.543,00) da receita gerada enquanto que os 49,94% (R$ 13.335.736,00) restantes correspondem a pagamentos por boleto. Esta versão, que demonstra maior equilíbrio até esta fase do estudo, revela que a receita média por Pix de usuários recebidos é R$ 1.497,37 enquanto que, para boleto, a quantia média de R$ 1.515,94.

Além disso, outro ponto observado é que entre as receitas alcançadas, a versão Controle (R$ 26.701.279,00) tem um aumento de 5,04% (R$ 25.419.172,00) se comparado com a versão Variante.

total_pagamentos <- promessa_pagamento_totais %>%
filter(forma_pgto %in% c("Boleto", "PIX")) %>% 
 group_by(grupo, forma_pgto) %>%  
 summarise(total_valores = sum(valor, na.rm = TRUE), .groups = "drop")  
 
total_pagamentos$total_valores <- paste0(
  "R$ ", format(total_pagamentos$total_valores, big.mark = ".", decimal.mark = ",", nsmall = 2) ) 

grafico <- ggplot(total_pagamentos, aes(x = grupo, y = total_valores, fill = forma_pgto)) +
  geom_text(aes(label = total_valores), position = position_stack(vjust = 0.4), color = "white", size = 4) + 
    geom_bar(stat = "identity", position = "stack") +
  labs(
   title = "Formas de Pagamento por Grupo e Valor",
    x = "Grupo",
   y = "Total de Valores",
    fill = "Forma de Pagamento"
 ) +
   theme_minimal() +
   scale_fill_manual(values = c("Boleto" = "#FF6347", "PIX" = "#4682B4"))
 ggplotly(grafico)

Pagamentos Efetivados

Pagamentos Efetivados VS Promessa de Pagamento

A versão Controle contabilizou 53,27% (9441) de pagamentos efetivados contra 71,68% (12038) da versão Variante.

46,73% (8282) e 28,32% (4756) correspondem a promessas de pagamento sem transação posterior nas versões Controle e Variante respectivamente.

dados_chave_totais <- resultados %>%
filter(!grepl("-NA$", chave))
       
 resumo_efetivado <- dados_chave_totais %>%
 group_by(grupo, efetivado) %>%
 summarise(qtd = n(), .groups = "drop")

ggplot(resumo_efetivado, aes(x = grupo, y = qtd, fill = efetivado)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.6) +
  geom_text(
    aes(label = scales::percent(qtd / tapply(qtd, grupo, sum)[grupo], accuracy = 0.1)),
    position = position_dodge(width = 0.8),
    vjust = -0.3,
    size = 4,
    color = "black"
  ) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "Efetivação de Pagamentos por Grupo",
    x = "Grupo (Controle ou Variante)",
    y = "Proporção de Pagamentos",
    fill = "Efetivado"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
    legend.position = "bottom"
  )

Pagamentos Não Efetivados por Grupo

A versão Controle teve mais abandonos em ambas as formas de pagamento quando comparamos com a versão Variante do teste. Em ambos os cenários, o pagamento por boleto bancário é o que mais resulta em desistência (4903 usuários Controle, contra 2695 usuários Variante) com receita maior se comparado ao Pix.

dados_nao_efetivados <- dados_chave_totais %>%
    filter(efetivado == FALSE)

tabela_nao_efetivados <- dados_nao_efetivados %>%
  filter(forma_pgto %in% c("PIX", "Boleto")) %>%
  group_by(grupo, forma_pgto) %>%
   summarise(
   quantidade = n(),
      receita_total = sum(valor, na.rm = TRUE),
       .groups = "drop"
    ) %>%
    mutate(
        receita_total = round(receita_total, 2),
       valor_formatado = paste0(
           "R$ ", format(receita_total, big.mark = ".", decimal.mark = ",", nsmall = 2)
        )
    )
 datatable(
  tabela_nao_efetivados %>%
    select(grupo, forma_pgto, quantidade, valor_formatado),
  caption = "Pagamentos Não Efetivados por Grupo e Forma de Pagamento",
  options = list(pageLength = 5, autoWidth = TRUE),
   rownames = FALSE)

Conversão Total por Grupo

Cálculo utilizado: usuarios com pagamentos efetivados por versão / total de usuarios por versão

A análise da taxa de conversão por grupo revelou que a Variante superou o Controle de forma consistente. O grupo Controle apresentou uma taxa de conversão de 6,41%, enquanto a Variante alcançou 8,21%. Essa diferença representa um aumento relativo de aproximadamente 28% na taxa de conversão da Variante em relação ao Controle, indicando que a mudança testada teve impacto positivo no comportamento dos usuários.

taxa_conversao <- resultados %>%
  group_by(grupo) %>%
  summarise(
    total_usuarios = length(user_id),
    usuarios_efetivados = sum(efetivado == TRUE),
    taxa_conversao = (usuarios_efetivados / total_usuarios) * 100,
    .groups = "drop"
  ) %>%
  mutate(
    taxa_conversao = paste0(round(taxa_conversao, 2), "%")
  ) %>%
  rename(
    `Total de Usuários` = total_usuarios,
    `Usuários Efetivados` = usuarios_efetivados,
    `Taxa de Conversão (%)` = taxa_conversao
  )

ggplot(taxa_conversao, aes(x = grupo, y = as.numeric(gsub("%", "", `Taxa de Conversão (%)`)), fill = grupo)) +
  geom_bar(stat = "identity", width = 0.4, color = NA) +
  geom_text(
    aes(label = `Taxa de Conversão (%)`),
    vjust = -0.8, 
    size = 6, 
    fontface = "bold",
    color = "gray20"
  ) +
  scale_fill_manual(values = c("#4E79A7", "#F28E2B")) +  # Cores sofisticadas
  labs(
    title = "Taxa de Conversão por Grupo",
    subtitle = "Comparativo entre Controle e Variante",
    x = NULL,
    y = "Taxa de Conversão (%)"
  ) +
  theme_minimal(base_family = "Arial", base_size = 16) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5, size = 20),
    plot.subtitle = element_text(hjust = 0.5, size = 14, color = "gray40"),
    axis.title.y = element_text(face = "bold", size = 14),
    axis.text.x = element_text(face = "bold", size = 14),
    axis.text.y = element_blank(),
    panel.grid.major.x = element_line(color = "gray85", linetype = "dashed"),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_blank(),
    legend.position = "none"
  ) +
  ylim(0, 10)

Método de Pagamento Mais Utilizado

Pix é a forma de pagamento mais dominante em ambas as versões. Destaca-se as receitas obtidas por este método bem como o número de usuários aderentes.

Na Variante, usuários que optaram por Boleto Bancário representam 59,20% se comparado com o número de usuários que pagaram com Pix (40,80%).

No grupo Controle, observamos uma divisão em que 33,50% dos usuários selecionaram Boleto Bancário contra 66,50% finalizações com PIX.

dados_efetivados <- dados_chave_totais %>%
 filter(efetivado == TRUE)

tabela_efetivados <- dados_efetivados %>%
     filter(forma_pgto %in% c("PIX", "Boleto")) %>%
    group_by(grupo, forma_pgto) %>%
      summarise(
      quantidade = n(),
               receita_total = sum(valor, na.rm = TRUE),
         .groups = "drop"
   ) %>%
   mutate(
       receita_total = round(receita_total, 2),
           valor_formatado = paste0(
                  "R$ ", format(receita_total, big.mark = ".", decimal.mark = ",", nsmall = 2)
         ))

datatable(
     tabela_efetivados %>%
     select(grupo, forma_pgto, quantidade, valor_formatado),
  caption = "Pagamentos Efetivados por Grupo e Forma de Pagamento",
   options = list(pageLength = 5, autoWidth = TRUE),
     rownames = FALSE)

Conclusão

A análise integrada dos dados do teste A/B e das transações financeiras revelou que a variante apresentou melhor desempenho em termos de taxa de conversão final (pagamentos efetivados) e geração de receita, com diferença estatisticamente significativa. Além da conversão final, foi realizada uma análise intermediária de promessas de pagamento para entender o comportamento antes da efetivação. Observamos que:

  • A variante também melhorou a taxa de promessa de pagamento em relação ao controle.
  • A conversão de promessas em pagamentos efetivos se manteve proporcionalmente estável entre as versões.

Isso indica que o novo fluxo não apenas incentiva mais usuários a iniciar pagamentos, como também não compromete a efetivação — ou seja, o aumento nas promessas não é artificial ou enganoso.

Projeção

A projeção simulada parte da taxa de conversão atual da versão Variante (8,2%, com 12038 de usuários efetivados), considerando o cenário em que esse grupo receba o mesmo volume de usuários futuros. Com um total de 146.561 usuários simulados, pequenos aumentos percentuais na taxa de conversão geram ganhos expressivos em volume de transações:

  • Um aumento para 9,0% implicaria em aproximadamente 13.190 usuários convertidos (contra os 12.038 atuais);

  • Em uma taxa de 10,5%, esse número sobe para cerca de 15.389 usuários.

Essa análise reforça que otimizações mesmo discretas no fluxo da Variante podem resultar em ganhos substanciais de receita, especialmente em escala. O comportamento mais engajado observado nesta versão — tanto na etapa de promessa de pagamento quanto na efetivação — indica que há espaço para crescimento com base em ajustes incrementais e ações de retenção.

library(ggplot2)

usuarios_variante <- 146561

taxas_percentuais <- seq(8.5, 10.5, by = 0.5)
taxas_decimais <- taxas_percentuais / 100

usuarios_efetivados_projetados <- usuarios_variante * taxas_decimais

df_projecao <- data.frame(
  taxa_conversao = taxas_percentuais,
  usuarios_projetados = usuarios_efetivados_projetados
)

library(plotly)
fig <- plot_ly(
  data = df_projecao,
  x = ~taxa_conversao,
  y = ~usuarios_projetados,
  type = 'scatter',
  mode = 'lines+markers+text',
  text = ~round(usuarios_projetados),
  textposition = 'top center',
  marker = list(color = 'darkgreen', size = 8),
  line = list(color = 'darkgreen', width = 2),
  name = "Projeção"
)

# Adicionando o ponto da taxa atual
fig <- fig %>%
  add_trace(
    x = c(8.2),
    y = c(12038),
    type = 'scatter',
    mode = 'markers+text',
    marker = list(color = 'red', size = 10, symbol = 'circle'),
    text = paste0("Atual: ", round(12038), " usuários"),
    textposition = 'top center',
    name = "Taxa Atual"
  ) %>%
  layout(
    title = list(text = "📈 Projeção de Conversões - Grupo Variante", x = 0.5),
    xaxis = list(title = "Taxa de Conversão (%)"),
    yaxis = list(title = "Usuários Efetivados Projetados"),
    shapes = list(
      list(
        type = "line",
        x0 = 8.2,
        x1 = 8.2,
        y0 = min(df_projecao$usuarios_projetados),
        y1 = max(df_projecao$usuarios_projetados),
        line = list(dash = 'dash', color = 'red')
      )
    )
  )

fig

Recomendações e Próximos Passos

1. Tornar a Variante padrão do site

A Variante superou consistentemente o Controle em:

  • Taxa de conversão final (+28% de aumento relativo);
  • Efetivação após promessa de pagamento (71,68% vs 53,27%);
  • Receita gerada via formas de pagamento (com Pix gerando R$ 12.078.948,00, um aumento de 45,22% em relação a receita de R$ 8.317.557,00 da versão Controle. Por Boleto Bancário, o aumento foi de 2,32% sendo a receita Variante de R$ 6.049.655,00 e a Controle R$ 5.912.715,00)

Esses indicadores sustentam a escolha da Variante como versão vencedora.


2. Otimizar o fluxo da Variante com foco em PIX

A maior parte das promessas e dos pagamentos efetivados foi realizada via PIX, o que sugere:

  • Maior urgência na intenção de pagamento;
  • Preferência do usuário por métodos instantâneos.

Ação recomendada: priorizar o PIX no layout ou incluir incentivos visuais para reforçar esse comportamento Alguns exemplos são: - colocar a forma de pagamento em primeiro lugar na lista de opções; destacar o botão com uma cor ou borda específica; - ou adicionar selos visuais que ativem heurísticas de decisão rápida; - fluxo responsivo otimizado para mobile garantindo que o botão de PIX Seja fácil de clicar no celular, apareça antes de qualquer scroll


3. Reduzir abandono na etapa de promessa

Apesar da maior taxa de conversão final, a Variante ainda apresenta 88,54% de abandono antes da promessa.

Próximos passos: - Testar variações de layout, microtextos e indicadores de urgência; - Aplicar UX writing voltado para segurança e agilidade.


4. Investigar comportamento dos não pagadores

Há evidência de que o boleto concentra a maioria das promessas não efetivadas.

Sugestões: - Mapear motivos de desistência com pesquisas rápidas e embutidas no app (curtas e opcionais), como: “O que impediu você de finalizar o pagamento?” com opções clicáveis e botão de “prefero não responder”). - Testar lembretes ou notificações para incentivar o pagamento do boleto; - Avaliar o impacto de substituição ou despriorização dessa opção.


5. Monitorar duplicidade entre grupos

Apesar de a análise ter indicado ausência de usuários duplicados entre Controle e Variante, é recomendável:

  • Reforçar esse controle em futuros testes A/B;
  • Incluir validações preventivas no momento do disparo do experimento (ex: check de ID antes da atribuição) garantindo que cada usuário seja alocado apenas uma vez (em controle ou variante) e que isso não mude entre sessões ou interações;
  • Analisar usuários novos x retornantes pois o impacto de versões pode variar entre perfis;
  • Validar o split de tráfego distribuído para garantir distribuição equilibrada entre grupos;
  • Considerar análises adicionais por canal de entrada (ex: push, notificação, busca interna).