check for customer portal link

This commit is contained in:
vincanger 2023-11-30 17:44:01 +01:00
parent da0d79e95c
commit 3fe74e40e2
9 changed files with 50 additions and 21 deletions

View File

@ -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

View File

@ -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:

View File

@ -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<boolean>(false);
@ -82,7 +82,11 @@ function BuyMoreButton({ isLoading, setIsLoading }: { isLoading: boolean, setIsL
function CustomerPortalButton({ isLoading, setIsLoading }: { isLoading: boolean, setIsLoading: Dispatch<SetStateAction<boolean>> }) {
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);
};

View File

@ -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() {
</div>
{!!user && user.hasPaid ? (
<a
href={CUSTOMER_PORTAL_LINK}
href={STRIPE_CUSTOMER_PORTAL_LINK}
aria-describedby='manage-subscription'
className={`
${tier.id === 'enterprise-tier' ? 'opacity-50 cursor-not-allowed' : 'opacity-100 cursor-pointer'}

View File

@ -1,4 +1,4 @@
import { TierIds } from '@wasp/shared/const';
import { TierIds } from '@wasp/shared/constants';
export const navigation = [
{ name: 'Features', href: '#features' },

View File

@ -6,7 +6,7 @@ import type { GenerateGptResponse, StripePayment } from '@wasp/actions/types';
import type { StripePaymentResult, OpenAIResponse } from './types';
import { UpdateCurrentUser, UpdateUserById } from '@wasp/actions/types';
import { fetchStripeCustomer, createStripeCheckoutSession } from './stripeUtils.js';
import { TierIds } from '@wasp/shared/const.js';
import { TierIds } from '@wasp/shared/constants.js';
export const stripePayment: StripePayment<string, StripePaymentResult> = async (tier, context) => {
if (!context.user || !context.user.email) {

View File

@ -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';

View File

@ -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'
: '<insert-prod-link-here>';
export enum TierIds {
HOBBY = 'hobby-tier',
PRO = 'pro-tier',
ENTERPRISE = 'enterprise-tier',
}

23
src/shared/constants.ts Normal file
View File

@ -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);