ChurnCut/Docs

Quickstart

Integra ChurnCut en tu aplicación en minutos y comienza a retener clientes.

Requisitos previos

  • Una cuenta activa de Stripe con suscripciones (live o test)
  • Tu App ID y Secret Key de ChurnCut (disponibles en Settings)
  • Posibilidad de añadir un snippet de JavaScript a tu app web
  • Un desarrollador disponible para la configuración de HMAC
ChurnCut Settings page showing where to find your Secret Key and Organization ID under the API access section
Encuentra tu Secret Key y Organization ID en Settings → API access

Paso 1: Generar firma HMAC

Para mantener el flujo de cancelación seguro y accesible solo para tus usuarios autenticados, necesitas generar un token HMAC en tu backend.

El token se genera concatenando:

  • external_user_id - Customer ID de Stripe
  • churncut_app_id - Tu App ID de ChurnCut
  • expiration_timestamp - Timestamp Unix de expiración
javascript
const crypto = require('crypto');

function generateChurncutToken(secretKey, customerId, appId, expirationTimestamp) {
  const message = customerId + appId + expirationTimestamp;

  return crypto
    .createHmac('sha256', secretKey)
    .update(message)
    .digest('hex');
}

// Example usage
const secretKey = "your-secret-key";
const customerId = "cus_XXXXXXXXXXXXXX";
const appId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
const expirationTimestamp = "1767139200";

const token = generateChurncutToken(secretKey, customerId, appId, expirationTimestamp);
console.log(token);

Important: El token HMAC debe generarse en tu backend. Nunca expongas tu Secret Key en el cliente.

Paso 2: Añadir el script

Incluye el script de ChurnCut en tu aplicación web:

html
<script src="https://app.churncut.com/static/js/churncut.js"></script>

Paso 3: Iniciar el flujo de cancelación

Una vez que tengas el token HMAC, puedes iniciar el flujo de cancelación:

javascript
startCancellationFlow(
  "cus_XXXXXXXXXXXXXX",    // Stripe customer ID
  "sub_XXXXXXXXXXXXXX",    // Current Stripe subscription ID
  "your-hmac-token",       // HMAC token generated in step 1
  "1767139200",            // Expiration timestamp (same used to generate token)
  "your-app-id"            // Your ChurnCut App ID
);

Ejemplos completos por framework

Elige tu framework para ver un ejemplo completo con botón de cancelación y token HMAC:

jsx
import { useCallback } from 'react';

function CancelButton({ customerId, subscriptionId }) {
  const handleCancel = useCallback(async () => {
    // 1. Get HMAC token from your backend
    const res = await fetch(
      \`/api/churncut-token?customerId=\${customerId}&subscriptionId=\${subscriptionId}\`
    );
    const { token, expiration, appId } = await res.json();

    // 2. Start the cancellation flow
    window.startCancellationFlow(
      customerId,
      subscriptionId,
      token,
      expiration,
      appId
    );
  }, [customerId, subscriptionId]);

  return (
    <button onClick={handleCancel} className="cancel-btn">
      Cancel subscription
    </button>
  );
}

Botón de cancelación con preview de suscripción

Un patrón común es mostrar los detalles de la suscripción del usuario con un botón para cancelar. Aquí tienes un componente completo que puedes adaptar:

Vista previa

Pro Plan

$49/month · Renews Feb 28, 2026

EstadoActiva
Método de pago•••• 4242
jsx
import { useCallback, useState, useEffect } from 'react';

function SubscriptionSettings({ customerId }) {
  const [subscription, setSubscription] = useState(null);

  useEffect(() => {
    // Fetch subscription details from your backend
    fetch(`/api/subscription?customerId=${customerId}`)
      .then(res => res.json())
      .then(data => setSubscription(data));
  }, [customerId]);

  const handleCancel = useCallback(async () => {
    // 1. Get HMAC token from your backend
    const res = await fetch(
      `/api/churncut-token?customerId=${customerId}&subscriptionId=${subscription.id}`
    );
    const { token, expiration, appId } = await res.json();

    // 2. ChurnCut handles the rest — shows personalized offers,
    //    collects feedback, and only cancels if the user confirms
    window.startCancellationFlow(
      customerId,
      subscription.id,
      token,
      expiration,
      appId
    );
  }, [customerId, subscription]);

  if (!subscription) return <div>Loading...</div>;

  return (
    <div className="subscription-card">
      <h3>{subscription.planName}</h3>
      <p>${subscription.amount}/month · Renews {subscription.renewalDate}</p>

      <div className="subscription-details">
        <div><span>Status</span><span>{subscription.status}</span></div>
        <div><span>Payment</span><span>•••• {subscription.last4}</span></div>
      </div>

      <div className="subscription-actions">
        <button onClick={() => navigate('/change-plan')}>
          Change plan
        </button>
        <button onClick={handleCancel} className="cancel-btn">
          Cancel subscription
        </button>
      </div>
    </div>
  );
}

Tip: ChurnCut se encarga de mostrar ofertas personalizadas, recoger feedback y solo cancela si el usuario lo confirma. Tú solo necesitas llamar a startCancellationFlow.

Método alternativo: Cancelación por email

Si prefieres identificar usuarios por email en lugar de IDs de Stripe:

javascript
startCancellationFlow(
  null,                       // No customer ID
  null,                       // No subscription ID
  "your-hmac-token",          // HMAC token
  "1767139200",               // Expiration timestamp
  "your-app-id",              // Your App ID
  "user@example.com"          // User email
);

Warning: Usa este método solo si cada usuario tiene un email único en Stripe y solo tiene una suscripción activa a la vez.

Próximos pasos