Skip to content

[MKT-748]:feat/implement tracking services for cancelled subscriptions#351

Open
jaaaaavier wants to merge 8 commits intomasterfrom
feat/track-cancelled-users
Open

[MKT-748]:feat/implement tracking services for cancelled subscriptions#351
jaaaaavier wants to merge 8 commits intomasterfrom
feat/track-cancelled-users

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

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

@jaaaaavier
Copy link
Author

Check Sonarcloud and tests, they are failing @jaaaaavier

I think they are falling because we need to add some environment variables

@jaaaaavier jaaaaavier marked this pull request as draft February 16, 2026 13:52
try {
await klaviyoService.trackSubscriptionCancelled(customer.email);
} catch (error) {
Logger.error(`[KLAVIYO] Failed to track cancellation for ${customerId}`, error);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add the error inside the first string, I think it is not printed if it is outside. Or it works?

jest.clearAllMocks();
(config as any).KLAVIYO_API_KEY = mockApiKey;
(config as any).KLAVIYO_BASE_URL = mockBaseUrl;
service = new KlaviyoTrackingService();
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 instantiate the service in the service-factory.

Logger.info(`[Klaviyo] ${eventName} tracked for ${email}`);
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
Logger.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.

Add the error inside the first string, I think it is not printed if it is outside. Or it works?

@sonarqubecloud
Copy link

@jaaaaavier jaaaaavier requested a review from xabg2 February 17, 2026 15:00
import config from '../../../src/config';

jest.mock('axios');
jest.mock('../../../src/Logger');
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the logger can be spied: jest.spyOn(Logger, 'error)`

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

⚠️ This pull request has been marked as stale due to 30 days of inactivity.

It will be automatically closed in 7 days if no further updates are made.

@github-actions github-actions bot added the stale No activity for a while. Needs attention. label Mar 6, 2026
@jaaaaavier jaaaaavier removed the stale No activity for a while. Needs attention. label Mar 13, 2026
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