Manually trigger the widget using JavaScript. To opt out globally, pass cancelOptOut: true to the config:
<script>
StaySignal.init({
siteId: 'YOUR_SITE_ID',
cancelOptOut: true // Opt out of automatic cancellation
});
</script>
Complete Example
<!DOCTYPE html>
<html>
<head>
<title>StaySignal Integration Example</title>
</head>
<body>
{/* Example Button: */}
<button class="staysignal-cancel" data-subscription_id="sub_123456">Cancel Subscription</button>
<!-- Include the StaySignal Widget -->
<script>
const script = document.createElement('script');
script.src = 'https://app.staysignal.com/api/widget/script/YOUR_SITE_ID_HERE';
script.onload = function() {
StaySignal.init({
// site_id is embedded in the script loaded via /api/widget/script/[siteId]
onComplete: (payload) => {
console.log('Widget flow complete:', payload);
if (payload.resolution === 'cancelled') {
alert('Subscription cancelled successfully.');
} else {
alert('Great! You decided to stay with us.');
}
},
onError: (error) => {
console.error('Widget error:', error);
}
}); // Escape backticks in the initLogic string itself
StaySignal.onReady(() => {
console.log('StaySignal Ready!');
// Optional: Add JS click handlers if not using class-based approach
});
};
document.body.appendChild(script);
</script>
</body>
</html>
Error Handling
It's recommended to implement proper error handling:
<script>
// Global error handler for widget loading issues
window.onerror = function(msg, url, line, col, error) {
console.error('Widget error:', { msg, url, line, col, error });
return false;
};
// Widget-specific error handling
StaySignal.init({
// site_id is no longer needed here, it's included in the script URL
onError: (error) => {
console.error('Widget error:', error);
// Handle the error appropriately
}
});
</script>
Testing
To test your integration:
Ensure the widget script loads successfully
Check browser console for any errors
Test both class-based and JavaScript-based cancel buttons
Verify the onComplete callback is triggered
Test error scenarios by providing invalid subscription IDs
Finding Stripe Subscription IDs
Staysignal requires a subscription_id to identify which subscription a user is trying to cancel. Here are ways to find and use a user's Stripe subscription ID:
From Your Database
Most applications store subscription IDs in their database after a successful Stripe subscription creation. This is the recommended approach for performance and reliability.
<script>
// Example using Node.js with Express and MongoDB
app.get('/account', async (req, res) => {
try {
// Get user ID from session/JWT
const userId = req.user.id;
// Fetch subscription from your database
const user = await User.findById(userId).populate('subscription');
const subscriptionId = user.subscription?.stripeSubscriptionId;
res.render('account', {
user,
subscriptionId // Pass to your view
});
} catch (error) {
console.error('Error fetching subscription:', error);
res.status(500).send('Server error');
}
});
</script>
<?php
// Example using PHP with Laravel
public function showAccount()
{
$user = Auth::user();
$subscription = $user->subscription; // Assuming relationship is set up
$subscriptionId = $subscription ? $subscription->stripe_subscription_id : null;
return view('account', [
'user' => $user,
'subscriptionId' => $subscriptionId
]);
}
# Example using Ruby on Rails
class AccountController < ApplicationController
def show
@user = current_user
@subscription = @user.subscription
@subscription_id = @subscription&.stripe_subscription_id
end
end
# In your view: account.html.erb
<button class="staysignal-cancel" data-subscription_id="<%= @subscription_id %>">
Cancel Subscription
</button>
# Example using Django
def account_view(request):
user = request.user
subscription = Subscription.objects.filter(user=user).first()
subscription_id = subscription.stripe_subscription_id if subscription else None
return render(request, 'account.html', {
'user': user,
'subscription_id': subscription_id
})
Fetching from Stripe API
If you need to fetch the subscription ID directly from Stripe (not recommended for production):
<script>
// Using Stripe Node.js SDK
const stripe = require('stripe')('sk_test_your_stripe_secret_key');
async function getCustomerSubscriptions(customerId) {
try {
const subscriptions = await stripe.subscriptions.list({
customer: customerId,
status: 'active',
limit: 1
});
if (subscriptions.data.length > 0) {
return subscriptions.data[0].id; // Returns the subscription ID
}
return null;
} catch (error) {
console.error('Error fetching from Stripe:', error);
throw error;
}
}
</script>