Installation
Guía completa para integrar ChurnCut en tu aplicación.
Arquitectura
ChurnCut funciona con dos componentes:
- Backend - Llama a la API de ChurnCut para generar URL de sesión
- Frontend - Widget JavaScript que muestra el flujo de cancelación
text
Your Frontend --> Your Backend --> Churncut API
(JS Widget) (Get Session URL)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 autenticación API (nunca exponer en el cliente)
Paso 2: Llamar a la API de sesión
Crea un endpoint en tu backend que llame a la API de ChurnCut para obtener la URL de sesión.
Express.js
javascript
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json()); // Fix #3: parse request body
const CHURNCUT_SECRET = process.env.CHURNCUT_SECRET_KEY;
const CHURNCUT_APP_ID = process.env.CHURNCUT_APP_ID;
app.post('/api/churncut-url', async (req, res) => {
const { customerEmail } = req.body;
const expiration = Math.floor(Date.now() / 1000) + 3600;
const response = await axios.post(
'https://app.churncut.com/churncut-client-integration/get-cancellation-session-url',
{
churncut_app_id: CHURNCUT_APP_ID,
expiration_date_timestamp: expiration,
customer_email: customerEmail
},
{
headers: {
'Authorization': `Bearer ${CHURNCUT_SECRET}`,
'Content-Type': 'application/json'
}
}
);
const data = response.data; // axios parses JSON automatically, no .json() needed
res.json({ url: data.url, hmac: data.hmac });
});FastAPI (Python)
python
from fastapi import FastAPI
import os
import time
import requests
app = FastAPI()
CHURNCUT_SECRET = os.environ["CHURNCUT_SECRET_KEY"]
CHURNCUT_APP_ID = os.environ["CHURNCUT_APP_ID"]
@app.post("/api/churncut-url")
def get_cancellation_url(request: dict):
customer_email = request.get("customer_email")
expiration = int(time.time()) + 3600
response = requests.post(
"https://app.churncut.com/churncut-client-integration/get-cancellation-session-url",
headers={"Authorization": f"Bearer {CHURNCUT_SECRET}", "Content-Type": "application/json"},
json={
"churncut_app_id": CHURNCUT_APP_ID,
"expiration_date_timestamp": expiration,
"customer_email": customer_email,
},
)
data = response.json()
return {"url": data["url"], "hmac": data["hmac"]}
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/user_integration/js/integration_initiallizer.js"></script>React
jsx
import { useCallback } from 'react';
function CancelButton({ customerEmail }) {
const handleCancel = useCallback(async () => {
// Get session URL and hmac from backend
const res = await fetch('/api/churncut-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ customerEmail })
});
const { url, hmac } = await res.json();
// Start cancellation flow
window.starCancellationFromURl(url);
}, [customerEmail]);
return (
<button onClick={handleCancel}>
Cancel subscription
</button>
);
}Vue
vue
<template>
<button @click="handleCancel">Cancel subscription</button>
</template>
<script setup>
const props = defineProps(['customerEmail']);
async function handleCancel() {
const res = await fetch('/api/churncut-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ customerEmail: props.customerEmail })
});
const { url, hmac } = await res.json();
const urlObj = new URL(url);
const params = new URLSearchParams(urlObj.search);
window.starCancellationFromURl(data.url);
}
</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 llama a la API desde 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
