This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| DATABASE_URL="postgresql://postgres:secret@localhost:54321/stripe" | |
| POSTGRES_PASSWORD="secret" | |
| STRIPE_SECRET_KEY="sk_test_************************************" | |
| STRIPE_WEBHOOK_ENDPOINT_SECRET="whsec_********************************" | |
| ORIGIN="http://localhost:3000" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const handleInvoicePaymentFailed = async (data: Stripe.Event.Data.Object) => { | |
| const invoice = data as Stripe.Invoice; | |
| const stripeSub = invoice.subscription; | |
| const subId = typeof stripeSub === 'string' ? stripeSub : stripeSub?.id; | |
| const subscription = await db.subscription.findFirst({ | |
| where: { | |
| stripe_subscription_id: subId, | |
| }, | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const handleCustomerSubscriptionUpdated = async ( | |
| data: Stripe.Event.Data.Object | |
| ) => { | |
| const stripeSub = data as Stripe.Subscription; | |
| const subscription = await db.subscription.findFirst({ | |
| where: { | |
| stripe_subscription_id: stripeSub.id, | |
| }, | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const handleCheckoutSessionCompleted = async ( | |
| session: Stripe.Event.Data.Object | |
| ) => { | |
| const data = session as Stripe.Checkout.Session; | |
| const user = await db.user.findFirst({ | |
| where: { email: data.customer_email! }, | |
| }); | |
| const stripeSubscriptionId = data.subscription?.toString(); | |
| const stripeSub = await stripe.subscriptions.retrieve(stripeSubscriptionId!); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { ActionFunction } from '@remix-run/node'; | |
| import { json } from '@remix-run/node'; | |
| import { stripe } from '~/stripe.server'; | |
| import { handleStripeEvent } from '~/routes/webhook.server'; | |
| //[credit @kiliman to get this webhook working](https://github.com/remix-run/remix/discussions/1978) | |
| export const action: ActionFunction = async ({ request }) => { | |
| const payload = await request.text(); | |
| const sig = request.headers.get('stripe-signature')!; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { LoaderFunction } from '@remix-run/server-runtime'; | |
| import { redirect } from '@remix-run/server-runtime'; | |
| import { getLoggedInUser } from '~/user.server'; | |
| export const loader: LoaderFunction = async () => { | |
| const user = await getLoggedInUser(); | |
| if (!user) { | |
| return redirect('/'); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { ActionFunction } from '@remix-run/server-runtime'; | |
| import { redirect } from '@remix-run/server-runtime'; | |
| import { stripe } from '~/stripe.server'; | |
| import { getLoggedInUser } from '~/user.server'; | |
| export const action: ActionFunction = async () => { | |
| const user = await getLoggedInUser(); | |
| if (!user) { | |
| return redirect('/'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { ActionFunction } from "@remix-run/server-runtime"; | |
| import { redirect } from "@remix-run/server-runtime"; | |
| import { stripeCheckout } from "~/stripe.server"; | |
| import { getPriceId } from "~/types/subscription"; | |
| import { getLoggedInUser } from "~/user.server"; | |
| export const action: ActionFunction = async ({ request }) => { | |
| const user = await getLoggedInUser(); | |
| if (!user) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export enum USER_STATUS { | |
| NO_ACTIVE_SUBSCRIPTION, | |
| IS_IN_TRIAL, | |
| IN_SUBSCRIPTION, | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const plans = [ | |
| { | |
| name: "Basic", | |
| tier: "basic", | |
| price: 5, | |
| priceId: "price_1MNhAzFSrpGVHE9i8tGqm0R7", | |
| }, | |
| { | |
| name: "Pro", | |
| tier: "pro", |