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-keyImportant: 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
