ChurnCut/Docs

Installation

Guía completa para integrar ChurnCut en tu aplicación.

Arquitectura

ChurnCut funciona con dos componentes:

  • Backend - Genera tokens HMAC para autenticar usuarios
  • Frontend - Widget JavaScript que muestra el flujo de cancelación
text
Your Frontend  -->  Your Backend  -->  Churncut API
 (JS Widget)       (HMAC Token)

Paso 1: Obtener credenciales

En tu dashboard de ChurnCut, ve a Settings y copia:

  • App ID: Identificador único para tu aplicación
  • Secret Key: Clave secreta para generar tokens (nunca exponer en el cliente)

Paso 2: Implementar endpoint de token

Crea un endpoint en tu backend que genere el token HMAC cuando un usuario quiera cancelar.

Express.js

javascript
const express = require('express');
const crypto = require('crypto');

const app = express();

const CHURNCUT_SECRET = process.env.CHURNCUT_SECRET_KEY;
const CHURNCUT_APP_ID = process.env.CHURNCUT_APP_ID;

app.get('/api/churncut-token', (req, res) => {
  const { customerId, subscriptionId } = req.query;

  // Token expires in 1 hour
  const expiration = Math.floor(Date.now() / 1000) + 3600;

  const message = customerId + CHURNCUT_APP_ID + expiration;
  const token = crypto
    .createHmac('sha256', CHURNCUT_SECRET)
    .update(message)
    .digest('hex');

  res.json({
    token,
    expiration: expiration.toString(),
    appId: CHURNCUT_APP_ID
  });
});

FastAPI (Python)

python
from fastapi import FastAPI
import hmac
import hashlib
import os
import time

app = FastAPI()

CHURNCUT_SECRET = os.environ["CHURNCUT_SECRET_KEY"]
CHURNCUT_APP_ID = os.environ["CHURNCUT_APP_ID"]

@app.get("/api/churncut-token")
def get_churncut_token(customer_id: str, subscription_id: str):
    # Token expires in 1 hour
    expiration = str(int(time.time()) + 3600)

    message = (customer_id + CHURNCUT_APP_ID + expiration).encode('utf-8')
    token = hmac.new(
        CHURNCUT_SECRET.encode('utf-8'),
        message,
        digestmod=hashlib.sha256
    ).hexdigest()

    return {
        "token": token,
        "expiration": expiration,
        "appId": CHURNCUT_APP_ID
    }

Paso 3: Integrar el widget

Añade el script de ChurnCut y conéctalo a tu botón de cancelar.

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

React

jsx
import { useCallback } from 'react';

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

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

  return (
    <button onClick={handleCancel}>
      Cancel subscription
    </button>
  );
}

Vue

vue
<template>
  <button @click="handleCancel">Cancel subscription</button>
</template>

<script setup>
const props = defineProps(['customerId', 'subscriptionId']);

async function handleCancel() {
  const res = await fetch(
    `/api/churncut-token?customerId=${props.customerId}&subscriptionId=${props.subscriptionId}`
  );
  const { token, expiration, appId } = await res.json();

  window.startCancellationFlow(
    props.customerId,
    props.subscriptionId,
    token,
    expiration,
    appId
  );
}
</script>

Variables de entorno

Configura estas variables en tu servidor:

bash
CHURNCUT_APP_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CHURNCUT_SECRET_KEY=your-secret-key

Important: Nunca expongas tu Secret Key en el cliente. Siempre genera tokens en el backend.

Probar la integración

  • Usa credenciales de test en tu entorno de desarrollo
  • Inicia un flujo de cancelación con un cliente test de Stripe
  • Verifica que el widget aparece correctamente
  • Comprueba los eventos en tu dashboard de ChurnCut