mirror of
https://github.com/documenso/documenso.git
synced 2026-08-24 23:32:29 +10:00
fix: update stripe team member billing (#2991)
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
import {
|
||||
assertMemberCountWithinCap,
|
||||
syncMemberCountWithStripeSeatPlan,
|
||||
} from '@documenso/ee/server-only/stripe/update-subscription-item-quantity';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { OrganisationGroup, OrganisationMemberRole } from '@prisma/client';
|
||||
import { OrganisationGroupType, OrganisationMemberInviteStatus } from '@prisma/client';
|
||||
import { OrganisationGroupType, OrganisationMemberInviteStatus, SubscriptionStatus } from '@prisma/client';
|
||||
|
||||
import { IS_BILLING_ENABLED } from '../../constants/app';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { jobs } from '../../jobs/client';
|
||||
import { generateDatabaseId } from '../../universal/id';
|
||||
@@ -22,6 +27,13 @@ export const acceptOrganisationInvitation = async ({ token }: AcceptOrganisation
|
||||
organisation: {
|
||||
include: {
|
||||
groups: true,
|
||||
organisationClaim: true,
|
||||
subscription: true,
|
||||
members: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -66,6 +78,35 @@ export const acceptOrganisationInvitation = async ({ token }: AcceptOrganisation
|
||||
return;
|
||||
}
|
||||
|
||||
const newMemberCount = organisation.members.length + 1;
|
||||
|
||||
// Billing occurs when a user accepts an invite.
|
||||
// Assert that the new member count is within the cap and sync the seat plan with Stripe.
|
||||
if (IS_BILLING_ENABLED()) {
|
||||
const { subscription, organisationClaim } = organisation;
|
||||
|
||||
// A canceled subscription cannot have its seat quantity updated in Stripe,
|
||||
// and an organisation with lapsed billing should not gain new members.
|
||||
// Throw a deliberate error so the invite page can render an accurate
|
||||
// message instead of an opaque Stripe failure.
|
||||
if (subscription && subscription.status === SubscriptionStatus.INACTIVE) {
|
||||
throw new AppError('SUBSCRIPTION_INACTIVE', {
|
||||
message: 'The organisation subscription is inactive',
|
||||
});
|
||||
}
|
||||
|
||||
// Organisations can exist without a subscription (e.g. after being
|
||||
// downgraded to the free plan). The claim cap remains authoritative in
|
||||
// that case, surfacing LIMIT_EXCEEDED instead of an opaque "subscription
|
||||
// not found" error.
|
||||
await assertMemberCountWithinCap(subscription, organisationClaim, newMemberCount);
|
||||
|
||||
if (subscription) {
|
||||
await syncMemberCountWithStripeSeatPlan(subscription, organisationClaim, newMemberCount, 'grow');
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Logging
|
||||
await addUserToOrganisation({
|
||||
userId: user.id,
|
||||
organisationId: organisation.id,
|
||||
|
||||
Reference in New Issue
Block a user