61ca128ce2
* feat(gatekeeper): support multiple currencies * feat(helm): add new currency based prices to helm chart * chore(env): add example currency based pricing values * fix(ci): update price ids to the proper values * feat(helm): rename price ids to fit multi currency * feat(gatekeeper): currency input for checkout session * Updated prices in the FE * chore(gatekeeper): remove old checkout session flow * Updated prices in the FE * Fix FE * Fix pipeline --------- Co-authored-by: Mike Tasset <mike.tasset@gmail.com>
143 lines
4.8 KiB
TypeScript
143 lines
4.8 KiB
TypeScript
import {
|
|
Currency,
|
|
GetWorkspacePlanPriceId,
|
|
GetWorkspacePlanProductAndPriceIds,
|
|
GetWorkspacePlanProductId,
|
|
isMultiCurrencyPrice
|
|
} from '@/modules/gatekeeper/domain/billing'
|
|
import { getStringFromEnv, getStripeApiKey } from '@/modules/shared/helpers/envHelper'
|
|
import { PriceLookupError } from '@/modules/gatekeeper/errors/billing'
|
|
import { Stripe } from 'stripe'
|
|
import { NotImplementedError } from '@/modules/shared/errors'
|
|
|
|
let stripeClient: Stripe | undefined = undefined
|
|
|
|
export const getStripeClient = () => {
|
|
if (!stripeClient) stripeClient = new Stripe(getStripeApiKey(), { typescript: true })
|
|
return stripeClient
|
|
}
|
|
|
|
const loadProductAndPriceIds: GetWorkspacePlanProductAndPriceIds = () => ({
|
|
// old
|
|
guest: {
|
|
productId: getStringFromEnv('WORKSPACE_GUEST_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_GUEST_SEAT_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_GUEST_SEAT_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
starter: {
|
|
productId: getStringFromEnv('WORKSPACE_STARTER_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_STARTER_SEAT_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_STARTER_SEAT_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
plus: {
|
|
productId: getStringFromEnv('WORKSPACE_PLUS_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_PLUS_SEAT_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_PLUS_SEAT_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
business: {
|
|
productId: getStringFromEnv('WORKSPACE_BUSINESS_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_BUSINESS_SEAT_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_BUSINESS_SEAT_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
team: {
|
|
productId: getStringFromEnv('WORKSPACE_TEAM_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_TEAM_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_MONTHLY_TEAM_SEAT_USD_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_TEAM_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_YEARLY_TEAM_SEAT_USD_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
teamUnlimited: {
|
|
productId: getStringFromEnv('WORKSPACE_TEAM_UNLIMITED_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv(
|
|
'WORKSPACE_MONTHLY_TEAM_UNLIMITED_SEAT_GBP_STRIPE_PRICE_ID'
|
|
),
|
|
usd: getStringFromEnv('WORKSPACE_MONTHLY_TEAM_UNLIMITED_SEAT_USD_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_TEAM_UNLIMITED_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_YEARLY_TEAM_UNLIMITED_SEAT_USD_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
pro: {
|
|
productId: getStringFromEnv('WORKSPACE_PRO_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_PRO_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_MONTHLY_PRO_SEAT_USD_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_PRO_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_YEARLY_PRO_SEAT_USD_STRIPE_PRICE_ID')
|
|
}
|
|
},
|
|
proUnlimited: {
|
|
productId: getStringFromEnv('WORKSPACE_PRO_UNLIMITED_SEAT_STRIPE_PRODUCT_ID'),
|
|
monthly: {
|
|
gbp: getStringFromEnv('WORKSPACE_MONTHLY_PRO_UNLIMITED_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_MONTHLY_PRO_UNLIMITED_SEAT_USD_STRIPE_PRICE_ID')
|
|
},
|
|
yearly: {
|
|
gbp: getStringFromEnv('WORKSPACE_YEARLY_PRO_UNLIMITED_SEAT_GBP_STRIPE_PRICE_ID'),
|
|
usd: getStringFromEnv('WORKSPACE_YEARLY_PRO_UNLIMITED_SEAT_USD_STRIPE_PRICE_ID')
|
|
}
|
|
}
|
|
})
|
|
|
|
let priceIds: ReturnType<typeof getWorkspacePlanProductAndPriceIds> | null = null
|
|
|
|
export const getWorkspacePlanProductAndPriceIds: GetWorkspacePlanProductAndPriceIds =
|
|
() => {
|
|
if (!priceIds) priceIds = loadProductAndPriceIds()
|
|
return priceIds
|
|
}
|
|
|
|
export const getWorkspacePlanPriceId: GetWorkspacePlanPriceId = ({
|
|
workspacePlan,
|
|
billingInterval,
|
|
currency
|
|
}) => {
|
|
const plan = getWorkspacePlanProductAndPriceIds()[workspacePlan]
|
|
const priceIds = plan[billingInterval]
|
|
if (!isMultiCurrencyPrice(priceIds)) {
|
|
if (currency !== Currency.gbp)
|
|
throw new PriceLookupError(
|
|
`Plan '${workspacePlan}' does not have a ${billingInterval} price for currency ${currency}`
|
|
)
|
|
return priceIds[currency]
|
|
}
|
|
return priceIds[currency]
|
|
}
|
|
|
|
export const getWorkspacePlanProductId: GetWorkspacePlanProductId = ({
|
|
workspacePlan
|
|
}) => {
|
|
const planMetadata = getWorkspacePlanProductAndPriceIds()[workspacePlan]
|
|
if (!planMetadata) {
|
|
throw new NotImplementedError(`Plan {workspacePlan} not supported`, {
|
|
info: { workspacePlan }
|
|
})
|
|
}
|
|
|
|
return planMetadata.productId
|
|
}
|