Files
calendar/packages/features/ee/billing/organizations/internal-organization-billing.ts
837349e3d3 feat: Organization onboarding improvement - Payment before creation of org but onboarding doesn't require payment (#18990)
* create seed for org upgrade

* migrate about/new pages

* pages refactor + use persistant zustand store

* invited members view + confirm button

* add check to org slug

* check reserved subdomain

* remove quotes from subdomain env var

* intro to creation + billing

* create price

* fix types

* createWithPaymentIntent + permission check on teams

* open stripe link in popup

* intro to tests

* organization price and seat override tests

* move permissions to a new permission service

* update env and permission check

* intro to paid invoice trigger

* dont use subId

* wip

* Get e2e working with migration of teams and members

* fix ts errors

* Get flow working again

* Fix various issues and refactor

* Some more fixes

* Fix wrong page route link

* Platform onboarding fix and moving members of team to org rix

* Platform onboarding fix and moving members of team to org rix

* Fix tests, found a bug

* Get custom price flow working

* Get admin impersonation flow working for a non-existent user

* Fix unit test

* Admin onboarding handover

* fix admin onboarding tests

* fix ts error

* Get updateQuantity working

* More fixes

* fix test

* fix schema name

* Add tests

* Add missing file

* More tests

* Add more tests

* fix mt-2 moving down input into overflow

* fix handover layout removing HOC

* Update PR_TODO.md

* fix ts error due to merge conflict

---------

Co-authored-by: Hariom Balhara <[email protected]>
Co-authored-by: Hariom <[email protected]>
Co-authored-by: Omar López <[email protected]>
2025-03-13 11:17:43 +00:00

57 lines
1.6 KiB
TypeScript

import { stripe } from "@calcom/features/ee/payments/server/stripe";
import { OrganizationBilling } from "./organization-billing";
import { OrganizationBillingRepository } from "./organization-billing.repository";
export class InternalOrganizationBilling extends OrganizationBilling {
constructor(
organization: Parameters<typeof OrganizationBilling>[0],
repository: OrganizationBillingRepository = new OrganizationBillingRepository()
) {
super(organization);
this.repository = repository;
}
async getStripeCustomerId() {
return this.repository.getStripeCustomerId(this.organization.id);
}
async getSubscriptionId() {
return this.repository.getSubscriptionId(this.organization.id);
}
async getSubscriptionItems() {
const subscriptionId = await this.getSubscriptionId();
if (!subscriptionId) return [];
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
return subscription.items.data.map((item) => ({
id: item.id,
quantity: item.quantity ?? 0,
}));
}
async createPaymentIntent({ seats, pricePerSeat }: { seats: number; pricePerSeat: number }) {
const stripeCustomerId = await this.getStripeCustomerId();
if (!stripeCustomerId) {
throw new Error("No stripe customer id found");
}
const amount = seats * pricePerSeat;
return stripe.paymentIntents.create({
amount,
currency: "usd",
customer: stripeCustomerId,
automatic_payment_methods: {
enabled: true,
},
metadata: {
organizationId: this.organization.id,
seats,
pricePerSeat,
},
});
}
}