Skip to content

Conversation

@jaaaaavier
Copy link

@jaaaaavier jaaaaavier commented Feb 11, 2026

This task, which is linked to additional PRs in other repositories, aims to track users who cancel their plans and send that data to Klaviyo. While Klaviyo already integrates with Stripe, it lacks this specific functionality, which is why we created this solution.

Changes:

  • Created the klaviyo.service that sends the email of the user that cancels the subscription.
  • Added the service on the handleSubscription

Comment

Need to add two Environment variables

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
80.0% Coverage on New Code (required ≥ 85%)
E Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Copy link
Collaborator

@xabg2 xabg2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the tests for this new klaviyo service.

},
});

console.log(`[Klaviyo] ${eventName} tracked for ${email}`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Logger instead

console.log(`[Klaviyo] ${eventName} tracked for ${email}`);
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
console.error(`[Klaviyo] ${eventName} failed for ${email}:`, message);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Logger instead

try {
await klaviyoService.trackSubscriptionCancelled(customer.email);
} catch (error) {
log.error(`[KLAVIYO] Failed to track cancellation for ${customerId}`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log the error here also, and it would be nice to use Logger we can remove log in the future.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Export the class here directly, e.g.: const klaviyoService = new KlaviyoService(); so you can export it directly without instantiating it every time (you can use the api key directly).

baseUrl: string | undefined = process.env.KLAVIYO_BASE_URL
) {
if (!apiKey) {
throw new Error("Klaviyo API Key is required.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use throw new BadRequestError('...') instead.

}

export class KlaviyoTrackingService {
private readonly apiKey: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can assign here directly the variables if you want, no need to pass it as props. Also, use config file instead of process.env.

async trackSubscriptionCancelled(email: string): Promise<void> {
await this.trackEvent({
email,
eventName: 'Subscription Cancelled',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you can extract this to an enum so you can do:
TRACK_ENENTS.SubscriptionCancelled or smth like that.

@xabg2
Copy link
Collaborator

xabg2 commented Feb 11, 2026

Check Sonarcloud and tests, they are failing @jaaaaavier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ready-for-preview

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants