create checkout sessions when subscribe is clicked

This commit is contained in:
Abi Raja 2023-12-22 12:45:11 -05:00
parent 9bc5817aa4
commit 231d334679
5 changed files with 109 additions and 0 deletions

View File

@ -31,6 +31,7 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@stripe/stripe-js": "^2.2.2",
"class-variance-authority": "^0.7.0",
"classnames": "^2.3.2",
"clsx": "^2.0.0",

View File

@ -8,10 +8,14 @@ import {
DialogTrigger,
} from "../ui/dialog";
import { FaCheckCircle } from "react-icons/fa";
import Spinner from "../custom-ui/Spinner";
import useStripeCheckout from "./useStripeCheckout";
const LOGOS = ["microsoft", "amazon", "mit", "stanford", "bytedance", "baidu"];
const PricingDialog: React.FC = () => {
const { checkout, isLoadingCheckout } = useStripeCheckout();
return (
<Dialog>
<DialogTrigger
@ -86,6 +90,34 @@ const PricingDialog: React.FC = () => {
</li>
</ul>
</div>
{/* Economy Plan */}
<div className="bg-white rounded-lg shadow p-6">
<h2 className="font-semibold">Hobby</h2>
<p className="text-gray-500">Higher limits</p>
<div className="my-4">
<span className="text-4xl font-bold">$15</span>
<span className="text-gray-500"> / month</span>
</div>
<button
className="bg-black text-white rounded py-2 px-4 w-full text-sm"
onClick={() => checkout("test")}
>
Subscribe {isLoadingCheckout && <Spinner />}
</button>
<ul className="mt-4 space-y-2">
<li className="flex items-center">
<FaCheckCircle className="text-black mr-2" />
300 credits
</li>
<li className="flex items-center">
<FaCheckCircle className="text-black mr-2" />
Slack support
</li>
</ul>
</div>
</div>
</div>
<p className="text-center text-xs text-gray-600 mt-1">

View File

@ -0,0 +1,66 @@
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { SAAS_BACKEND_URL, STRIPE_PUBLISHABLE_KEY } from "../../config";
import { addEvent } from "../../lib/analytics";
import { Stripe, loadStripe } from "@stripe/stripe-js";
import { useAuthenticatedFetch } from "../hosted/useAuthenticatedFetch";
interface CreateCheckoutSessionResponse {
sessionId: string;
}
export default function useStripeCheckout() {
const authenticatedFetch = useAuthenticatedFetch();
const [stripe, setStripe] = useState<Stripe | null>(null);
const [isLoadingCheckout, setIsLoadingCheckout] = useState(false);
const checkout = async (priceLookupKey: string) => {
const rewardfulReferralId = "xxx"; // TODO: Use later with Rewardful
if (!stripe) {
addEvent("StripeNotLoaded");
return;
}
try {
setIsLoadingCheckout(true);
// Create a Checkout Session
const res: CreateCheckoutSessionResponse = await authenticatedFetch(
`${SAAS_BACKEND_URL}/create_checkout_session` +
`?price_lookup_key=${priceLookupKey}` +
`&rewardful_referral_id=${rewardfulReferralId}`,
"POST"
);
// Redirect to Stripe Checkout
const { error } = await stripe.redirectToCheckout({
sessionId: res.sessionId,
});
if (error) {
throw new Error(error.message);
}
} catch (e) {
toast.error("Error directing you to checkout. Please contact support.");
addEvent("StripeCheckoutError");
} finally {
setIsLoadingCheckout(false);
}
};
// Load Stripe when the component mounts
useEffect(() => {
async function load() {
try {
setStripe(await loadStripe(STRIPE_PUBLISHABLE_KEY));
} catch (e) {
console.error(e);
addEvent("StripeFailedToLoad");
}
}
load();
}, []);
return { checkout, isLoadingCheckout };
}

View File

@ -15,3 +15,8 @@ export const PICO_BACKEND_FORM_SECRET =
export const CLERK_PUBLISHABLE_KEY =
import.meta.env.VITE_CLERK_PUBLISHABLE_KEY || null;
export const STRIPE_PUBLISHABLE_KEY =
import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY || null;
export const SAAS_BACKEND_URL = import.meta.env.VITE_SAAS_BACKEND_URL || null;

View File

@ -1287,6 +1287,11 @@
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e"
integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==
"@stripe/stripe-js@^2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-2.2.2.tgz#9c1318a3e09a6df0a667d54d7f6edb917670109d"
integrity sha512-LvFZRZEBoMe6vXC6RoOAIbXWo/0JDdndq43ekL9M6affcM7PtF5KALmwt91BazW7q49sbSl0l7TunWhhSwEW4w==
"@types/babel__core@^7.20.3":
version "7.20.4"
resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz"