Skip to content

Commit

Permalink
creating checkout session endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Le committed Jun 4, 2024
1 parent 64befa5 commit 5bd9e03
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 6 deletions.
1 change: 1 addition & 0 deletions backend/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"reflect-metadata": "^0.1.13",
"sequelize": "^6.5.0",
"sequelize-typescript": "^2.1.0",
"stripe": "^15.9.0",
"swagger-ui-express": "^4.1.6",
"ts-node": "^10.0.0",
"umzug": "^3.0.0-beta.16",
Expand Down
73 changes: 73 additions & 0 deletions backend/typescript/rest/stripeRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import express, { Request, Response } from "express";

Check failure on line 1 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

'/home/runner/work/don-efficace/don-efficace/backend/typescript/node_modules/express/index.js' imported multiple times
import { Router } from "express";

Check failure on line 2 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

'/home/runner/work/don-efficace/don-efficace/backend/typescript/node_modules/express/index.js' imported multiple times
import StripeService from "../services/implementations/stripeService";
import IStripeService from "../services/interfaces/stripeService";

const stripeService: IStripeService = new StripeService();

const stripeRouter = Router();

//const app = express();

Check failure on line 10 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Expected exception block, space or tab after '//' in comment
//app.use(express.json());

Check failure on line 11 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Expected exception block, space or tab after '//' in comment

// Endpoint to create a Stripe Checkout session
stripeRouter.post("/create-checkout-session-payment",async (req: Request, res: Response) => {

Check failure on line 14 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Replace `"/create-checkout-session-payment",` with `⏎··"/create-checkout-session-payment",⏎··`
try {
const {user_id, amount, cause_id} = req.body;

Check failure on line 16 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Replace `user_id,·amount,·cause_id` with `·user_id,·amount,·cause_id·`

Check failure on line 16 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Variable name `user_id` must match one of the following formats: camelCase, PascalCase, UPPER_CASE

Check failure on line 16 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Variable name `cause_id` must match one of the following formats: camelCase, PascalCase, UPPER_CASE
const sessionUrl = await stripeService.createCheckoutSessionPayment(user_id, amount, cause_id);

Check failure on line 17 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Replace `user_id,·amount,·cause_id` with `⏎········user_id,⏎········amount,⏎········cause_id,⏎······`
console.log(`Created checkout session`);
res.json({ url: sessionUrl });
} catch (error) {
res.status(500).json({ error: "Error creating payment checkout session." });

Check failure on line 21 in backend/typescript/rest/stripeRoute.ts

View workflow job for this annotation

GitHub Actions / run-lint

Replace `.status(500)` with `⏎········.status(500)⏎········`
}
},
);

/*
stripeRouter.post("/create-checkout-session-subscription", async (req, res) => {
try {
const prices = await stripe.prices.list({
lookup_keys: [req.body.lookup_key],
expand: ["data.product"],
});
const session = await stripe.checkout.sessions.create({
billing_address_collection: "auto",
line_items: [
{
price: prices.data[0].id,
// For metered billing, do not pass quantity
quantity: 1,
},
],
mode: "subscription",
success_url: `http://localhost:5173/checkout-success`,
cancel_url: `http://localhost:5173/checkout-cancel`,
});
res.send({url: session.url});
//res.redirect(303, session.url);
} catch (error) {
res
.status(500)
.json({ error: "Error creating subscription checkout session." });
}
});
stripeRouter.post("/create-portal-session", async (req, res) => {
// For demonstration purposes, we're using the Checkout session to retrieve the customer ID.
// Typically this is stored alongside the authenticated user in your database.
const { session_id } = req.body;
const checkoutSession = await stripe.checkout.sessions.retrieve(session_id);
// This is the url to which the customer will be redirected when they are done
// managing their billing with the portal.
const returnUrl = YOUR_DOMAIN;
const portalSession = await stripe.billingPortal.sessions.create({
customer: checkoutSession.customer,
return_url: returnUrl,
});
res.redirect(303, portalSession.url);
});
*/
export default stripeRouter;
2 changes: 2 additions & 0 deletions backend/typescript/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import entityRouter from "./rest/entityRoutes";
import simpleEntityRouter from "./rest/simpleEntityRoutes";
import userRouter from "./rest/userRoutes";
import donationRouter from "./rest/donationsRoutes";
import stripeRouter from "./rest/stripeRoute";

