mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 14:43:46 +01:00
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:
@@ -27,21 +27,26 @@ function ensurePlansAreSetupCorrectly() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const recurlyPlanCodeToStripeLookupKey = {
|
const recurlyPlanCodeToStripeLookupKey = {
|
||||||
'professional-annual': 'professional_annual',
|
collaborator: 'collaborator_may2025',
|
||||||
professional: 'professional_monthly',
|
'collaborator-annual': 'collaborator_annual_may2025',
|
||||||
professional_free_trial_7_days: 'professional_monthly',
|
collaborator_free_trial_7_days: 'collaborator_may2025',
|
||||||
'collaborator-annual': 'standard_annual',
|
|
||||||
collaborator: 'standard_monthly',
|
professional: 'professional_may2025',
|
||||||
collaborator_free_trial_7_days: 'standard_monthly',
|
'professional-annual': 'professional_annual_may2025',
|
||||||
'student-annual': 'student_annual',
|
professional_free_trial_7_days: 'professional_may2025',
|
||||||
student: 'student_monthly',
|
|
||||||
student_free_trial_7_days: 'student_monthly',
|
student: 'student_may2025',
|
||||||
group_professional: 'group_professional_enterprise',
|
'student-annual': 'student_annual_may2025',
|
||||||
group_professional_educational: 'group_professional_educational',
|
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: 'group_standard_enterprise',
|
||||||
group_collaborator_educational: 'group_standard_educational',
|
group_collaborator_educational: 'group_standard_educational',
|
||||||
'assistant-annual': 'error_assist_annual',
|
group_professional: 'group_professional_enterprise',
|
||||||
assistant: 'error_assist_monthly',
|
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
|
// Recurly always uses 'assistant' as the code regardless of the subscription duration
|
||||||
if (recurlyAddOnCode === 'assistant') {
|
if (recurlyAddOnCode === 'assistant') {
|
||||||
if (billingCycleInterval === 'month') {
|
if (billingCycleInterval === 'month') {
|
||||||
return 'error_assist_monthly'
|
return 'assistant_may2025'
|
||||||
}
|
}
|
||||||
if (billingCycleInterval === 'year') {
|
if (billingCycleInterval === 'year') {
|
||||||
return 'error_assist_annual'
|
return 'assistant_annual_may2025'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@@ -77,21 +82,25 @@ function mapRecurlyAddOnCodeToStripeLookupKey(
|
|||||||
|
|
||||||
const recurlyPlanCodeToPlanTypeAndPeriod = {
|
const recurlyPlanCodeToPlanTypeAndPeriod = {
|
||||||
collaborator: { planType: 'individual', period: 'monthly' },
|
collaborator: { planType: 'individual', period: 'monthly' },
|
||||||
collaborator_free_trial_7_days: { planType: 'individual', period: 'monthly' },
|
|
||||||
'collaborator-annual': { planType: 'individual', period: 'annual' },
|
'collaborator-annual': { planType: 'individual', period: 'annual' },
|
||||||
|
collaborator_free_trial_7_days: { planType: 'individual', period: 'monthly' },
|
||||||
|
|
||||||
professional: { planType: 'individual', period: 'monthly' },
|
professional: { planType: 'individual', period: 'monthly' },
|
||||||
|
'professional-annual': { planType: 'individual', period: 'annual' },
|
||||||
professional_free_trial_7_days: {
|
professional_free_trial_7_days: {
|
||||||
planType: 'individual',
|
planType: 'individual',
|
||||||
period: 'monthly',
|
period: 'monthly',
|
||||||
},
|
},
|
||||||
'professional-annual': { planType: 'individual', period: 'annual' },
|
|
||||||
student: { planType: 'student', period: 'monthly' },
|
student: { planType: 'student', period: 'monthly' },
|
||||||
student_free_trial_7_days: { planType: 'student', period: 'monthly' },
|
|
||||||
'student-annual': { planType: 'student', period: 'annual' },
|
'student-annual': { planType: 'student', period: 'annual' },
|
||||||
group_professional: { planType: 'group', period: 'annual' },
|
student_free_trial_7_days: { planType: 'student', period: 'monthly' },
|
||||||
group_professional_educational: { planType: 'group', period: 'annual' },
|
|
||||||
group_collaborator: { planType: 'group', period: 'annual' },
|
group_collaborator: { planType: 'group', period: 'annual' },
|
||||||
group_collaborator_educational: { 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: { planType: null, period: 'monthly' },
|
||||||
'assistant-annual': { planType: null, period: 'annual' },
|
'assistant-annual': { planType: null, period: 'annual' },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ block append meta
|
|||||||
meta(name="ol-user" data-type="json" content=user)
|
meta(name="ol-user" data-type="json" content=user)
|
||||||
if (personalSubscription && personalSubscription.payment)
|
if (personalSubscription && personalSubscription.payment)
|
||||||
meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
|
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-recommendedCurrency" content=personalSubscription.payment.currency)
|
||||||
meta(name="ol-groupPlans" data-type="json" content=groupPlans)
|
meta(name="ol-groupPlans" data-type="json" content=groupPlans)
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ export default async function handleStripePaymentAction(
|
|||||||
const clientSecret = error?.data?.clientSecret
|
const clientSecret = error?.data?.clientSecret
|
||||||
|
|
||||||
if (clientSecret) {
|
if (clientSecret) {
|
||||||
const stripePublicKey = getMeta('ol-stripeApiKey')
|
// TODO: support both US and UK Stripe accounts
|
||||||
const stripe = await loadStripe(stripePublicKey)
|
const stripeUKPublicKey = getMeta('ol-stripeUKApiKey')
|
||||||
|
const stripe = await loadStripe(stripeUKPublicKey)
|
||||||
if (stripe) {
|
if (stripe) {
|
||||||
const manualConfirmationFlow =
|
const manualConfirmationFlow =
|
||||||
await stripe.confirmCardPayment(clientSecret)
|
await stripe.confirmCardPayment(clientSecret)
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ export interface Meta {
|
|||||||
'ol-splitTestVariants': { [name: string]: string }
|
'ol-splitTestVariants': { [name: string]: string }
|
||||||
'ol-ssoDisabled': boolean
|
'ol-ssoDisabled': boolean
|
||||||
'ol-ssoErrorMessage': string
|
'ol-ssoErrorMessage': string
|
||||||
'ol-stripeApiKey': string
|
|
||||||
'ol-stripeCustomerId': string
|
'ol-stripeCustomerId': string
|
||||||
|
'ol-stripeUKApiKey': string
|
||||||
'ol-subscription': any // TODO: mixed types, split into two fields
|
'ol-subscription': any // TODO: mixed types, split into two fields
|
||||||
'ol-subscriptionChangePreview': SubscriptionChangePreview
|
'ol-subscriptionChangePreview': SubscriptionChangePreview
|
||||||
'ol-subscriptionId': string
|
'ol-subscriptionId': string
|
||||||
|
|||||||
@@ -55,63 +55,63 @@ describe('PlansLocator', function () {
|
|||||||
const planCode = 'collaborator'
|
const planCode = 'collaborator'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "collaborator_free_trial_7_days" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'collaborator_free_trial_7_days'
|
const planCode = 'collaborator_free_trial_7_days'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "collaborator-annual" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'collaborator-annual'
|
const planCode = 'collaborator-annual'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "professional" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'professional'
|
const planCode = 'professional'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "professional_free_trial_7_days" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'professional_free_trial_7_days'
|
const planCode = 'professional_free_trial_7_days'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "professional-annual" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'professional-annual'
|
const planCode = 'professional-annual'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "student" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'student'
|
const planCode = 'student'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('shoult map "student_free_trial_7_days" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'student_free_trial_7_days'
|
const planCode = 'student_free_trial_7_days'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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 () {
|
it('should map "student-annual" plan code to stripe lookup keys', function () {
|
||||||
const planCode = 'student-annual'
|
const planCode = 'student-annual'
|
||||||
const lookupKey =
|
const lookupKey =
|
||||||
this.PlansLocator.mapRecurlyPlanCodeToStripeLookupKey(planCode)
|
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,
|
addOnCode,
|
||||||
billingCycleInterval
|
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 () {
|
it('returns the key for an annual AI assist add-on', function () {
|
||||||
@@ -151,7 +151,7 @@ describe('PlansLocator', function () {
|
|||||||
addOnCode,
|
addOnCode,
|
||||||
billingCycleInterval
|
billingCycleInterval
|
||||||
)
|
)
|
||||||
expect(lookupKey).to.equal('error_assist_annual')
|
expect(lookupKey).to.equal('assistant_annual_may2025')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -589,7 +589,7 @@ describe('SubscriptionViewModelBuilder', function () {
|
|||||||
|
|
||||||
describe('isEligibleForGroupPlan', function () {
|
describe('isEligibleForGroupPlan', function () {
|
||||||
it('is false for Stripe subscriptions', async function () {
|
it('is false for Stripe subscriptions', async function () {
|
||||||
this.paymentRecord.service = 'stripe'
|
this.paymentRecord.service = 'stripe-us'
|
||||||
const result =
|
const result =
|
||||||
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
||||||
this.user
|
this.user
|
||||||
@@ -627,7 +627,7 @@ describe('SubscriptionViewModelBuilder', function () {
|
|||||||
|
|
||||||
describe('isEligibleForPause', function () {
|
describe('isEligibleForPause', function () {
|
||||||
it('is false for Stripe subscriptions', async function () {
|
it('is false for Stripe subscriptions', async function () {
|
||||||
this.paymentRecord.service = 'stripe'
|
this.paymentRecord.service = 'stripe-us'
|
||||||
const result =
|
const result =
|
||||||
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
||||||
this.user
|
this.user
|
||||||
@@ -777,7 +777,7 @@ describe('SubscriptionViewModelBuilder', function () {
|
|||||||
this.paymentRecord.pausePeriodStart = null
|
this.paymentRecord.pausePeriodStart = null
|
||||||
this.paymentRecord.remainingPauseCycles = null
|
this.paymentRecord.remainingPauseCycles = null
|
||||||
this.paymentRecord.trialPeriodEnd = null
|
this.paymentRecord.trialPeriodEnd = null
|
||||||
this.paymentRecord.service = 'stripe'
|
this.paymentRecord.service = 'stripe-us'
|
||||||
const result =
|
const result =
|
||||||
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
await this.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
|
||||||
this.user
|
this.user
|
||||||
@@ -847,7 +847,7 @@ describe('SubscriptionViewModelBuilder', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('does not add a billing details link for a Stripe subscription', async 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
|
this.Modules.hooks.fire
|
||||||
.withArgs('getPaymentFromRecord', this.individualSubscription)
|
.withArgs('getPaymentFromRecord', this.individualSubscription)
|
||||||
.yields(null, [
|
.yields(null, [
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { TeamInvite } from '../team-invite'
|
|||||||
|
|
||||||
type RecurlyAdminClientPaymentProvider = Record<string, never>
|
type RecurlyAdminClientPaymentProvider = Record<string, never>
|
||||||
type StripeAdminClientPaymentProvider = PaymentProvider & {
|
type StripeAdminClientPaymentProvider = PaymentProvider & {
|
||||||
service: 'stripe'
|
service: 'stripe-us' | 'stripe-uk'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Subscription = {
|
export type Subscription = {
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export type MemberGroupSubscription = Omit<GroupSubscription, 'admin_id'> & {
|
|||||||
admin_id: User
|
admin_id: User
|
||||||
}
|
}
|
||||||
|
|
||||||
type PaymentProviderService = 'stripe' | 'recurly'
|
type PaymentProviderService = 'stripe-us' | 'stripe-uk' | 'recurly'
|
||||||
|
|
||||||
export type PaymentProvider = {
|
export type PaymentProvider = {
|
||||||
service: PaymentProviderService
|
service: PaymentProviderService
|
||||||
|
|||||||
@@ -91,15 +91,16 @@ export type RecurlyPlanCode =
|
|||||||
export type RecurlyAddOnCode = 'assistant'
|
export type RecurlyAddOnCode = 'assistant'
|
||||||
|
|
||||||
export type StripeLookupKey =
|
export type StripeLookupKey =
|
||||||
| 'standard_monthly'
|
| 'collaborator_may2025'
|
||||||
| 'standard_annual'
|
| 'collaborator_annual_may2025'
|
||||||
| 'professional_monthly'
|
| 'professional_may2025'
|
||||||
| 'professional_annual'
|
| 'professional_annual_may2025'
|
||||||
| 'student_monthly'
|
| 'student_may2025'
|
||||||
| 'student_annual'
|
| 'student_annual_may2025'
|
||||||
|
// TODO: change all group plans' lookup_keys to match the UK account after they have been added
|
||||||
| 'group_standard_enterprise'
|
| 'group_standard_enterprise'
|
||||||
| 'group_professional_enterprise'
|
| 'group_professional_enterprise'
|
||||||
| 'group_standard_educational'
|
| 'group_standard_educational'
|
||||||
| 'group_professional_educational'
|
| 'group_professional_educational'
|
||||||
| 'error_assist_annual'
|
| 'assistant_annual_may2025'
|
||||||
| 'error_assist_monthly'
|
| 'assistant_may2025'
|
||||||
|
|||||||
Reference in New Issue
Block a user