Churnkey Direct
Churnkey Direct lets you integrate retention flows with any billing system. Instead of connecting to Stripe or Chargebee, you pass customer and subscription data directly and handle billing operations through callbacks.
Use Direct mode when:
- You use a custom or unsupported billing system
- You have strict data privacy requirements
- You're managing trial or freemium users without subscriptions
- You need to test flows before setting up a full integration
How it works
- Pass customer data when initializing Churnkey
- Customer interacts with your retention flow
- Your handlers execute billing operations (cancel, discount, pause, etc.)
- Churnkey tracks results in analytics automatically
Quick Start
window.churnkey.init('show', {
appId: 'your_app_id',
mode: 'live',
provider: 'direct',
authHash: 'hmac_signature', // See Authentication section
customer: {
id: 'cus_12345',
email: '[email protected]',
},
subscriptions: [
{
id: 'sub_67890',
start: new Date('2024-06-01'), // When subscription started
status: {
name: 'active',
currentPeriod: {
start: new Date('2025-01-01'),
end: new Date('2025-02-01'),
},
},
items: [
{
price: {
id: 'price_pro',
amount: { value: 2999, currency: 'usd' },
interval: 'month',
intervalCount: 1,
},
},
],
},
],
async handleCancel(customer, surveyChoice, feedback, followupResponse) {
await yourAPI.cancelSubscription(customer.id);
return { message: 'Subscription canceled.' };
},
});
For script installation and HMAC authentication, see the Quick Start Guide.
Customer object
Identifies who is interacting with the retention flow. Only id is required.
Your internal customer ID. Used for authentication and tracking.
Customer's email address. Used for Slack notifications, merge fields, and analytics dashboard.
Customer's display name. Used for merge fields and analytics.
ISO 4217 currency code (e.g., 'usd', 'eur', 'gbp'). Used for customer segmentation.
Custom key-value pairs for segmentation. Can also use customerAttributes param. Example: {plan_tier: 'enterprise', team_size: '35'}
Usage: Additional fields like email, name, and metadata are used for segmentation, Slack notifications, merge fields, and analytics.
Subscription object
Describes the customer's billing state and determines which offers are shown.
Your internal subscription ID
Subscription status with status-specific fields. Determines which offers are shown.
At least one subscription item (plan) required
When subscription started. Required for accurate subscription age calculation used in segmentation (e.g., new vs. long-term customers).
When the subscription ended or is scheduled to end. Used for cancel-at-period-end scenarios.
Custom key-value pairs for segmentation. Same as using customerAttributes or customer.metadata.
Subscription status
The status field determines which offers are available. For example, trial extensions only appear for trial subscriptions.
status: {
name: 'active',
currentPeriod: {
start: new Date('2025-01-01'),
end: new Date('2025-02-01'),
},
}
Subscription items
Items represent the products and pricing on a subscription:
items: [
{
id: 'si_basic',
price: {
id: 'price_basic_monthly',
amount: { value: 2999, currency: 'usd' }, // $29.99
interval: 'month',
intervalCount: 1,
},
quantity: 1,
product: {
id: 'prod_basic',
name: 'Basic Plan',
},
},
];
See Direct mode examples for usage-based billing, paused subscriptions, and complex scenarios.
Handlers
Handlers execute billing operations when customers accept offers. Each offer requires its corresponding handler—if you configure a pause offer in the Flow Builder but don't provide handlePause, the offer won't appear.
async handleCancel(customer, surveyChoice, feedback, followupResponse) {
// surveyChoice: Selected cancellation reason (string)
// feedback: Additional text feedback (string | null)
// followupResponse: Follow-up question answers (object | null)
try {
await yourAPI.cancelSubscription(customer.id);
return { message: 'Your subscription has been canceled.' };
} catch (error) {
// Error messages are shown to customers
throw new Error('Unable to cancel. Please contact support.');
}
}
Configuring offers
Configure offers in the Flow Builder. Churnkey automatically shows or hides offers based on:
- Subscription status — Trial extensions only appear for trial subscriptions
- Billing interval — Annual customers won't see pause offers by default
- Handler availability — Offers only appear if you've implemented the handler
You configure offer values (discount percentages, pause durations, etc.) in the Flow Builder, then implement the billing changes in your handlers.
Segmentation
Create targeted flows for different customer segments based on:
- Subscription attributes — Status, billing interval, subscription duration
- Customer metadata — Custom attributes via
customer.metadataandsubscription.metadata - Billing amounts — MRR, subscription value, pricing tier
Configure segments in the Flow Builder under Audience Targeting. Learn more about segmentation →