Skip to content

Commit

Permalink
setup stripe
Browse files Browse the repository at this point in the history
  • Loading branch information
alaister committed Oct 27, 2024
1 parent 744d11c commit 76af91c
Show file tree
Hide file tree
Showing 32 changed files with 6,561 additions and 2,657 deletions.
31 changes: 0 additions & 31 deletions app/api/billing/checkout/route.ts

This file was deleted.

174 changes: 0 additions & 174 deletions app/api/billing/webhook/route.ts

This file was deleted.

2 changes: 1 addition & 1 deletion components/WhoisInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const WhoisInfo = ({ data }: WhoisInfoProps) => {
return Object.entries(data)
.filter(([key]) => !excludeFields.includes(key))
.map(([key, value]) => (
<div key={key} className="flex flex-col gap-1 py-1.5">
<div key={key} className="flex flex-col gap-1 py-1.5 break-all">
<dt className="text-xs font-semibold text-gray-600 capitalize">
{key.replace(/_/g, ' ')}
</dt>
Expand Down
23 changes: 15 additions & 8 deletions components/purchase-page.tsx → components/checkout-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,36 @@ import {
} from '@stripe/react-stripe-js'
import { loadStripe } from '@stripe/stripe-js'
import { useCallback, useMemo } from 'react'
import { fetchAPI } from '~/lib/fetcher'
import supabase from '~/lib/supabase'

const stripePromise = loadStripe(
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!
)

const PurchasePage = () => {
interface CheckoutFormProps {
planType: 'MONTHLY' | 'LIFETIME'
}

const CheckoutForm = ({ planType }: CheckoutFormProps) => {
const fetchClientSecret = useCallback(() => {
return fetchAPI<{ clientSecret: string }>('/billing/checkout', 'POST').then(
(data) => data.clientSecret
)
}, [])
return supabase.functions
.invoke('stripe-checkout', { body: { planType } })
.then(({ data }) => data?.clientSecret)
}, [planType])

return (
<div id="checkout">
<EmbeddedCheckoutProvider
stripe={stripePromise}
options={useMemo(() => ({ fetchClientSecret }), [fetchClientSecret])}
options={useMemo(
() => ({ fetchClientSecret, onComplete: console.log }),
[fetchClientSecret]
)}
>
<EmbeddedCheckout />
</EmbeddedCheckoutProvider>
</div>
)
}

export default PurchasePage
export default CheckoutForm
4 changes: 2 additions & 2 deletions components/home/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { GithubIcon, TwitterIcon } from 'lucide-react'
const SOCIAL = [
{
name: 'Twitter',
href: 'https://twitter.com/alaisteryoung',
href: 'https://twitter.com/melb_dot_tech',
icon: <TwitterIcon className="h-6 w-6" aria-hidden="true" />,
},
{
name: 'GitHub',
href: 'https://github.com/alaister/side.domains',
href: 'https://github.com/melbourne-tech/side.domains',
icon: <GithubIcon className="h-6 w-6" aria-hidden="true" />,
},
]
Expand Down
83 changes: 4 additions & 79 deletions components/home/pricing.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ArrowRightIcon, CheckIcon } from 'lucide-react'
import { Button } from '~/components/ui/button'
import { cn } from '~/lib/utils'
import { CheckIcon } from 'lucide-react'
import PurchasePlans from '../purchase-plans'

const features = [
'Check domain availability',
Expand All @@ -9,29 +8,6 @@ const features = [
'For-sale pages with SSL',
]

const tiers = [
{
name: 'Monthly Plan',
id: 'monthly',
href: `${process.env.NEXT_PUBLIC_LEMON_SQUEEZY_STORE_URL}/checkout/buy/${process.env.NEXT_PUBLIC_LEMON_SQUEEZY_VARIANT_ID}`,
price: '$5',
period: '/month',
description: 'Pay monthly, cancel anytime',
ctaText: 'Start Monthly Plan',
featured: false,
},
{
name: 'Lifetime Access',
id: 'lifetime',
href: `${process.env.NEXT_PUBLIC_LEMON_SQUEEZY_STORE_URL}/checkout/buy/${process.env.NEXT_PUBLIC_LEMON_SQUEEZY_VARIANT_ID}`,
price: '$49',
period: 'one-time',
description: 'Pay once, use forever',
ctaText: 'Get Lifetime Access',
featured: true,
},
]

const Pricing = () => {
return (
<div
Expand Down Expand Up @@ -71,63 +47,12 @@ const Pricing = () => {
</div>

{/* Pricing Cards */}
<div className="mx-auto mt-16 grid max-w-xl grid-cols-1 gap-y-6 sm:mt-20 lg:max-w-4xl lg:grid-cols-2 lg:gap-x-8">
{tiers.map((tier) => (
<div
key={tier.id}
className={cn(
'rounded-3xl p-8 ring-1',
tier.featured
? 'bg-gray-900 ring-gray-900 text-white'
: 'ring-gray-200 bg-white'
)}
>
<h3
className={cn(
'text-lg font-semibold leading-8',
tier.featured ? 'text-white' : 'text-gray-900'
)}
>
{tier.name}
</h3>
<p className="mt-4 flex items-baseline gap-x-2">
<span className="text-4xl font-bold tracking-tight">
{tier.price}
</span>
<span
className={cn(
'text-sm',
tier.featured ? 'text-gray-400' : 'text-gray-500'
)}
>
{tier.period}
</span>
</p>
<p
className={cn(
'mt-6 text-sm leading-6',
tier.featured ? 'text-gray-300' : 'text-gray-600'
)}
>
{tier.description}
</p>
<Button
asChild
variant={tier.featured ? 'secondary' : 'outline'}
className="w-full mt-6"
>
<a href={tier.href} aria-describedby={tier.id}>
{tier.ctaText} <ArrowRightIcon size={16} />
</a>
</Button>
</div>
))}
</div>
<PurchasePlans />

<p className="text-center text-sm text-gray-500 mt-8">
Want to self-host?{' '}
<a
href="https://github.com/alaister/side.domains"
href="https://github.com/melbourne-tech/side.domains"
className="text-indigo-600 hover:text-indigo-500"
>
The code is on GitHub
Expand Down
Loading

0 comments on commit 76af91c

Please sign in to comment.