Skip to content

Commit 6848d16

Browse files
committed
move customer portal url to .env.client
1 parent 88545be commit 6848d16

File tree

5 files changed

+33
-45
lines changed

5 files changed

+33
-45
lines changed

app/.env.client.example

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
# learn more about client side env vars https://wasp-lang.dev/docs/project/env-vars
2-
REACT_APP_SOME_VAR_NAME=foo
1+
# All client-side env vars must start with REACT_APP_ https://wasp-lang.dev/docs/project/env-vars
2+
3+
# Find your test url at https://dashboard.stripe.com/test/settings/billing/portal
4+
# Remember to replace the test url with the live url before deploying to production
5+
REACT_APP_STRIPE_CUSTOMER_PORTAL=

app/src/client/app/AccountPage.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Link } from 'wasp/client/router';
22
import { type User } from 'wasp/entities';
33
import { logout } from 'wasp/client/auth';
4-
import { STRIPE_CUSTOMER_PORTAL_LINK } from '../../shared/constants';
54
import { TierIds } from '../../shared/constants';
5+
import { z } from 'zod';
66

77
export default function AccountPage({ user }: { user: User }) {
88
return (
@@ -82,7 +82,13 @@ function BuyMoreButton() {
8282

8383
function CustomerPortalButton() {
8484
const handleClick = () => {
85-
window.open(STRIPE_CUSTOMER_PORTAL_LINK, '_blank');
85+
try {
86+
const schema = z.string().url();
87+
const customerPortalUrl = schema.parse(import.meta.env.REACT_APP_STRIPE_CUSTOMER_PORTAL);
88+
window.open(customerPortalUrl, '_blank');
89+
} catch (err) {
90+
console.error(err)
91+
}
8692
};
8793

8894
return (

app/src/client/app/PricingPage.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { useAuth } from 'wasp/client/auth';
22
import { stripePayment } from 'wasp/client/operations';
3-
import { TierIds, STRIPE_CUSTOMER_PORTAL_LINK } from '../../shared/constants';
3+
import { TierIds } from '../../shared/constants';
44
import { AiFillCheckCircle } from 'react-icons/ai';
55
import { useState } from 'react';
66
import { useHistory } from 'react-router-dom';
77
import { cn } from '../../shared/utils';
8+
import { z } from 'zod';
89

910
export const tiers = [
1011
{
@@ -57,6 +58,20 @@ const PricingPage = () => {
5758
}
5859
}
5960

61+
const handleCustomerPortalClick = () => {
62+
if (!user) {
63+
history.push('/login');
64+
return;
65+
}
66+
try {
67+
const schema = z.string().url();
68+
const customerPortalUrl = schema.parse(import.meta.env.REACT_APP_STRIPE_CUSTOMER_PORTAL);
69+
window.open(customerPortalUrl, '_blank');
70+
} catch (err) {
71+
console.error(err);
72+
}
73+
};
74+
6075
return (
6176
<div className='py-10 lg:mt-10'>
6277
<div className='mx-auto max-w-7xl px-6 lg:px-8'>
@@ -115,8 +130,8 @@ const PricingPage = () => {
115130
</ul>
116131
</div>
117132
{!!user && user.hasPaid ? (
118-
<a
119-
href={STRIPE_CUSTOMER_PORTAL_LINK}
133+
<button
134+
onClick={handleCustomerPortalClick}
120135
aria-describedby='manage-subscription'
121136
className={cn(
122137
'mt-8 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 focus-visible:outline focus-visible:outline-2 focus-visible:outline-yellow-400',
@@ -127,7 +142,7 @@ const PricingPage = () => {
127142
)}
128143
>
129144
Manage Subscription
130-
</a>
145+
</button>
131146
) : (
132147
<button
133148
onClick={() => handleBuyNowClick(tier.id)}

app/src/shared/constants.ts

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { z } from 'zod';
2-
31
export enum TierIds {
42
HOBBY = 'hobby-tier',
53
PRO = 'pro-tier',
@@ -8,38 +6,3 @@ export enum TierIds {
86

97
export const DOCS_URL = 'https://docs.opensaas.sh';
108
export const BLOG_URL = 'https://docs.opensaas.sh/blog';
11-
12-
const isDevEnv = process.env.NODE_ENV !== 'production';
13-
const customerPortalTestUrl = '<your-url-here>'; // TODO: find your test url at https://dashboard.stripe.com/test/settings/billing/portal
14-
const customerPortalProdUrl = '<your-url-here>'; // TODO: add before deploying to production
15-
16-
export const STRIPE_CUSTOMER_PORTAL_LINK = isDevEnv ? customerPortalTestUrl : customerPortalProdUrl;
17-
18-
checkStripePortalLinksExist({ customerPortalTestUrl, customerPortalProdUrl });
19-
20-
type StripePortalUrls = {
21-
customerPortalTestUrl: string | undefined;
22-
customerPortalProdUrl: string | undefined;
23-
};
24-
25-
function checkStripePortalLinksExist(links: StripePortalUrls) {
26-
const schema = z.string().url();
27-
const testResult = schema.safeParse(links.customerPortalTestUrl);
28-
const prodResult = schema.safeParse(links.customerPortalProdUrl);
29-
let consoleMsg = {
30-
color: '\x1b[33m%s\x1b[0m',
31-
msg: '',
32-
};
33-
34-
if (testResult.success && prodResult.success) {
35-
consoleMsg.color = '\x1b[32m%s\x1b[0m';
36-
consoleMsg.msg = '✅ Both STRIPE_CUSTOMER_PORTAL_LINK links defined';
37-
} else if (!testResult.success && !prodResult.success) {
38-
consoleMsg.msg = '⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined';
39-
} else if (!testResult.success) {
40-
consoleMsg.msg = '⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined for test env';
41-
} else {
42-
consoleMsg.msg = '⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined for prod env';
43-
}
44-
console.log(consoleMsg.color, consoleMsg.msg);
45-
}

app/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{
77
"compilerOptions": {
88
"target": "esnext",
9+
"module": "ES2022",
910
// We're bundling all code in the end so this is the most appropriate option,
1011
// it's also important for autocomplete to work properly.
1112
"moduleResolution": "bundler",

0 commit comments

Comments
 (0)