Merge pull request #26087 from overleaf/mf-change-to-stripe-uk

[web] Configure to use Stripe UK account

GitOrigin-RevId: 0856f6da2caae8caf9887ec2acea8e7f0972e598
This commit is contained in:
Kristina
2025-06-06 11:19:42 +02:00
committed by Copybot
parent 9e9ad3c005
commit a8df91e91b
9 changed files with 60 additions and 49 deletions

View File

@@ -27,21 +27,26 @@ function ensurePlansAreSetupCorrectly() {
}
const recurlyPlanCodeToStripeLookupKey = {
'professional-annual': 'professional_annual',
professional: 'professional_monthly',
professional_free_trial_7_days: 'professional_monthly',
'collaborator-annual': 'standard_annual',
collaborator: 'standard_monthly',
collaborator_free_trial_7_days: 'standard_monthly',
'student-annual': 'student_annual',
student: 'student_monthly',
student_free_trial_7_days: 'student_monthly',
group_professional: 'group_professional_enterprise',
group_professional_educational: 'group_professional_educational',
collaborator: 'collaborator_may2025',
'collaborator-annual': 'collaborator_annual_may2025',
collaborator_free_trial_7_days: 'collaborator_may2025',
professional: 'professional_may2025',
'professional-annual': 'professional_annual_may2025',
professional_free_trial_7_days: 'professional_may2025',
student: 'student_may2025',
'student-annual': 'student_annual_may2025',
student_free_trial_7_days: 'student_may2025',
// TODO: change all group plans' lookup_keys to match the UK account after they have been added
group_collaborator: 'group_standard_enterprise',
group_collaborator_educational: 'group_standard_educational',
'assistant-annual': 'error_assist_annual',
assistant: 'error_assist_monthly',
group_professional: 'group_professional_enterprise',
group_professional_educational: 'group_professional_educational',
assistant: 'assistant_may2025',
'assistant-annual': 'assistant_annual_may2025',
}
/**
@@ -66,10 +71,10 @@ function mapRecurlyAddOnCodeToStripeLookupKey(
// Recurly always uses 'assistant' as the code regardless of the subscription duration
if (recurlyAddOnCode === 'assistant') {
if (billingCycleInterval === 'month') {
return 'error_assist_monthly'
return 'assistant_may2025'
}
if (billingCycleInterval === 'year') {
return 'error_assist_annual'
return 'assistant_annual_may2025'
}
}
return null
@@ -77,21 +82,25 @@ function mapRecurlyAddOnCodeToStripeLookupKey(
const recurlyPlanCodeToPlanTypeAndPeriod = {
collaborator: { planType: 'individual', period: 'monthly' },
collaborator_free_trial_7_days: { planType: 'individual', period: 'monthly' },
'collaborator-annual': { planType: 'individual', period: 'annual' },
collaborator_free_trial_7_days: { planType: 'individual', period: 'monthly' },
professional: { planType: 'individual', period: 'monthly' },
'professional-annual': { planType: 'individual', period: 'annual' },
professional_free_trial_7_days: {
planType: 'individual',
period: 'monthly',
},
'professional-annual': { planType: 'individual', period: 'annual' },
student: { planType: 'student', period: 'monthly' },
student_free_trial_7_days: { planType: 'student', period: 'monthly' },
'student-annual': { planType: 'student', period: 'annual' },
group_professional: { planType: 'group', period: 'annual' },
group_professional_educational: { planType: 'group', period: 'annual' },
student_free_trial_7_days: { planType: 'student', period: 'monthly' },
group_collaborator: { planType: 'group', period: 'annual' },
group_collaborator_educational: { planType: 'group', period: 'annual' },
group_professional: { planType: 'group', period: 'annual' },
group_professional_educational: { planType: 'group', period: 'annual' },
assistant: { planType: null, period: 'monthly' },
'assistant-annual': { planType: null, period: 'annual' },
}

View File

@@ -27,7 +27,7 @@ block append meta
meta(name="ol-user" data-type="json" content=user)
if (personalSubscription && personalSubscription.payment)
meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
meta(name="ol-stripeApiKey" content=settings.apis.stripe.publishableKey)
meta(name="ol-stripeUKApiKey" content=settings.apis.stripeUK.publishableKey)
meta(name="ol-recommendedCurrency" content=personalSubscription.payment.currency)
meta(name="ol-groupPlans" data-type="json" content=groupPlans)

View File

@@ -8,8 +8,9 @@ export default async function handleStripePaymentAction(
const clientSecret = error?.data?.clientSecret
if (clientSecret) {
const stripePublicKey = getMeta('ol-stripeApiKey')
const stripe = await loadStripe(stripePublicKey)
// TODO: support both US and UK Stripe accounts
const stripeUKPublicKey = getMeta('ol-stripeUKApiKey')
const stripe = await loadStripe(stripeUKPublicKey)
if (stripe) {
const manualConfirmationFlow =
await stripe.confirmCardPayment(clientSecret)

View File

@@ -240,8 +240,8 @@ export interface Meta {
'ol-splitTestVariants': { [name: string]: string }
'ol-ssoDisabled': boolean
'ol-ssoErrorMessage': string
'ol-stripeApiKey': string
'ol-stripeCustomerId': string
'ol-stripeUKApiKey': string
'ol-subscription': any // TODO: mixed types, split into two fields
'ol-subscriptionChangePreview': SubscriptionChangePreview
'ol-subscriptionId': string

View File

@@ -55,63 +55,63 @@ describe('PlansLocator', function () {
const planCode = 'collaborator'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('standard_monthly')
expect(lookupKey).to.equal('collaborator_may2025')
})
it('should map "collaborator_free_trial_7_days" plan code to stripe lookup keys', function () {
const planCode = 'collaborator_free_trial_7_days'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('standard_monthly')
expect(lookupKey).to.equal('collaborator_may2025')
})
it('should map "collaborator-annual" plan code to stripe lookup keys', function () {
const planCode = 'collaborator-annual'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('standard_annual')
expect(lookupKey).to.equal('collaborator_annual_may2025')
})
it('should map "professional" plan code to stripe lookup keys', function () {
const planCode = 'professional'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('professional_monthly')
expect(lookupKey).to.equal('professional_may2025')
})
it('should map "professional_free_trial_7_days" plan code to stripe lookup keys', function () {
const planCode = 'professional_free_trial_7_days'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('professional_monthly')
expect(lookupKey).to.equal('professional_may2025')
})
it('should map "professional-annual" plan code to stripe lookup keys', function () {
const planCode = 'professional-annual'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('professional_annual')
expect(lookupKey).to.equal('professional_annual_may2025')
})
it('should map "student" plan code to stripe lookup keys', function () {
const planCode = 'student'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('student_monthly')
expect(lookupKey).to.equal('student_may2025')
})
it('shoult map "student_free_trial_7_days" plan code to stripe lookup keys', function () {
const planCode = 'student_free_trial_7_days'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('student_monthly')
expect(lookupKey).to.equal('student_may2025')
})
it('should map "student-annual" plan code to stripe lookup keys', function () {
const planCode = 'student-annual'
const lookupKey =
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
expect(lookupKey).to.equal('student_annual')
expect(lookupKey).to.equal('student_annual_may2025')
})
})
@@ -141,7 +141,7 @@ describe('PlansLocator', function () {
addOnCode,
billingCycleInterval
)
expect(lookupKey).to.equal('error_assist_monthly')
expect(lookupKey).to.equal('assistant_may2025')
})
it('returns the key for an annual AI assist add-on', function () {
@@ -151,7 +151,7 @@ describe('PlansLocator', function () {
addOnCode,
billingCycleInterval
)
expect(lookupKey).to.equal('error_assist_annual')
expect(lookupKey).to.equal('assistant_annual_may2025')
})
})

View File

@@ -589,7 +589,7 @@ describe('SubscriptionViewModelBuilder', function () {
describe('isEligibleForGroupPlan', function () {
it('is false for Stripe subscriptions', async function () {
this.paymentRecord.service = 'stripe'
this.paymentRecord.service = 'stripe-us'
const result =
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
this.user
@@ -627,7 +627,7 @@ describe('SubscriptionViewModelBuilder', function () {
describe('isEligibleForPause', function () {
it('is false for Stripe subscriptions', async function () {
this.paymentRecord.service = 'stripe'
this.paymentRecord.service = 'stripe-us'
const result =
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
this.user
@@ -777,7 +777,7 @@ describe('SubscriptionViewModelBuilder', function () {
this.paymentRecord.pausePeriodStart = null
this.paymentRecord.remainingPauseCycles = null
this.paymentRecord.trialPeriodEnd = null
this.paymentRecord.service = 'stripe'
this.paymentRecord.service = 'stripe-us'
const result =
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
this.user
@@ -847,7 +847,7 @@ describe('SubscriptionViewModelBuilder', function () {
})
it('does not add a billing details link for a Stripe subscription', async function () {
this.paymentRecord.service = 'stripe'
this.paymentRecord.service = 'stripe-us'
this.Modules.hooks.fire
.withArgs('getPaymentFromRecord', this.individualSubscription)
.yields(null, [

View File

@@ -7,7 +7,7 @@ import { TeamInvite } from '../team-invite'
type RecurlyAdminClientPaymentProvider = Record<string, never>
type StripeAdminClientPaymentProvider = PaymentProvider & {
service: 'stripe'
service: 'stripe-us' | 'stripe-uk'
}
export type Subscription = {

View File

@@ -103,7 +103,7 @@ export type MemberGroupSubscription = Omit<GroupSubscription, 'admin_id'> & {
admin_id: User
}
type PaymentProviderService = 'stripe' | 'recurly'
type PaymentProviderService = 'stripe-us' | 'stripe-uk' | 'recurly'
export type PaymentProvider = {
service: PaymentProviderService

View File

@@ -91,15 +91,16 @@ export type RecurlyPlanCode =
export type RecurlyAddOnCode = 'assistant'
export type StripeLookupKey =
| 'standard_monthly'
| 'standard_annual'
| 'professional_monthly'
| 'professional_annual'
| 'student_monthly'
| 'student_annual'
| 'collaborator_may2025'
| 'collaborator_annual_may2025'
| 'professional_may2025'
| 'professional_annual_may2025'
| 'student_may2025'
| 'student_annual_may2025'
// TODO: change all group plans' lookup_keys to match the UK account after they have been added
| 'group_standard_enterprise'
| 'group_professional_enterprise'
| 'group_standard_educational'
| 'group_professional_educational'
| 'error_assist_annual'
| 'error_assist_monthly'
| 'assistant_annual_may2025'
| 'assistant_may2025'