diff --git a/loaders/express.js b/loaders/express.js index 3cff582..3fe6e29 100644 --- a/loaders/express.js +++ b/loaders/express.js @@ -7,7 +7,7 @@ import routeRestaurant from "../routes/routeRestaurant.js"; import routeUser from "../routes/routeUser.js"; import routeSearch from "../routes/routeSearch.js"; import routeImg from "../routes/routeImg.js"; -import routeTest from "../routes/routeTest.js"; +import routePayments from "../routes/routePayments.js"; export default ({ app, secret }) => { const limiter = rateLimiter({ @@ -28,7 +28,7 @@ export default ({ app, secret }) => { app.use("/img", routeImg); app.use("/user", routeUser); app.use("/search", routeSearch); - app.use("/test", routeTest); + app.use("/payments", routePayments); return app; }; diff --git a/models/payments.js b/models/payments.js new file mode 100644 index 0000000..88fcc58 --- /dev/null +++ b/models/payments.js @@ -0,0 +1,10 @@ +import mongoose from "mongoose"; + +const paymentSchema = mongoose.Schema({ + _id: mongoose.Types.ObjectId, + restaurantId: mongoose.Types.ObjectId, + amount: Number, + months: Number, +}); + +export default mongoose.model("Payment", paymentSchema); diff --git a/package-lock.json b/package-lock.json index 635e026..18f9c20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2062,6 +2062,14 @@ "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "babel-jest": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz", @@ -3502,6 +3510,11 @@ "path-exists": "^4.0.0" } }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", diff --git a/package.json b/package.json index b799091..d570334 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "license": "ISC", "dependencies": { "@azure/storage-blob": "^12.2.0-preview.1", + "axios": "^0.20.0", "bcrypt": "^5.0.0", "body-parser": "^1.19.0", "cors": "^2.8.5", diff --git a/routes/routeTest.js b/routes/routePayments.js similarity index 69% rename from routes/routeTest.js rename to routes/routePayments.js index 6b38e9f..90a5281 100644 --- a/routes/routeTest.js +++ b/routes/routePayments.js @@ -1,4 +1,5 @@ import express from "express"; +import { handleError } from "../services/services.js"; var router = express.Router(); @@ -6,7 +7,7 @@ router.post("/", async (req, res) => { try { console.log("test"); } catch (error) { - services.handleError(error, res); + handleError(error, res); } }); diff --git a/routes/routeRestaurant.js b/routes/routeRestaurant.js index 1b39f03..9bc04b7 100644 --- a/routes/routeRestaurant.js +++ b/routes/routeRestaurant.js @@ -9,6 +9,8 @@ import { changeLunchMenu, changeLunchMenuSet, fetchUser, + initializePayment, + renewSubscription, } from "../services/databaseServices.js"; import { decodeAndSanitize, @@ -159,4 +161,23 @@ router.post("/delete", async (req, res) => { } }); +// ACTIVATE SUBSCRIPTION + +router.post("/subscription", async (req, res) => { + try { + const token = req.headers["x-auth-token"]; + const user = validateUserToken(token); + await validateRestaurant(req.body.restaurantId); + /* const response = await initializePayment( + req.body.restaurantId, + req.body.userData, + req.body.type + ); */ + await renewSubscription(req.body.restaurantId, req.body.type); + res.send(200); + } catch (error) { + handleError(error, res); + } +}); + export default router; diff --git a/services/dataPrepServices.js b/services/dataPrepServices.js index 56d3af2..0eaa0b0 100644 --- a/services/dataPrepServices.js +++ b/services/dataPrepServices.js @@ -160,3 +160,32 @@ export async function createDish(dish, restaurantId, oldDish) { throw newError("Cannot create dish", 500); } } + +export function appendDishToLunchSet(lunchMenu, setName, dishId) { + const result = lunchMenu.map((lunchSet) => { + if (lunchSet.lunchSetName === setName) { + let updatedSet = lunchSet; + updatedSet.lunchSetDishes.push(dishId); + return updatedSet; + } else { + return lunchSet; + } + }); + return result; +} + +export function removeDishFromLunchSet(lunchMenu, setName, dishId) { + const result = lunchMenu.map((lunchSet) => { + if (lunchSet.lunchSetName === setName) { + let updatedSet = lunchSet; + const dishIndex = updatedSet.lunchSetDishes.indexOf(dishId); + if (dishIndex > -1) { + updatedSet.lunchSetDishes.splice(dishIndex, 1); + } + return updatedSet; + } else { + return lunchSet; + } + }); + return result; +} diff --git a/services/databaseServices.js b/services/databaseServices.js index 0ec4621..50f396d 100644 --- a/services/databaseServices.js +++ b/services/databaseServices.js @@ -1,8 +1,16 @@ import Restaurant from "../models/restaurant.js"; import Dish from "../models/dish.js"; import User from "../models/users.js"; +import Payments from "../models/payments.js"; import { deleteImage } from "./azureServices.js"; +import { + appendDishToLunchSet, + removeDishFromLunchSet, +} from "./dataPrepServices.js"; import { newError } from "./services.js"; +import mongoose from "mongoose"; +import axios from "axios"; +import crypto from "crypto"; export async function changeUserPass(userId, newPass) { User.findByIdAndUpdate(userId, { $set: { password: newPass } }).catch((e) => { @@ -132,7 +140,7 @@ async function checkIfSetAlreadyInLunchMenu(restaurant, setName) { async function checkIfAlreadyInSet(restaurant, setName, dishId) { const lunchMenu = restaurant.lunchMenu; - for (lunchSet of lunchMenu) { + for (const lunchSet of lunchMenu) { if (lunchSet.lunchSetName === setName) { const dishes = lunchSet.lunchSetDishes; if (dishes.includes(dishId)) { @@ -200,14 +208,27 @@ export async function changeLunchMenu(restaurantId, setName, dishId, action) { throw newError("Nie udało się pobrać restauracji.", 404); }); await checkIfAlreadyInSet(restaurant, setName, dishId); + const updatedLunchMenu = appendDishToLunchSet( + restaurant.lunchMenu, + setName, + dishId + ); await Restaurant.findByIdAndUpdate(restaurantId, { - $push: { lunchMenu: dishId }, + $set: { lunchMenu: updatedLunchMenu }, }).catch((e) => { throw newError("Nie udało się dodać dania do lunch menu.", 500); }); } else if (action === "delete") { + const restaurant = await Restaurant.findById(restaurantId).catch((err) => { + throw newError("Nie udało się pobrać restauracji.", 404); + }); + const updatedLunchMenu = removeDishFromLunchSet( + restaurant.lunchMenu, + setName, + dishId + ); await Restaurant.findByIdAndUpdate(restaurantId, { - $pull: { lunchMenu: dishId }, + $set: { lunchMenu: updatedLunchMenu }, }).catch((e) => { throw newError("Nie udało się usunąć dania.", 500); }); @@ -254,3 +275,64 @@ export async function fetchUser(email) { if (!user) throw newError("Użytkownik nie istnieje", 404); return user; } + +function amountFromType(type) { + if (type === 1) { + return 6150; + } else if (type === 12) { + return 61500; + } else { + return 0; + } +} + +function controlSum(sessionId, merchantId, amount, currency) { + const input = { + sessionId: sessionId, + merchantId: merchantId, + amount: amount, + currency: currency, + crc: "???? wie co tu ma być", + }; + let hash = crypto.createHash("sha384"); + const checkSum = hash.update(input, "utf8"); + return checkSum; +} + +async function registerTransaction(paymentInfo, userData) { + const data = { + merchantId: 11111, + posId: paymentInfo.type, + sessionId: paymentInfo._id, + amount: paymentInfo.amount, + currency: "PLN", + description: `Subskrypcja Menui na: ${paymentInfo.months} miesięcy.`, + email: userData.userEmail, + client: `${userData.firstname} ${userData.lastname}`, + country: "PL", + language: "pl", + urlReturn: "http://test.pl", + sign: controlSum(paymentInfo._id, 11111, paymentInfo.amount, "PLN"), + }; + const response = await axios({ + method: "POST", + url: "https://sandbox.przelewy24.pl/api/v1", + data: data, + }).catch((error) => { + console.log(error); + throw newError("Błąd.", 500); + }); + return response; +} + +export async function initializePayment(restaurantId, userData, type) { + const newPayment = new Payments({ + _id: new mongoose.Types.ObjectId(), + restaurantId: restaurantId, + amount: amountFromType(type), + months: type, + }); + const payment = await registerTransaction(newPayment, userData); + newPayment.save(); + return payment; +}