---
title: "Gerenciar Pro — eu.dev.br"
url: "https://eu.dev.br/pro/gerenciar/"
markdown_url: "https://eu.dev.br/pro/gerenciar.MD"
description: "Gerencie sua assinatura do Acesso Antecipado: plano atual, próxima renovação, cancelar (com opção de retenção)."
date: "2026-05-26"
author: ""
---

# Gerenciar Pro — eu.dev.br

Gerencie sua assinatura do Acesso Antecipado: plano atual, próxima renovação, cancelar (com opção de retenção).


{{< public-only >}}

Esta página é a versão pública. Para gerenciar sua assinatura (cancelar, ver próxima cobrança, aceitar retenção), faça login em **[/pro/entrar/?return=/gerenciar/](/pro/entrar/?return=/gerenciar/)** com o mesmo email que você usou no pagamento — depois do link de acesso, você cai em **pro.eu.dev.br/gerenciar/** com os controles reais.

## o que você consegue lá

- ver o plano atual (mensal R$ 9,99 ou anual R$ 69,93) e quando renova
- abrir o portal de cobrança do Stripe (atualizar cartão, baixar nota)
- aceitar **uma oferta única de 30% off pelos próximos 3 meses** antes de cancelar
- cancelar de vez (sem fidelidade, sem pegadinha)

## ainda não é assinante?

Volta para [/pro/](/pro/) e escolhe entre mensal ou anual.

{{< /public-only >}}

{{< pro-only >}}

<div id="gerenciar-loading" style="border:2px solid var(--ink);padding:var(--s-6);margin:var(--s-6) 0;">
  carregando sua assinatura…
</div>

<div id="gerenciar-content" style="display:none;">

  <h2 style="margin-bottom:var(--s-3);">sua assinatura</h2>

  <div style="border:2px solid var(--ink);padding:var(--s-6);margin:var(--s-4) 0;">
    <p style="margin:0 0 var(--s-2);font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:0.08em;">// status</p>
    <p style="margin:0;font-size:18px;font-weight:800;">
      <span id="g-status">—</span> · <span id="g-plan">—</span>
    </p>
    <p style="margin:var(--s-3) 0 0;font-size:12px;color:var(--muted);">próxima cobrança: <span id="g-next">—</span></p>
    <p style="margin:var(--s-2) 0 0;font-size:12px;color:var(--muted);">acesso antecipado: 48h de vantagem sobre o site público.</p>
  </div>

  <h2 id="trocar-de-plano" style="margin-top:var(--s-7);">trocar de plano</h2>

  <div id="switch-box" style="border:2px solid var(--ink);padding:var(--s-5);margin:var(--s-4) 0;">
    <p style="margin-top:0;font-size:13px;" id="switch-pitch">—</p>
    <button id="btn-switch" type="button"
            class="pro-cta"
            style="display:inline-block;"
            data-umami-event="paywall:plan-switch-intent"
            data-umami-event-location="pro-gerenciar">
      trocar plano →
    </button>
    <p id="switch-msg" style="margin:var(--s-3) 0 0;font-size:12px;color:var(--muted);min-height:1em;"></p>
  </div>

  <h2 style="margin-top:var(--s-7);">cancelar / faturas</h2>

  <p style="margin-top:var(--s-3);">O portal de cobrança do Stripe te leva ao fluxo de cancelamento, atualização de cartão e download das notas fiscais.</p>

  <button id="btn-portal" type="button"
          class="btn ghost"
          style="display:inline-block;margin-top:var(--s-3);"
          data-umami-event="paywall:cancel-intent"
          data-umami-event-location="pro-gerenciar">
    abrir portal de cobrança →
  </button>

  <div id="retention-box" style="display:none;border:2px solid var(--lime);padding:var(--s-5);margin:var(--s-5) 0 0;">
    <strong style="text-transform:uppercase;letter-spacing:0.08em;font-size:12px;">// espera — oferta única antes de cancelar</strong>
    <p style="margin:var(--s-2) 0 var(--s-4);">Antes de você ir pro portal, posso aplicar <strong>30% de desconto nos próximos 3 meses</strong>? Vale uma vez por assinante. Se aceitar, continua com o Pro mais barato; se não, segue pra cancelar.</p>
    <button id="btn-retain" type="button"
            class="pro-cta"
            style="display:inline-block;"
            data-umami-event="paywall:retention-accept"
            data-umami-event-location="pro-gerenciar">
      aceitar 30% off por 3 meses
    </button>
    <button id="btn-portal-decline" type="button"
            class="btn ghost"
            style="display:inline-block;margin-left:var(--s-3);"
            data-umami-event="paywall:retention-decline"
            data-umami-event-location="pro-gerenciar">
      não, quero cancelar mesmo →
    </button>
    <p id="retention-msg" style="margin:var(--s-3) 0 0;font-size:12px;color:var(--muted);"></p>
  </div>

  <p style="margin-top:var(--s-6);font-size:11px;color:var(--muted);">// precisa de ajuda? escreve pra suporte@eu.dev.br com o email da sua assinatura.</p>

</div>

<script>
(function () {
  var WORKER = 'https://pro.eu.dev.br/api';

  function $(id) { return document.getElementById(id); }

  function fmtDate(unix) {
    if (!unix) return '—';
    var d = new Date(unix * 1000);
    return d.toLocaleDateString('pt-BR', { year: 'numeric', month: 'long', day: 'numeric' });
  }

  function fmtPlan(plan) {
    if (plan === 'monthly') return 'Mensal — R$ 9,99/mês';
    if (plan === 'yearly') return 'Anual — R$ 69,93/ano';
    return plan || '—';
  }

  function fmtStatus(s) {
    if (s === 'active') return 'ativa';
    if (s === 'trialing') return 'período de teste';
    if (s === 'past_due') return 'pagamento atrasado';
    if (s === 'canceled') return 'cancelada';
    if (s === 'unpaid') return 'inadimplente';
    if (s === 'unknown') return 'sem assinatura encontrada';
    return s || '—';
  }

  function showError(msg) {
    $('gerenciar-loading').innerHTML = '<strong>algo deu errado:</strong><br>' + msg +
      '<br><br>se persistir, escreve pra suporte@eu.dev.br';
  }

  // Track whether the retention offer has already been used (server-side
  // truth from /api/me). If true, /api/portal calls bypass the offer
  // and go straight to Stripe. If false, the first click on
  // "abrir portal de cobrança" surfaces the retention save-flow before
  // any redirect happens.
  var retentionUsed = false;
  var currentPlan = null;

  function redirectToPortal(btn) {
    btn.disabled = true;
    var original = btn.textContent;
    btn.textContent = 'abrindo portal…';
    fetch(WORKER + '/portal', { method: 'POST', credentials: 'include' })
      .then(function (r) { return r.json(); })
      .then(function (data) {
        if (data.url) {
          window.umami && window.umami.track('paywall:portal-opened');
          window.location.href = data.url;
        } else {
          btn.disabled = false;
          btn.textContent = original;
          alert('erro: ' + (data.error || 'sem URL'));
        }
      })
      .catch(function (e) {
        btn.disabled = false;
        btn.textContent = original;
        alert('erro de rede: ' + e);
      });
  }

  fetch(WORKER + '/me', { credentials: 'include' })
    .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
    .then(function (data) {
      $('g-status').textContent = fmtStatus(data.status);
      $('g-plan').textContent = fmtPlan(data.plan);
      $('g-next').textContent = fmtDate(data.current_period_end);
      $('gerenciar-loading').style.display = 'none';
      $('gerenciar-content').style.display = '';

      retentionUsed = !!data.retention_used;

      // Populate the "trocar de plano" section based on current plan.
      currentPlan = data.plan;
      if (data.plan === 'monthly') {
        $('switch-pitch').innerHTML = '<strong>Pulando pra anual,</strong> você paga R$ 69,93 uma vez e ganha <strong>5 meses grátis</strong> (~42% de economia vs continuar pagando R$ 9,99/mês). A proração da diferença entra na próxima fatura.';
        $('btn-switch').textContent = 'trocar pra anual (5 meses grátis) →';
        $('btn-switch').setAttribute('data-target', 'yearly');
      } else if (data.plan === 'yearly') {
        $('switch-pitch').innerHTML = '<strong>Voltando pra mensal,</strong> você passa a pagar R$ 9,99/mês a partir da próxima cobrança. A proração do que você já pagou no anual vira crédito na conta. Mais flexível, custa mais.';
        $('btn-switch').textContent = 'trocar pra mensal →';
        $('btn-switch').setAttribute('data-target', 'monthly');
      } else {
        $('switch-box').style.display = 'none';
      }

      if (data.status === 'unknown' || data.status === 'canceled') {
        $('switch-box').style.display = 'none';
        $('btn-portal').textContent = 'voltar para /pro/ →';
        $('btn-portal').onclick = function () { window.location.href = 'https://eu.dev.br/pro/'; };
      }
    })
    .catch(function (e) { showError(String(e && e.message || e)); });

  // Plan switch handler
  $('btn-switch').addEventListener('click', function () {
    var btn = this;
    var target = btn.getAttribute('data-target');
    if (!target) return;
    var confirmMsg = target === 'yearly'
      ? 'Confirmar troca pra anual? R$ 69,93/ano com 5 meses grátis. A proração entra na próxima fatura.'
      : 'Confirmar troca pra mensal? R$ 9,99/mês a partir da próxima cobrança. A proração do anual vira crédito.';
    if (!window.confirm(confirmMsg)) return;
    btn.disabled = true;
    btn.textContent = 'trocando…';
    fetch(WORKER + '/switch-plan', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ target: target }),
      credentials: 'include'
    })
      .then(function (r) { return r.json().then(function (j) { return { status: r.status, body: j }; }); })
      .then(function (res) {
        if (res.status === 200 && res.body.ok) {
          $('switch-msg').innerHTML = '✓ ' + res.body.message;
          $('g-plan').textContent = fmtPlan(res.body.plan);
          $('g-next').textContent = fmtDate(res.body.current_period_end);
          // Swap the switch UI to the OTHER direction now.
          currentPlan = res.body.plan;
          if (res.body.plan === 'yearly') {
            $('switch-pitch').innerHTML = '<strong>Voltando pra mensal,</strong> você passa a pagar R$ 9,99/mês a partir da próxima cobrança. A proração do que você já pagou no anual vira crédito na conta.';
            btn.textContent = 'trocar pra mensal →';
            btn.setAttribute('data-target', 'monthly');
          } else {
            $('switch-pitch').innerHTML = '<strong>Pulando pra anual,</strong> você paga R$ 69,93 uma vez e ganha <strong>5 meses grátis</strong>. A proração entra na próxima fatura.';
            btn.textContent = 'trocar pra anual (5 meses grátis) →';
            btn.setAttribute('data-target', 'yearly');
          }
          btn.disabled = false;
          window.umami && window.umami.track('paywall:plan-switched', { plan: res.body.plan });
        } else {
          $('switch-msg').textContent = '✗ ' + (res.body.error || 'erro ao trocar');
          btn.disabled = false;
          btn.textContent = target === 'yearly' ? 'trocar pra anual (5 meses grátis) →' : 'trocar pra mensal →';
        }
      })
      .catch(function (e) {
        $('switch-msg').textContent = '✗ erro de rede: ' + e;
        btn.disabled = false;
      });
  });

  // Primary cancel button: surfaces retention offer first (unless already used).
  $('btn-portal').addEventListener('click', function () {
    var btn = this;
    if (retentionUsed) {
      // Already used the retention coupon — go straight to portal.
      redirectToPortal(btn);
      return;
    }
    // First time: show the save-flow before any redirect.
    $('retention-box').style.display = 'block';
    btn.style.display = 'none';
    window.umami && window.umami.track('paywall:cancel-intent-soft', { location: 'pro-gerenciar' });
    // Scroll the retention box into view (works on small screens too).
    setTimeout(function () { $('retention-box').scrollIntoView({ behavior: 'smooth', block: 'center' }); }, 50);
  });

  // Retention accept: apply the coupon.
  $('btn-retain').addEventListener('click', function () {
    var btn = this;
    btn.disabled = true;
    btn.textContent = 'aplicando…';
    fetch(WORKER + '/retain', { method: 'POST', credentials: 'include' })
      .then(function (r) { return r.json().then(function (j) { return { status: r.status, body: j }; }); })
      .then(function (res) {
        if (res.status === 200 && res.body.ok) {
          $('retention-msg').textContent = '✓ ' + res.body.message + ' (você continua no Pro; cancelamento abortado)';
          btn.textContent = 'aplicado ✓';
          $('btn-portal-decline').style.display = 'none';
          retentionUsed = true;
          window.umami && window.umami.track('paywall:retention-applied');
        } else {
          $('retention-msg').textContent = '✗ ' + (res.body.error || 'erro ao aplicar');
          btn.disabled = false;
          btn.textContent = 'aceitar 30% off por 3 meses';
        }
      })
      .catch(function (e) {
        $('retention-msg').textContent = '✗ erro de rede: ' + e;
        btn.disabled = false;
        btn.textContent = 'aceitar 30% off por 3 meses';
      });
  });

  // Retention decline: go to portal anyway.
  $('btn-portal-decline').addEventListener('click', function () {
    redirectToPortal(this);
  });
})();
</script>

{{< /pro-only >}}
