payments
This commit is contained in:
parent
2d17ad0663
commit
1a1ec57772
|
@ -3,12 +3,20 @@ import Stripe from "stripe";
|
||||||
import { StatusCodes } from "http-status-codes";
|
import { StatusCodes } from "http-status-codes";
|
||||||
|
|
||||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
|
||||||
|
const isFreeTier = (tier) => tier === 1;
|
||||||
|
const isPaidTier = (tier) => !isFreeTier(tier);
|
||||||
|
|
||||||
const getStripeCustomer = (user) => {
|
const getStripeCustomer = async (user, authorization) => {
|
||||||
if (user.stripeCustomerId) {
|
if (user.stripeCustomerId) {
|
||||||
return stripe.customers.retrieve(user.stripeCustomerId);
|
return stripe.customers.retrieve(user.stripeCustomerId);
|
||||||
}
|
}
|
||||||
return stripe.customers.create({ email: user.email });
|
|
||||||
|
const customer = stripe.customers.create();
|
||||||
|
|
||||||
|
// update user instance and include the customer id once created
|
||||||
|
await got.put(`http://accounts:3000/user`, { headers: { authorization }, json: { stripeCustomerId: customer.id } });
|
||||||
|
|
||||||
|
return customer;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
|
@ -22,31 +30,23 @@ export default async (req, res) => {
|
||||||
return res.status(StatusCodes.BAD_REQUEST).json({ error: { message: "Missing 'price' attribute" } });
|
return res.status(StatusCodes.BAD_REQUEST).json({ error: { message: "Missing 'price' attribute" } });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new Checkout Session for the order
|
|
||||||
// Other optional params include:
|
|
||||||
// [billing_address_collection] - to display billing address details on the page
|
|
||||||
// [customer] - if you have an existing Stripe Customer ID
|
|
||||||
// [customer_email] - lets you prefill the email input in the form
|
|
||||||
// For full details see https://stripe.com/docs/api/checkout/sessions/create
|
|
||||||
try {
|
try {
|
||||||
const authorization = req.headers.authorization; // authorization header from request
|
const authorization = req.headers.authorization; // authorization header from request
|
||||||
const { stripeCustomerId, ...user } = await got("http://accounts:3000/user", { headers: { authorization } }).json();
|
const user = await got("http://accounts:3000/user", { headers: { authorization } }).json();
|
||||||
// const customer = await getStripeCustomer(user);
|
|
||||||
|
|
||||||
// if (!user.stripeCustomerId) {
|
if (isPaidTier(user.tier)) {
|
||||||
// await got.put(`http://accounts:3000/user`, {
|
const message = `Customer can have only one active subscription at a time, use Stripe Customer Portal to manage active subscription`;
|
||||||
// headers: { authorization },
|
|
||||||
// json: { stripeCustomerId: customer.id },
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
return res.status(StatusCodes.BAD_REQUEST).json({ error: { message } });
|
||||||
|
}
|
||||||
|
|
||||||
|
const customer = await getStripeCustomer(user, authorization);
|
||||||
const session = await stripe.checkout.sessions.create({
|
const session = await stripe.checkout.sessions.create({
|
||||||
mode: "subscription",
|
mode: "subscription",
|
||||||
payment_method_types: ["card"],
|
payment_method_types: ["card"],
|
||||||
line_items: [{ price, quantity: 1 }],
|
line_items: [{ price, quantity: 1 }],
|
||||||
[stripeCustomerId ? "customer" : "customer_email"]: stripeCustomerId ? stripeCustomerId : user.email,
|
customer: customer.id,
|
||||||
client_reference_id: user.sub,
|
client_reference_id: user.sub,
|
||||||
// ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param
|
|
||||||
success_url: `${process.env.SKYNET_DASHBOARD_URL}/payments?session_id={CHECKOUT_SESSION_ID}`,
|
success_url: `${process.env.SKYNET_DASHBOARD_URL}/payments?session_id={CHECKOUT_SESSION_ID}`,
|
||||||
cancel_url: `${process.env.SKYNET_DASHBOARD_URL}/payments`,
|
cancel_url: `${process.env.SKYNET_DASHBOARD_URL}/payments`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,6 +41,8 @@ const plans = [
|
||||||
|
|
||||||
const fetcher = (url) => fetch(url).then((r) => r.json());
|
const fetcher = (url) => fetch(url).then((r) => r.json());
|
||||||
const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
|
const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
|
||||||
|
const isFreeTier = (tier) => tier === 1;
|
||||||
|
const isPaidTier = (tier) => !isFreeTier(tier);
|
||||||
|
|
||||||
const ActiveBadge = () => {
|
const ActiveBadge = () => {
|
||||||
return (
|
return (
|
||||||
|
@ -54,7 +56,6 @@ export default function Payments() {
|
||||||
const { data: user } = useSWR(`${apiPrefix}/user`, fetcher);
|
const { data: user } = useSWR(`${apiPrefix}/user`, fetcher);
|
||||||
const [selectedPlan, setSelectedPlan] = useState(plans[0]);
|
const [selectedPlan, setSelectedPlan] = useState(plans[0]);
|
||||||
const activePlan = plans.find((plan) => user?.tier === plan?.tier);
|
const activePlan = plans.find((plan) => user?.tier === plan?.tier);
|
||||||
const isFreePlan = (plan) => plan?.tier === 1;
|
|
||||||
const handleSubscribe = async () => {
|
const handleSubscribe = async () => {
|
||||||
try {
|
try {
|
||||||
const price = selectedPlan.stripe;
|
const price = selectedPlan.stripe;
|
||||||
|
@ -82,7 +83,7 @@ export default function Payments() {
|
||||||
<div className="px-4 py-5 sm:p-6">
|
<div className="px-4 py-5 sm:p-6">
|
||||||
<dt className="text-sm font-medium text-gray-500 truncate">Subscription status</dt>
|
<dt className="text-sm font-medium text-gray-500 truncate">Subscription status</dt>
|
||||||
<dd className="mt-1 text-3xl font-semibold text-gray-900 capitalize">
|
<dd className="mt-1 text-3xl font-semibold text-gray-900 capitalize">
|
||||||
{isFreePlan(activePlan) ? "—" : user?.subscriptionStatus}
|
{isFreeTier(activePlan?.tier) ? "—" : user?.subscriptionStatus}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
{user?.subscriptionCancelAtPeriodEnd && (
|
{user?.subscriptionCancelAtPeriodEnd && (
|
||||||
|
|
Reference in New Issue