diff --git a/.env b/.env index b3dc341..0b34646 100644 --- a/.env +++ b/.env @@ -34,4 +34,6 @@ SMPT_PASSWORD="ND5sgVnWtrpUFfTb" # SMPT_PASSWORD="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" PAYPAL_CLIENT_ID="AemCjVuWswklp1sWUo4peCFg9eS4bofMsMR0RCrVRB2DifYR1IUSrWqtHpVmQlrVMKTI2cWZXLJAdYwn" -PAYPAL_CLIENT_SECRET="EAo0Y9ff3jpHHg1QAbftdebfh7cb_-vnebhQrP9KALbCVer908yx2tO2eHO39r7EJSfqc4D69Qgx8R31" \ No newline at end of file +PAYPAL_CLIENT_SECRET="EAo0Y9ff3jpHHg1QAbftdebfh7cb_-vnebhQrP9KALbCVer908yx2tO2eHO39r7EJSfqc4D69Qgx8R31" + +STRIPE_SECRET="sk_test_51OhPRdSG6gbAOwcEid1GavJ4FTD0ZuHVTferdvJwKal77RlMtFJGBzL5GjtL0ie8ZJztsGjUWi8DWrnw1pDdDRGS005Hk0ahql" \ No newline at end of file diff --git a/app.js b/app.js index 3ce08dc..dd94073 100644 --- a/app.js +++ b/app.js @@ -67,6 +67,7 @@ import TaxRouter from "./resources/Tax/tax_routes.js"; //specialties import SpecialtiesRouter from "./resources/Specialties/SpecialtiesRoute.js"; import ShippingAddressRoute from "./resources/ShippingAddresses/ShippingAddressRoute.js"; +import stripeRoute from "./resources/StripePayment/stripeRoute.js"; //short urls // import ShortUrlRouter from "./resources/Businesses/Short_Urls/ShortUrlRoute.js"; @@ -112,6 +113,8 @@ app.use("/api/business", orderRoute); app.use("/api/tax", TaxRouter); //config app.use("/api/config", ConfigRouter); + +app.use("/api/stripe",stripeRoute); //config specialty // app.use("/api/config/specialty", SpecialtiesRouter); //specialties diff --git a/package-lock.json b/package-lock.json index 1afcf6f..f83d64d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "nodemailer": "^6.9.4", "nodemon": "^3.0.1", "secure-random-password": "^0.2.3", + "stripe": "^14.16.0", "uuid": "^9.0.1", "validator": "^13.7.0" } @@ -2209,6 +2210,32 @@ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "optional": true }, + "node_modules/stripe": { + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-14.16.0.tgz", + "integrity": "sha512-1gOr2LzafWV84cPIO5Md/QPh4XVPLKULVuRpBVOV3Plq3seiHmg/eeOktX+hDl8jpNZuORHYaUJGrNqrABLwdg==", + "dependencies": { + "@types/node": ">=8.1.0", + "qs": "^6.11.0" + }, + "engines": { + "node": ">=12.*" + } + }, + "node_modules/stripe/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 9379766..15b643d 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "nodemailer": "^6.9.4", "nodemon": "^3.0.1", "secure-random-password": "^0.2.3", + "stripe": "^14.16.0", "uuid": "^9.0.1", "validator": "^13.7.0" } diff --git a/resources/ShippingAddresses/ShippingAddressModel.js b/resources/ShippingAddresses/ShippingAddressModel.js index d2f4f5a..d8eacb0 100644 --- a/resources/ShippingAddresses/ShippingAddressModel.js +++ b/resources/ShippingAddresses/ShippingAddressModel.js @@ -32,7 +32,7 @@ const shippingAddressSchema = new mongoose.Schema( trim: true, // Add a regular expression to enforce a specific postal code format // For example, assuming a 5-digit format for the United States - match: /^\d{5}$/, + match: /^\d{6}$/, }, country: { type: String, diff --git a/resources/StripePayment/stripeController.js b/resources/StripePayment/stripeController.js new file mode 100644 index 0000000..21d3346 --- /dev/null +++ b/resources/StripePayment/stripeController.js @@ -0,0 +1,12 @@ +import { createCheckoutSession } from './stripeModel.js'; + +export async function createCheckoutSessionController(req, res) { + try { + const body = req.body; + const sessionId = await createCheckoutSession(body); + res.json({ id: sessionId }); + } catch (error) { + console.error("Error creating checkout session:", error); + res.status(500).json({ error: "Failed to create checkout session" }); + } +} diff --git a/resources/StripePayment/stripeModel.js b/resources/StripePayment/stripeModel.js new file mode 100644 index 0000000..bd514d0 --- /dev/null +++ b/resources/StripePayment/stripeModel.js @@ -0,0 +1,29 @@ +import Stripe from 'stripe'; + +const stripe = new Stripe(process.env.STRIPE_SECRET); + +export async function createCheckoutSession(body) { + const lineItems = body.products.map(({ product, quantity }) => ({ + price_data: { + currency: "usd", + product_data: { + name: product.name, + images: [product.image[0].url] // assuming you want to use the first image URL + }, + unit_amount: Math.round(product.price * 100), // Ensure proper conversion to cents + }, + quantity: quantity + })); + + + + const session = await stripe.checkout.sessions.create({ + payment_method_types: ["card"], + line_items: lineItems, + mode: "payment", + success_url: "http://localhost:5173/order-complete", // Provide your success URL here + cancel_url: "http://localhost:5173/cart" // Provide your cancel URL here + }); + + return session.id; +} diff --git a/resources/StripePayment/stripeRoute.js b/resources/StripePayment/stripeRoute.js new file mode 100644 index 0000000..c22bae6 --- /dev/null +++ b/resources/StripePayment/stripeRoute.js @@ -0,0 +1,8 @@ +import express from "express"; +import { createCheckoutSessionController } from "./stripeController.js"; + +const router = express.Router(); + +router.post("/create-checkout-session", createCheckoutSessionController); + +export default router;