Files
cfw-autumn/server/src/internal/billing/v2/actions/attach/setup/setupAttachCheckoutMode.ts
2026-05-05 12:29:16 +01:00

86 lines
2.1 KiB
TypeScript

import type { CheckoutMode, InvoiceMode, TrialContext } from "@autumn/shared";
import {
type FullCusProduct,
type FullProduct,
isFreeProduct,
isOneOffProduct,
type RedirectMode,
} from "@autumn/shared";
import type Stripe from "stripe";
/**
* Determines the checkout mode for attach operations.
*
*/
export const setupAttachCheckoutMode = ({
paymentMethod,
redirectMode,
attachProduct,
currentCustomerProduct,
stripeSubscription,
trialContext,
invoiceMode,
hasFutureStartDate,
}: {
paymentMethod?: Stripe.PaymentMethod;
currentCustomerProduct?: FullCusProduct;
redirectMode?: RedirectMode;
attachProduct: FullProduct;
stripeSubscription?: Stripe.Subscription;
trialContext?: TrialContext;
invoiceMode?: InvoiceMode;
hasFutureStartDate?: boolean;
}): CheckoutMode => {
const hasPaymentMethod = !!paymentMethod;
const hasExistingSubscription = !!stripeSubscription;
const prices = attachProduct.prices;
const productIsOneOff = isOneOffProduct({ prices });
const productIsFree = isFreeProduct({ prices });
const productIsPaidRecurring = !productIsOneOff && !productIsFree;
if (redirectMode === "never") {
return null;
}
if (invoiceMode) {
return null;
}
const getStripeCheckoutOrDirectBilling = () => {
// A. if no payment method
if (hasPaymentMethod) return null;
if (productIsOneOff) return "stripe_checkout";
if (!hasExistingSubscription && productIsPaidRecurring) {
// If trial no card required, direct billing
if (trialContext?.trialEndsAt && trialContext?.cardRequired === false) {
return null;
}
return "stripe_checkout";
}
return null;
};
const checkoutMode = getStripeCheckoutOrDirectBilling();
if (hasFutureStartDate && !hasPaymentMethod) {
return "stripe_checkout";
}
if (checkoutMode === null && redirectMode === "always") {
// 1. If it's one off product, return stripe_checkout
if (productIsOneOff) return "stripe_checkout";
// 2. If it's paid recurring and no subscription, return autumn_checkout
if (productIsPaidRecurring && !hasExistingSubscription) {
return "stripe_checkout";
}
return "autumn_checkout";
}
return checkoutMode;
};