diff --git a/packages/backend/src/graphql/queries/get-paddle-info.ee.js b/packages/backend/src/graphql/queries/get-paddle-info.ee.js deleted file mode 100644 index a07df777..00000000 --- a/packages/backend/src/graphql/queries/get-paddle-info.ee.js +++ /dev/null @@ -1,10 +0,0 @@ -import appConfig from '../../config/app.js'; -import Billing from '../../helpers/billing/index.ee.js'; - -const getPaddleInfo = async () => { - if (!appConfig.isCloud) return; - - return Billing.paddleInfo; -}; - -export default getPaddleInfo; diff --git a/packages/backend/src/graphql/queries/get-payment-plans.ee.js b/packages/backend/src/graphql/queries/get-payment-plans.ee.js deleted file mode 100644 index 49c4f7e2..00000000 --- a/packages/backend/src/graphql/queries/get-payment-plans.ee.js +++ /dev/null @@ -1,10 +0,0 @@ -import appConfig from '../../config/app.js'; -import Billing from '../../helpers/billing/index.ee.js'; - -const getPaymentPlans = async () => { - if (!appConfig.isCloud) return; - - return Billing.paddlePlans; -}; - -export default getPaymentPlans; diff --git a/packages/backend/src/graphql/query-resolvers.js b/packages/backend/src/graphql/query-resolvers.js index 1dbd0561..dc0eb649 100644 --- a/packages/backend/src/graphql/query-resolvers.js +++ b/packages/backend/src/graphql/query-resolvers.js @@ -11,8 +11,6 @@ import getFlow from './queries/get-flow.js'; import getFlows from './queries/get-flows.js'; import getInvoices from './queries/get-invoices.ee.js'; import getNotifications from './queries/get-notifications.js'; -import getPaddleInfo from './queries/get-paddle-info.ee.js'; -import getPaymentPlans from './queries/get-payment-plans.ee.js'; import getPermissionCatalog from './queries/get-permission-catalog.ee.js'; import getRole from './queries/get-role.ee.js'; import getRoles from './queries/get-roles.ee.js'; @@ -41,8 +39,6 @@ const queryResolvers = { getFlows, getInvoices, getNotifications, - getPaddleInfo, - getPaymentPlans, getPermissionCatalog, getRole, getRoles, diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index d157fe23..9ccd9088 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -27,8 +27,6 @@ type Query { getCurrentUser: User getConfig(keys: [String]): JSONObject getInvoices: [Invoice] - getPaddleInfo: GetPaddleInfo - getPaymentPlans: [PaymentPlan] getPermissionCatalog: PermissionCatalog getRole(id: String!): Role getRoles: [Role] @@ -660,11 +658,6 @@ type Usage { task: Int } -type GetPaddleInfo { - sandbox: Boolean - vendorId: Int -} - type Invoice { id: Int amount: Float @@ -673,13 +666,6 @@ type Invoice { receipt_url: String } -type PaymentPlan { - name: String - limit: String - price: String - productId: String -} - type ListSamlAuthProvider { id: String name: String diff --git a/packages/web/src/components/UpgradeFreeTrial/index.ee.jsx b/packages/web/src/components/UpgradeFreeTrial/index.ee.jsx index dbb15e24..c5773274 100644 --- a/packages/web/src/components/UpgradeFreeTrial/index.ee.jsx +++ b/packages/web/src/components/UpgradeFreeTrial/index.ee.jsx @@ -14,16 +14,19 @@ import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Paper from '@mui/material/Paper'; import LockIcon from '@mui/icons-material/Lock'; + import usePaymentPlans from 'hooks/usePaymentPlans.ee'; import useCurrentUser from 'hooks/useCurrentUser'; import usePaddle from 'hooks/usePaddle.ee'; + export default function UpgradeFreeTrial() { - const { plans, loading } = usePaymentPlans(); + const { data: plans, isLoading: isPaymentPlansLoading } = usePaymentPlans(); const currentUser = useCurrentUser(); const { loaded: paddleLoaded } = usePaddle(); const [selectedIndex, setSelectedIndex] = React.useState(0); - const selectedPlan = plans?.[selectedIndex]; + const selectedPlan = plans?.data?.[selectedIndex]; const updateSelection = (index) => setSelectedIndex(index); + const handleCheckout = React.useCallback(() => { window.Paddle.Checkout?.open({ product: selectedPlan.productId, @@ -34,7 +37,9 @@ export default function UpgradeFreeTrial() { }), }); }, [selectedPlan, currentUser]); - if (loading || !plans.length) return null; + + if (isPaymentPlansLoading || !plans?.data?.length) return null; + return ( @@ -82,7 +87,7 @@ export default function UpgradeFreeTrial() { - {plans.map((plan, index) => ( + {plans?.data?.map((plan, index) => ( updateSelection(index)} diff --git a/packages/web/src/contexts/Paddle.ee.jsx b/packages/web/src/contexts/Paddle.ee.jsx index 68e4a954..e7e71c5b 100644 --- a/packages/web/src/contexts/Paddle.ee.jsx +++ b/packages/web/src/contexts/Paddle.ee.jsx @@ -1,21 +1,29 @@ import * as React from 'react'; import { useNavigate } from 'react-router-dom'; + import * as URLS from 'config/urls'; import useCloud from 'hooks/useCloud'; import usePaddleInfo from 'hooks/usePaddleInfo.ee'; import apolloClient from 'graphql/client'; + export const PaddleContext = React.createContext({ loaded: false, }); + export const PaddleProvider = (props) => { const { children } = props; const isCloud = useCloud(); const navigate = useNavigate(); - const { sandbox, vendorId } = usePaddleInfo(); + const { data } = usePaddleInfo(); + const sandbox = data?.data?.sandbox; + const vendorId = data?.data?.vendorId; + const [loaded, setLoaded] = React.useState(false); + const paddleEventHandler = React.useCallback( async (payload) => { const { event, eventData } = payload; + if (event === 'Checkout.Close') { const completed = eventData.checkout?.completed; if (completed) { @@ -24,6 +32,7 @@ export const PaddleProvider = (props) => { await apolloClient.refetchQueries({ include: ['GetTrialStatus', 'GetBillingAndUsage'], }); + navigate(URLS.SETTINGS_BILLING_AND_USAGE, { state: { checkoutCompleted: true }, }); @@ -32,15 +41,18 @@ export const PaddleProvider = (props) => { }, [navigate], ); + const value = React.useMemo(() => { return { loaded, }; }, [loaded]); + React.useEffect( function loadPaddleScript() { if (!isCloud) return; const isInjected = document.getElementById('paddle-js'); + if (isInjected) { setLoaded(true); return; @@ -51,21 +63,26 @@ export const PaddleProvider = (props) => { g.defer = true; g.async = true; g.id = 'paddle-js'; + if (s.parentNode) { s.parentNode.insertBefore(g, s); } + g.onload = function () { setLoaded(true); }; }, [isCloud], ); + React.useEffect( function initPaddleScript() { if (!loaded || !vendorId) return; + if (sandbox) { window.Paddle.Environment.set('sandbox'); } + window.Paddle.Setup({ vendor: vendorId, eventCallback: paddleEventHandler, @@ -73,6 +90,7 @@ export const PaddleProvider = (props) => { }, [loaded, sandbox, vendorId, paddleEventHandler], ); + return ( {children} ); diff --git a/packages/web/src/graphql/queries/get-paddle-info.ee.js b/packages/web/src/graphql/queries/get-paddle-info.ee.js deleted file mode 100644 index f307f4ea..00000000 --- a/packages/web/src/graphql/queries/get-paddle-info.ee.js +++ /dev/null @@ -1,9 +0,0 @@ -import { gql } from '@apollo/client'; -export const GET_PADDLE_INFO = gql` - query GetPaddleInfo { - getPaddleInfo { - sandbox - vendorId - } - } -`; diff --git a/packages/web/src/graphql/queries/get-payment-plans.ee.js b/packages/web/src/graphql/queries/get-payment-plans.ee.js deleted file mode 100644 index 93fa134f..00000000 --- a/packages/web/src/graphql/queries/get-payment-plans.ee.js +++ /dev/null @@ -1,11 +0,0 @@ -import { gql } from '@apollo/client'; -export const GET_PAYMENT_PLANS = gql` - query GetPaymentPlans { - getPaymentPlans { - name - limit - price - productId - } - } -`; diff --git a/packages/web/src/hooks/usePaddleInfo.ee.js b/packages/web/src/hooks/usePaddleInfo.ee.js index b0ff9a7c..b50b1366 100644 --- a/packages/web/src/hooks/usePaddleInfo.ee.js +++ b/packages/web/src/hooks/usePaddleInfo.ee.js @@ -1,10 +1,17 @@ -import { useQuery } from '@apollo/client'; -import { GET_PADDLE_INFO } from 'graphql/queries/get-paddle-info.ee'; +import { useQuery } from '@tanstack/react-query'; +import api from 'helpers/api'; + export default function usePaddleInfo() { - const { data, loading } = useQuery(GET_PADDLE_INFO); - return { - sandbox: data?.getPaddleInfo?.sandbox, - vendorId: data?.getPaddleInfo?.vendorId, - loading, - }; + const query = useQuery({ + queryKey: ['paddleInfo'], + queryFn: async ({ signal }) => { + const { data } = await api.get('/v1/payment/paddle-info', { + signal, + }); + + return data; + }, + }); + + return query; } diff --git a/packages/web/src/hooks/usePaymentPlans.ee.js b/packages/web/src/hooks/usePaymentPlans.ee.js index c8744364..c36ef0f1 100644 --- a/packages/web/src/hooks/usePaymentPlans.ee.js +++ b/packages/web/src/hooks/usePaymentPlans.ee.js @@ -1,9 +1,18 @@ -import { useQuery } from '@apollo/client'; -import { GET_PAYMENT_PLANS } from 'graphql/queries/get-payment-plans.ee'; +import { useQuery } from '@tanstack/react-query'; + +import api from 'helpers/api'; + export default function usePaymentPlans() { - const { data, loading } = useQuery(GET_PAYMENT_PLANS); - return { - plans: data?.getPaymentPlans || [], - loading, - }; + const query = useQuery({ + queryKey: ['paymentPlans'], + queryFn: async ({ signal }) => { + const { data } = await api.get('/v1/payment/plans', { + signal, + }); + + return data; + }, + }); + + return query; }