Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 94b261fa32 | |||
| c684b54aef | |||
| ffc037b854 | |||
| 5990d4ce2d | |||
| bae4cf1d4f |
@@ -32,11 +32,12 @@ export default async function checkSubscriptionByEmail(email: string) {
|
|||||||
customer.subscriptions?.data.some((subscription) => {
|
customer.subscriptions?.data.some((subscription) => {
|
||||||
subscription.current_period_end;
|
subscription.current_period_end;
|
||||||
|
|
||||||
active = subscription.items.data.some(
|
active =
|
||||||
(e) =>
|
subscription.items.data.some(
|
||||||
(e.price.id === MONTHLY_PRICE_ID && e.price.active === true) ||
|
(e) =>
|
||||||
(e.price.id === YEARLY_PRICE_ID && e.price.active === true)
|
(e.price.id === MONTHLY_PRICE_ID && e.price.active === true) ||
|
||||||
);
|
(e.price.id === YEARLY_PRICE_ID && e.price.active === true)
|
||||||
|
) || false;
|
||||||
stripeSubscriptionId = subscription.id;
|
stripeSubscriptionId = subscription.id;
|
||||||
currentPeriodStart = subscription.current_period_start * 1000;
|
currentPeriodStart = subscription.current_period_start * 1000;
|
||||||
currentPeriodEnd = subscription.current_period_end * 1000;
|
currentPeriodEnd = subscription.current_period_end * 1000;
|
||||||
@@ -44,7 +45,7 @@ export default async function checkSubscriptionByEmail(email: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
active,
|
active: active || false,
|
||||||
stripeSubscriptionId,
|
stripeSubscriptionId,
|
||||||
currentPeriodStart,
|
currentPeriodStart,
|
||||||
currentPeriodEnd,
|
currentPeriodEnd,
|
||||||
|
|||||||
@@ -16,8 +16,11 @@ export default async function paymentCheckout(
|
|||||||
|
|
||||||
const isExistingCustomer = listByEmail?.data[0]?.id || undefined;
|
const isExistingCustomer = listByEmail?.data[0]?.id || undefined;
|
||||||
|
|
||||||
|
console.log("isExistingCustomer", listByEmail?.data[0]);
|
||||||
|
|
||||||
const NEXT_PUBLIC_TRIAL_PERIOD_DAYS =
|
const NEXT_PUBLIC_TRIAL_PERIOD_DAYS =
|
||||||
process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS;
|
Number(process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS) || 14;
|
||||||
|
|
||||||
const session = await stripe.checkout.sessions.create({
|
const session = await stripe.checkout.sessions.create({
|
||||||
customer: isExistingCustomer ? isExistingCustomer : undefined,
|
customer: isExistingCustomer ? isExistingCustomer : undefined,
|
||||||
line_items: [
|
line_items: [
|
||||||
@@ -34,9 +37,9 @@ export default async function paymentCheckout(
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
subscription_data: {
|
subscription_data: {
|
||||||
trial_period_days: NEXT_PUBLIC_TRIAL_PERIOD_DAYS
|
trial_period_days: isExistingCustomer
|
||||||
? Number(NEXT_PUBLIC_TRIAL_PERIOD_DAYS)
|
? undefined
|
||||||
: 14,
|
: NEXT_PUBLIC_TRIAL_PERIOD_DAYS,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,7 @@ export default async function verifySubscription(
|
|||||||
|
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
|
|
||||||
if (
|
if (!subscription?.active || currentDate > subscription.currentPeriodEnd) {
|
||||||
subscription &&
|
|
||||||
currentDate > subscription.currentPeriodEnd &&
|
|
||||||
!subscription.active
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subscription || currentDate > subscription.currentPeriodEnd) {
|
|
||||||
const {
|
const {
|
||||||
active,
|
active,
|
||||||
stripeSubscriptionId,
|
stripeSubscriptionId,
|
||||||
@@ -59,15 +51,21 @@ export default async function verifySubscription(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
}
|
} else if (!active) {
|
||||||
|
const subscription = await prisma.subscription.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: user.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!active) {
|
if (subscription)
|
||||||
if (user.username)
|
await prisma.subscription.delete({
|
||||||
// await prisma.user.update({
|
where: {
|
||||||
// where: { id: user.id },
|
userId: user.id,
|
||||||
// data: { username: null },
|
},
|
||||||
// });
|
});
|
||||||
return null;
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default async function verifyUser({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (STRIPE_SECRET_KEY) {
|
if (STRIPE_SECRET_KEY) {
|
||||||
const subscribedUser = verifySubscription(user);
|
const subscribedUser = await verifySubscription(user);
|
||||||
|
|
||||||
if (!subscribedUser) {
|
if (!subscribedUser) {
|
||||||
res.status(401).json({
|
res.status(401).json({
|
||||||
|
|||||||
+2
-2
@@ -10,10 +10,10 @@
|
|||||||
"seed": "node ./prisma/seed.js"
|
"seed": "node ./prisma/seed.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently -k \"next dev\" \"yarn worker:dev\"",
|
"dev": "concurrently -k -P \"next dev {@}\" \"yarn worker:dev\" --",
|
||||||
"worker:dev": "nodemon --skip-project scripts/worker.ts",
|
"worker:dev": "nodemon --skip-project scripts/worker.ts",
|
||||||
"worker:prod": "ts-node --transpile-only --skip-project scripts/worker.ts",
|
"worker:prod": "ts-node --transpile-only --skip-project scripts/worker.ts",
|
||||||
"start": "concurrently \"next start\" \"yarn worker:prod\"",
|
"start": "concurrently -k -P \"next start {@}\" \"yarn worker:prod\" --",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"format": "prettier --write \"**/*.{ts,tsx,js,json,md}\""
|
"format": "prettier --write \"**/*.{ts,tsx,js,json,md}\""
|
||||||
|
|||||||
+20
-10
@@ -5,6 +5,7 @@ import { useRouter } from "next/router";
|
|||||||
import CenteredForm from "@/layouts/CenteredForm";
|
import CenteredForm from "@/layouts/CenteredForm";
|
||||||
import { Plan } from "@/types/global";
|
import { Plan } from "@/types/global";
|
||||||
import AccentSubmitButton from "@/components/AccentSubmitButton";
|
import AccentSubmitButton from "@/components/AccentSubmitButton";
|
||||||
|
import useAccountStore from "@/store/account";
|
||||||
|
|
||||||
export default function Subscribe() {
|
export default function Subscribe() {
|
||||||
const [submitLoader, setSubmitLoader] = useState(false);
|
const [submitLoader, setSubmitLoader] = useState(false);
|
||||||
@@ -12,6 +13,8 @@ export default function Subscribe() {
|
|||||||
|
|
||||||
const [plan, setPlan] = useState<Plan>(1);
|
const [plan, setPlan] = useState<Plan>(1);
|
||||||
|
|
||||||
|
const { account } = useAccountStore();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
async function submit() {
|
async function submit() {
|
||||||
@@ -27,9 +30,13 @@ export default function Subscribe() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CenteredForm
|
<CenteredForm
|
||||||
text={`Start with a ${
|
text={
|
||||||
process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14
|
account.username
|
||||||
}-day free trial, cancel anytime!`}
|
? ""
|
||||||
|
: `Start with a ${
|
||||||
|
process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14
|
||||||
|
}-day free trial, cancel anytime!`
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className="p-4 mx-auto flex flex-col gap-3 justify-between max-w-[30rem] min-w-80 w-full bg-base-200 rounded-2xl shadow-md border border-neutral-content">
|
<div className="p-4 mx-auto flex flex-col gap-3 justify-between max-w-[30rem] min-w-80 w-full bg-base-200 rounded-2xl shadow-md border border-neutral-content">
|
||||||
<p className="sm:text-3xl text-2xl text-center font-extralight">
|
<p className="sm:text-3xl text-2xl text-center font-extralight">
|
||||||
@@ -37,7 +44,6 @@ export default function Subscribe() {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="divider my-0"></div>
|
<div className="divider my-0"></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
You will be redirected to Stripe, feel free to reach out to us at{" "}
|
You will be redirected to Stripe, feel free to reach out to us at{" "}
|
||||||
@@ -47,7 +53,6 @@ export default function Subscribe() {
|
|||||||
in case of any issue.
|
in case of any issue.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-3 border border-solid border-neutral-content w-4/5 mx-auto p-1 rounded-xl relative">
|
<div className="flex gap-3 border border-solid border-neutral-content w-4/5 mx-auto p-1 rounded-xl relative">
|
||||||
<button
|
<button
|
||||||
onClick={() => setPlan(Plan.monthly)}
|
onClick={() => setPlan(Plan.monthly)}
|
||||||
@@ -74,7 +79,6 @@ export default function Subscribe() {
|
|||||||
25% Off
|
25% Off
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col gap-2 justify-center items-center">
|
<div className="flex flex-col gap-2 justify-center items-center">
|
||||||
<p className="text-3xl">
|
<p className="text-3xl">
|
||||||
${plan === Plan.monthly ? "4" : "3"}
|
${plan === Plan.monthly ? "4" : "3"}
|
||||||
@@ -89,13 +93,20 @@ export default function Subscribe() {
|
|||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<p className="text-sm">
|
<p className="text-sm">
|
||||||
{process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS}-day free trial, then $
|
{account.username
|
||||||
{plan === Plan.monthly ? "4 per month" : "36 annually"}
|
? ""
|
||||||
|
: `${process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS}-day free trial, then `}
|
||||||
|
${plan === Plan.monthly ? "4 per month" : "36 annually"}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm">+ VAT if applicable</p>
|
<p className="text-sm">+ VAT if applicable</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<p className="text-sm mb-5">
|
||||||
|
{account.username
|
||||||
|
? "Please note that since your trial has been previously ended, your subscription will start immediately. You can cancel anytime."
|
||||||
|
: ""}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<AccentSubmitButton
|
<AccentSubmitButton
|
||||||
type="button"
|
type="button"
|
||||||
label="Complete Subscription!"
|
label="Complete Subscription!"
|
||||||
@@ -103,7 +114,6 @@ export default function Subscribe() {
|
|||||||
onClick={submit}
|
onClick={submit}
|
||||||
loading={submitLoader}
|
loading={submitLoader}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
onClick={() => signOut()}
|
onClick={() => signOut()}
|
||||||
className="w-fit mx-auto cursor-pointer text-neutral font-semibold "
|
className="w-fit mx-auto cursor-pointer text-neutral font-semibold "
|
||||||
|
|||||||
Reference in New Issue
Block a user