const CORS_ALLOW_LIST = [
"http://localhost:3000",
Expand Down Expand Up @@ -38,6 +39,7 @@ app.use("/simple-entities", simpleEntityRouter);
app.use("/users", userRouter);
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.use("/donations", donationRouter);
app.use("/stripe", stripeRouter);

// Health check
app.get("/test", async (req: any, res: any) => {
Expand Down
47 changes: 47 additions & 0 deletions backend/typescript/services/implementations/stripeService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import dotenv from "dotenv";
dotenv.config();

import IStripeService from "../interfaces/stripeService";
import logger from "../../utilities/logger";
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_PRIVATE_KEY as string);

const Logger = logger(__filename);

console.log(process.env.STRIPE_PRIVATE_KEY); // Log the value of STRIPE_PRIVATE_KEY
class StripeService implements IStripeService {
createCheckoutSessionPayment = async (
user_id: string,
amount: number,
cause_id: number,
): Promise<string> => {
try {
const session = await stripe.checkout.sessions.create({
//ui_mode: "embedded",
payment_method_types: ["card"],
mode: "payment",
line_items: [
{
price: "$8.99",
quantity: 1,
},
],
success_url: `http://localhost:5000/checkout-success`,
cancel_url: `http://localhost:5000/checkout-cancel`,
});

if (!session.url) {
throw new Error("Session URL is null");
}

return session.url;
} catch (error) {
Logger.error(
`Error creating a checkout session for a payment for user ${user_id} = ${error}`,
);
throw error;
}
};
}
export default StripeService;
2 changes: 1 addition & 1 deletion backend/typescript/services/interfaces/donationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ interface IDonationService {
user_id: string,
amount: number,
cause_id: number,
is_recurring: string,
is_recurring: string, // should this be Recurrence?
confirmation_email_sent: boolean,
): Promise<DonationDTO>;
}
Expand Down
19 changes: 19 additions & 0 deletions backend/typescript/services/interfaces/stripeService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { DonationDTO, Recurrence } from "../../types";

interface IStripeService {
/**
* Create a checkout session for a one time payemnt
* @param user_id user's id
* @param amount the amount the user is donating toward this cause in the donation
* @param cause_id the id of the cause the donation is associated with
* @returns the newly created session url
* @throws Error if
*/
createCheckoutSessionPayment(
user_id: string,
amount: number,
cause_id: number,
): Promise<string>;
}

export default IStripeService;
32 changes: 27 additions & 5 deletions backend/typescript/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1375,10 +1375,10 @@
resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6"
integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==

"@prisma/client@^5.10.2":
version "5.11.0"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.11.0.tgz#d8e55fab85163415b2245fb408b9106f83c8106d"
integrity sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw==
"@prisma/client@^5.11.0":
version "5.14.0"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.14.0.tgz#dadca5bb1137ddcebb454bbdaf89423823d3363f"
integrity sha512-akMSuyvLKeoU4LeyBAUdThP/uhVP3GuLygFE3MlYzaCb3/J8SfsYBE5PkaFuLuVpLyA6sFoW+16z/aPhNAESqg==

"@prisma/[email protected]":
version "5.11.0"
Expand Down Expand Up @@ -2256,6 +2256,13 @@
dependencies:
undici-types "~5.26.4"

"@types/node@>=8.1.0":
version "20.14.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.0.tgz#49ceec7b34f8621470cff44677fa9d461a477f17"
integrity sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==
dependencies:
undici-types "~5.26.4"

"@types/node@^10.1.0":
version "10.17.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
Expand Down Expand Up @@ -7600,6 +7607,13 @@ [email protected]:
dependencies:
side-channel "^1.0.4"

qs@^6.11.0:
version "6.12.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a"
integrity sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==
dependencies:
side-channel "^1.0.6"

qs@~6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
Expand Down Expand Up @@ -8020,7 +8034,7 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==

side-channel@^1.0.4:
side-channel@^1.0.4, side-channel@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
Expand Down Expand Up @@ -8306,6 +8320,14 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==

stripe@^15.9.0:
version "15.9.0"
resolved "https://registry.yarnpkg.com/stripe/-/stripe-15.9.0.tgz#fbe6434496afa27cb08be7dc730064a719e7c925"
integrity sha512-C7NAK17wGr6DOybxThO0n1zVcqSShWno7kx/UcJorQ/nWZ5KnfHQ38DUTb9NgizC8TCII3BPIhqq6Zc/1aUkrg==
dependencies:
"@types/node" ">=8.1.0"
qs "^6.11.0"

strnum@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db"
Expand Down

0 comments on commit 5bd9e03

Please sign in to comment.