ChurnCut/Docs

Quickstart

Integrate ChurnCut into your application in minutes and start retaining customers.

Prerequisites

  • An active Stripe account with subscriptions (live or test)
  • Your App ID and Secret Key from ChurnCut (available in Settings)
  • Ability to add a JavaScript snippet to your web app
  • A developer available for API integration
ChurnCut Settings page showing where to find your Secret Key and Organization ID under the API access section
Find your Secret Key and Organization ID in Settings → API access

Step 1: Get Cancellation Session URL

Call the ChurnCut API from your backend to generate a session URL.

Node.js

javascript
const requests = require('requests');

async function getCancellationUrl(apiKey, appId, customerEmail) {
  const expiration = Math.floor(Date.now() / 1000) + 3600;

  const response = await requests.post(
    'https://app.churncut.com/churncut-client-integration/get-cancellation-session-url',
    {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      json: {
        churncut_app_id: appId,
        expiration_date_timestamp: expiration,
        customer_email: customerEmail
      }
    }
  );

  return response.json(); // Returns { url, hmac }
}

Python

python
import requests
import time

def get_cancellation_url(api_key: str, app_id: str, customer_email: str):
    expiration = int(time.time()) + 3600

    response = requests.post(
        "https://app.churncut.com/churncut-client-integration/get-cancellation-session-url",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        },
        json={
            "churncut_app_id": app_id,
            "expiration_date_timestamp": expiration,
            "customer_email": customer_email
        }
    )

    return response.json()  # Returns { url, hmac }

Important: The API call must be made from your backend. Never expose your Secret Key on the client.

Step 2: Add the script

Include the ChurnCut script in your web application:

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

Step 3: Start the cancellation flow

After getting the URL from Step 1, parse it and call starCancellationFromURl:

javascript
// After getting { url, hmac } from the API

starCancellationFromURl(url);

Complete examples by framework

Choose your framework to see a complete example with cancel button:

jsx
import { useCallback } from 'react';

function CancelButton({ customerEmail }) {
  const handleCancel = useCallback(async () => {
    // 1. Get session URL and hmac from your backend
    const res = await fetch('/api/churncut-url', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ customerEmail })
    });
    const { url } = await res.json();

    // 2. Parse URL and start cancellation flow
    const urlObj = new URL(url);
    const params = new URLSearchParams(urlObj.search);

    window.starCancellationFromURl(data.url);
  }, [customerEmail]);

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

Cancel button with subscription preview

A common pattern is to show the user's subscription details with a cancel button. Here's a complete component you can adapt:

Preview

Pro Plan

$49/month · Renews Feb 28, 2026

StatusActive
Payment method•••• 4242
jsx
import { useCallback, useState, useEffect } from 'react';

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

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

  const handleCancel = useCallback(async () => {
    // 1. Get session URL from your backend
    const res = await fetch('/api/churncut-url', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ customerEmail })
    });
    const { url } = await res.json();

    // 2. Parse URL and start cancellation flow
    const urlObj = new URL(url);
    const params = new URLSearchParams(urlObj.search);

    // 3. ChurnCut handles the rest — shows personalized offers,
    //    collects feedback, and only cancels if the user confirms
    window.starCancellationFromURl(data.url);
  }, [customerEmail]);

  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 handles showing personalized offers, collecting feedback, and only cancels if the user confirms. You just need to call starCancellationFromURl.

Alternative method: Cancellation with Stripe IDs

If you prefer to use Stripe IDs instead of customer email, use this variant:

json
{
  "churncut_app_id": "your-app-uuid",
  "expiration_date_timestamp": 1735689600,
  "external_user_id": "stripe_customer_id",
  "subscription_id": "stripe_subscription_id"
}

Warning: When using Stripe IDs, make sure to provide a valid subscription_id as well.

Next steps