From 3fe74e40e2b4b9bd5b70993095c32cf698d17d72 Mon Sep 17 00:00:00 2001 From: vincanger <70215737+vincanger@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:44:01 +0100 Subject: [PATCH] check for customer portal link --- .env.client.example | 1 - .../content/docs/guides/stripe-integration.md | 15 ++++++++++++ src/client/app/AccountPage.tsx | 10 +++++--- src/client/landing-page/LandingPage.tsx | 4 ++-- src/client/landing-page/contentSections.ts | 2 +- src/server/actions.ts | 2 +- src/server/webhooks/stripe.ts | 2 +- src/shared/const.ts | 12 ---------- src/shared/constants.ts | 23 +++++++++++++++++++ 9 files changed, 50 insertions(+), 21 deletions(-) delete mode 100644 src/shared/const.ts create mode 100644 src/shared/constants.ts diff --git a/.env.client.example b/.env.client.example index f2a263d..95b14ca 100644 --- a/.env.client.example +++ b/.env.client.example @@ -1,3 +1,2 @@ # learn more about client side env vars https://wasp-lang.dev/docs/project/env-vars - REACT_APP_SOME_VAR_NAME=foo \ No newline at end of file diff --git a/docs/src/content/docs/guides/stripe-integration.md b/docs/src/content/docs/guides/stripe-integration.md index 4fe82ce..8f552b8 100644 --- a/docs/src/content/docs/guides/stripe-integration.md +++ b/docs/src/content/docs/guides/stripe-integration.md @@ -41,6 +41,21 @@ To create a test customer, go to the test customers url [https://dashboard.strip When filling in the test customer email address, use an address you have access to and will use when logging into your SaaS app. This is important because the email address is used to identify the customer when creating a subscription and allows you to manage your test user's payments/subscriptions via the test customer portal ::: +## Get your Customer Portal Link + +Go to https://dashboard.stripe.com/test/settings/billing/portal in the Stripe Dashboard and activate and copy the `Customer portal link`. Paste it in your `src/shared/constants.ts` file. + +```ts title="src/shared/constants.ts" +const customerPortalTestUrl = 'https//billing.stripe.com/p/login/test_...' +const customerPortalProdUrl = undefined + +export const STRIPE_CUSTOMER_PORTAL_LINK = isDev ? customerPortalTestUrl : customerPortalProdUrl; + +checkStripePortalLinkExists(STRIPE_CUSTOMER_PORTAL_LINK); // throws an error if the link is not set in production +``` + +Note that there are variables set aside for your test portal link, as well as a production portal link. You will be warned in the console if you there is no link in the development environment, but the app will throw an error if there is no link in the production environment! + ## Install the Stripe CLI To install the Stripe CLI with homebrew, run the following command in your terminal: diff --git a/src/client/app/AccountPage.tsx b/src/client/app/AccountPage.tsx index 540c226..669bc86 100644 --- a/src/client/app/AccountPage.tsx +++ b/src/client/app/AccountPage.tsx @@ -4,8 +4,8 @@ import getGptResponses from '@wasp/queries/getGptResponses' import logout from '@wasp/auth/logout'; import { useState, Dispatch, SetStateAction } from 'react'; import { Link } from '@wasp/router' -import { CUSTOMER_PORTAL_LINK } from '../../shared/const'; -import { TierIds } from '@wasp/shared/const'; +import { STRIPE_CUSTOMER_PORTAL_LINK } from '@wasp/shared/constants'; +import { TierIds } from '@wasp/shared/constants'; export default function AccountPage({ user }: { user: User }) { const [isLoading, setIsLoading] = useState(false); @@ -82,7 +82,11 @@ function BuyMoreButton({ isLoading, setIsLoading }: { isLoading: boolean, setIsL function CustomerPortalButton({ isLoading, setIsLoading }: { isLoading: boolean, setIsLoading: Dispatch> }) { const handleClick = () => { setIsLoading(true); - window.open(CUSTOMER_PORTAL_LINK, '_blank'); + if (!STRIPE_CUSTOMER_PORTAL_LINK) { + throw new Error('STRIPE_CUSTOMER_PORTAL_LINK is undefined'); + return + } + window.open(STRIPE_CUSTOMER_PORTAL_LINK, '_blank'); setIsLoading(false); }; diff --git a/src/client/landing-page/LandingPage.tsx b/src/client/landing-page/LandingPage.tsx index 9612c37..72f0a1a 100644 --- a/src/client/landing-page/LandingPage.tsx +++ b/src/client/landing-page/LandingPage.tsx @@ -11,7 +11,7 @@ import useAuth from '@wasp/auth/useAuth'; import DropdownUser from '../components/DropdownUser'; import { useHistory } from 'react-router-dom'; import stripePayment from '@wasp/actions/stripePayment'; -import { CUSTOMER_PORTAL_LINK } from '../../shared/const'; +import { STRIPE_CUSTOMER_PORTAL_LINK } from '@wasp/shared/constants'; import { UserMenuItems } from '../components/UserMenuItems'; export default function LandingPage() { @@ -360,7 +360,7 @@ export default function LandingPage() { {!!user && user.hasPaid ? ( = async (tier, context) => { if (!context.user || !context.user.email) { diff --git a/src/server/webhooks/stripe.ts b/src/server/webhooks/stripe.ts index 33b1a54..447d8bb 100644 --- a/src/server/webhooks/stripe.ts +++ b/src/server/webhooks/stripe.ts @@ -2,7 +2,7 @@ import express from 'express'; import { StripeWebhook } from '@wasp/apis/types'; import type { MiddlewareConfigFn } from '@wasp/middleware'; import { emailSender } from '@wasp/email/index.js'; -import { TierIds } from '../../shared/const.js'; +import { TierIds } from '@wasp/shared/constants.js'; import Stripe from 'stripe'; diff --git a/src/shared/const.ts b/src/shared/const.ts deleted file mode 100644 index d44d43b..0000000 --- a/src/shared/const.ts +++ /dev/null @@ -1,12 +0,0 @@ -// get your own link from your stripe dashboard: https://dashboard.stripe.com/settings/billing/portal -// and your own test link: https://dashboard.stripe.com/test/settings/billing/portal -const isDev = process.env.NODE_ENV === 'development'; -export const CUSTOMER_PORTAL_LINK = isDev - ? 'https://billing.stripe.com/p/login/test_8wM8x17JN7DT4zC000' - : ''; - -export enum TierIds { - HOBBY = 'hobby-tier', - PRO = 'pro-tier', - ENTERPRISE = 'enterprise-tier', -} \ No newline at end of file diff --git a/src/shared/constants.ts b/src/shared/constants.ts new file mode 100644 index 0000000..dca046e --- /dev/null +++ b/src/shared/constants.ts @@ -0,0 +1,23 @@ +export enum TierIds { + HOBBY = 'hobby-tier', + PRO = 'pro-tier', + ENTERPRISE = 'enterprise-tier', +} + +//get this link at https://dashboard.stripe.com/test/settings/billing/portal +const isDev = process.env.NODE_ENV === 'development'; +const customerPortalTestUrl: string | undefined = 'https://billing.stripe.com/p/login/test_8wM8x17JN7DT4zC000'; +const customerPortalProdUrl: string | undefined = undefined; + +export const STRIPE_CUSTOMER_PORTAL_LINK = isDev ? customerPortalTestUrl : customerPortalProdUrl; + +function checkStripePortalLinkExists(link: string | undefined) { + if (isDev && link === undefined) { + console.warn('\x1b[31m%s\x1b[0m', '🚫 STRIPE_CUSTOMER_PORTAL_LINK is not defined.'); + } else if (!isDev && link === undefined) { + throw new Error('🚫 STRIPE_CUSTOMER_PORTAL_LINK is not defined'); + } else { + console.log('🎉 STRIPE_CUSTOMER_PORTAL_LINK is defined'); + } +} +checkStripePortalLinkExists(STRIPE_CUSTOMER_PORTAL_LINK);