Files
documenso/packages/lib/jobs/definitions/internal/cancel-organisation-subscription.handler.ts
T
2026-05-13 15:28:27 +10:00

39 lines
1.5 KiB
TypeScript

import { Stripe, stripe } from '../../../server-only/stripe';
import type { JobRunIO } from '../../client/_internal/job';
import type { TCancelOrganisationSubscriptionJobDefinition } from './cancel-organisation-subscription';
/**
* Marks the given Stripe subscription for cancellation at the end of the
* current billing period.
*
* Idempotent: calling this on an already-cancel-at-period-end subscription is
* a no-op for Stripe and returns the same shape, so re-running the job after
* a partial failure is safe.
*
* If the subscription no longer exists in Stripe (`resource_missing`), the
* job treats it as a no-op rather than retrying forever \u2014 nothing further
* can be done.
*/
export const run = async ({ payload }: { payload: TCancelOrganisationSubscriptionJobDefinition; io: JobRunIO }) => {
const { stripeSubscriptionId } = payload;
try {
await stripe.subscriptions.update(stripeSubscriptionId, {
cancel_at_period_end: true,
});
} catch (error) {
// Subscription no longer exists in Stripe \u2014 nothing to cancel. Treat as
// success so the job doesn't retry indefinitely.
if (error instanceof Stripe.errors.StripeInvalidRequestError && error.code === 'resource_missing') {
console.warn(
`[CANCEL_ORGANISATION_SUBSCRIPTION] Stripe subscription ${stripeSubscriptionId} no longer exists; skipping.`,
);
return;
}
// Anything else: rethrow so the job runner retries.
throw error;
}
};