Merge pull request #28270 from overleaf/kh-add-stripe-payment-context

[web] add stripe payment context

GitOrigin-RevId: 79dfbb1da0dd6b1d36c68c86debffc1edb169961
This commit is contained in:
Kristina
2025-09-16 09:56:38 +02:00
committed by Copybot
parent 7b3c2b838d
commit c79cc52fcf
7 changed files with 68 additions and 16 deletions

15
package-lock.json generated
View File

@@ -11605,6 +11605,20 @@
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
}
},
"node_modules/@stripe/react-stripe-js": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-3.9.0.tgz",
"integrity": "sha512-pN1Re7zUc3m61FFQROok685g3zsBQRzCmZDmTzO8iPU6zhLvu2JnC0LrG0FCzSp6kgGa8AQSzq4rpFSgyhkjKg==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.7.2"
},
"peerDependencies": {
"@stripe/stripe-js": ">=1.44.1 <8.0.0",
"react": ">=16.8.0 <20.0.0",
"react-dom": ">=16.8.0 <20.0.0"
}
},
"node_modules/@stripe/stripe-js": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-7.7.0.tgz",
@@ -44655,6 +44669,7 @@
"@overleaf/stream-utils": "*",
"@phosphor-icons/react": "^2.1.7",
"@slack/webhook": "^7.0.2",
"@stripe/react-stripe-js": "^3.9.0",
"@stripe/stripe-js": "^7.7.0",
"@xmldom/xmldom": "^0.7.13",
"accepts": "^1.3.7",

View File

@@ -26,3 +26,19 @@ export function formatCurrency(
return `${currency} ${amount}`
}
export function convertToMinorUnits(amount: number, currency: string): number {
const isNoCentsCurrency = ['clp', 'jpy', 'krw', 'vnd'].includes(
currency.toLowerCase()
)
// Determine the multiplier based on currency
let multiplier = 100 // default for most currencies (2 decimal places)
if (isNoCentsCurrency) {
multiplier = 1 // no decimal places
}
// Convert and round to an integer
return Math.round(amount * multiplier)
}

View File

@@ -57,6 +57,7 @@ import { Subscription as ProjectDashboardSubscription } from '../../../types/pro
import { ThirdPartyIds } from '../../../types/third-party-ids'
import { Publisher } from '../../../types/subscription/dashboard/publisher'
import { SubscriptionChangePreview } from '../../../types/subscription/subscription-change-preview'
import { SubscriptionCreationPreview } from '../../../types/subscription/subscription-creation-preview'
import { DefaultNavbarMetadata } from '@/shared/components/types/default-navbar-metadata'
import { FooterMetadata } from '@/shared/components/types/footer-metadata'
import type { ScriptLogType } from '../../../modules/admin-panel/frontend/js/features/script-logs/script-log'
@@ -270,6 +271,8 @@ export interface Meta {
'ol-ssoErrorMessage': string
'ol-ssoInitPath': string
'ol-stripeAccountId': string
'ol-stripePublicKeyUK': string
'ol-stripePublicKeyUS': string
'ol-stripeSubscriptionData': {
customerId: string
subscriptionState: string | null
@@ -277,6 +280,7 @@ export interface Meta {
}
'ol-subscription': any // TODO: mixed types, split into two fields
'ol-subscriptionChangePreview': SubscriptionChangePreview
'ol-subscriptionCreationPreview': SubscriptionCreationPreview
'ol-subscriptionFeatures': {
managedUsers?: boolean
groupSSO?: boolean

View File

@@ -94,6 +94,7 @@
"@overleaf/stream-utils": "*",
"@phosphor-icons/react": "^2.1.7",
"@slack/webhook": "^7.0.2",
"@stripe/react-stripe-js": "^3.9.0",
"@stripe/stripe-js": "^7.7.0",
"@xmldom/xmldom": "^0.7.13",
"accepts": "^1.3.7",

View File

@@ -20,10 +20,12 @@ export type PurchasingAddOnCode = {
code: string
}
type PaymentProviderCoupon = {
export type PaymentProviderCoupon = {
code: string
name: string
description: string
description?: string
isSingleUse?: boolean
discountMonths?: number | null
}
type PaymentProviderRecord = {

View File

@@ -1,3 +1,18 @@
export type ImmediateCharge = {
subtotal: number
tax: number
total: number
discount: number
lineItems: {
planCode: string | null | undefined
description: string
subtotal: number
discount: number
tax: number
isAiAssist: boolean
}[]
}
export type SubscriptionChangePreview = {
change: SubscriptionChangeDescription
currency: string
@@ -6,20 +21,7 @@ export type SubscriptionChangePreview = {
nextPlan: {
annual: boolean
}
immediateCharge: {
subtotal: number
tax: number
total: number
discount: number
lineItems: {
planCode: string | null | undefined
description: string
subtotal: number
discount: number
tax: number
isAiAssist: boolean
}[]
}
immediateCharge: ImmediateCharge
nextInvoice: {
date: string
plan: {

View File

@@ -0,0 +1,12 @@
import { ImmediateCharge } from './subscription-change-preview'
import { PaymentProviderCoupon } from './dashboard/subscription'
import { Plan } from './plan'
export type SubscriptionCreationPreview = {
immediateCharge: ImmediateCharge
taxRate: number
billingCycleInterval: 'month' | 'year'
coupon: PaymentProviderCoupon
trialLength: number | null
plan: Plan
}