This commit is contained in:
 Илья Шалонин 2025-10-29 13:43:43 +05:00
commit 8538ab969a
434 changed files with 44051 additions and 0 deletions

View file

@ -0,0 +1,36 @@
import {
getOrganizationById,
getUserById,
updateOrganization,
updateUser,
} from "@repo/database";
export async function setCustomerIdToEntity(
customerId: string,
{ organizationId, userId }: { organizationId?: string; userId?: string },
) {
if (organizationId) {
await updateOrganization({
id: organizationId,
paymentsCustomerId: customerId,
});
} else if (userId) {
await updateUser({
id: userId,
paymentsCustomerId: customerId,
});
}
}
export const getCustomerIdFromEntity = async (
props: { organizationId: string } | { userId: string },
) => {
if ("organizationId" in props) {
return (
(await getOrganizationById(props.organizationId))
?.paymentsCustomerId ?? null
);
}
return (await getUserById(props.userId))?.paymentsCustomerId ?? null;
};

View file

@ -0,0 +1,85 @@
import { type Config, config } from "@repo/config";
import type { Purchase } from "@repo/database";
const plans = config.payments.plans as Config["payments"]["plans"];
type PlanId = keyof typeof config.payments.plans;
type PurchaseWithoutTimestamps = Omit<Purchase, "createdAt" | "updatedAt">;
function getActivePlanFromPurchases(purchases?: PurchaseWithoutTimestamps[]) {
const subscriptionPurchase = purchases?.find(
(purchase) => purchase.type === "SUBSCRIPTION",
);
if (subscriptionPurchase) {
const plan = Object.entries(plans).find(([_, plan]) =>
plan.prices?.some(
(price) => price.productId === subscriptionPurchase.productId,
),
);
return {
id: plan?.[0] as PlanId,
price: plan?.[1].prices?.find(
(price) => price.productId === subscriptionPurchase.productId,
),
status: subscriptionPurchase.status,
purchaseId: subscriptionPurchase.id,
};
}
const oneTimePurchase = purchases?.find(
(purchase) => purchase.type === "ONE_TIME",
);
if (oneTimePurchase) {
const plan = Object.entries(plans).find(([_, plan]) =>
plan.prices?.some(
(price) => price.productId === oneTimePurchase.productId,
),
);
return {
id: plan?.[0] as PlanId,
price: plan?.[1].prices?.find(
(price) => price.productId === oneTimePurchase.productId,
),
status: "active",
purchaseId: oneTimePurchase.id,
};
}
const freePlan = Object.entries(plans).find(([_, plan]) => plan.isFree);
return freePlan
? {
id: freePlan[0] as PlanId,
status: "active",
}
: null;
}
export function createPurchasesHelper(purchases: PurchaseWithoutTimestamps[]) {
const activePlan = getActivePlanFromPurchases(purchases);
const hasSubscription = (planIds?: PlanId[] | PlanId) => {
return (
!!activePlan &&
(Array.isArray(planIds)
? planIds.includes(activePlan.id)
: planIds === activePlan.id)
);
};
const hasPurchase = (planId: PlanId) => {
return !!purchases?.some((purchase) =>
Object.entries(plans)
.find(([id]) => id === planId)?.[1]
.prices?.some(
(price) => price.productId === purchase.productId,
),
);
};
return { activePlan, hasSubscription, hasPurchase };
}