diff --git a/README.md b/README.md new file mode 100644 index 0000000..fa20860 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/jlengrand/vanilla-js) diff --git a/server.js b/server.js index d82348d..0b68e7e 100644 --- a/server.js +++ b/server.js @@ -1,12 +1,6 @@ const express = require("express"); const path = require("path"); -const hbs = require("express-handlebars"); -const dotenv = require("dotenv"); const morgan = require("morgan"); -const { uuid } = require("uuidv4"); - -const { hmacValidator } = require('@adyen/api-library'); -const { Client, Config, CheckoutAPI } = require("@adyen/api-library"); // init app const app = express(); @@ -19,157 +13,11 @@ app.use(express.urlencoded({ extended: true })); // Serve client from build folder app.use(express.static(path.join(__dirname, "/public"))); -// enables environment variables by -// parsing the .env file and assigning it to process.env -dotenv.config({ - path: "./.env", -}); - -// Adyen Node.js API library boilerplate (configuration, etc.) -const config = new Config(); -config.apiKey = process.env.ADYEN_API_KEY; -const client = new Client({ config }); -client.setEnvironment("TEST"); // change to LIVE for production -const checkout = new CheckoutAPI(client); - -/* ################# API ENDPOINTS ###################### */ - -// Invoke /sessions endpoint -app.post("/api/sessions", async (req, res) => { - - try { - // unique ref for the transaction - const orderRef = uuid(); - // Allows for gitpod support - const localhost = req.get('host'); - // const isHttps = req.connection.encrypted; - const protocol = req.socket.encrypted? 'https' : 'http'; - // Ideally the data passed here should be computed based on business logic - const response = await checkout.sessions({ - amount: { currency: "EUR", value: 1000 }, // value is 10€ in minor units - countryCode: "NL", - merchantAccount: process.env.ADYEN_MERCHANT_ACCOUNT, // required - reference: orderRef, // required: your Payment Reference - returnUrl: `${protocol}://${localhost}/api/handleShopperRedirect?orderRef=${orderRef}` // set redirect URL required for some payment methods - }); - - res.json(response); - } catch (err) { - console.error(`Error: ${err.message}, error code: ${err.errorCode}`); - res.status(err.statusCode).json(err.message); - } -}); - - - -// Handle all redirects from payment type -app.all("/api/handleShopperRedirect", async (req, res) => { - // Create the payload for submitting payment details - const redirect = req.method === "GET" ? req.query : req.body; - const details = {}; - if (redirect.redirectResult) { - details.redirectResult = redirect.redirectResult; - } else if (redirect.payload) { - details.payload = redirect.payload; - } - - try { - const response = await checkout.paymentsDetails({ details }); - // Conditionally handle different result codes for the shopper - switch (response.resultCode) { - case "Authorised": - res.redirect("/result/success"); - break; - case "Pending": - case "Received": - res.redirect("/result/pending"); - break; - case "Refused": - res.redirect("/result/failed"); - break; - default: - res.redirect("/result/error"); - break; - } - } catch (err) { - console.error(`Error: ${err.message}, error code: ${err.errorCode}`); - res.redirect("/result/error"); - } -}); - -/* ################# end API ENDPOINTS ###################### */ - -/* ################# CLIENT SIDE ENDPOINTS ###################### */ - -// Index (select a demo) app.get("/", (req, res) => res.render("index")); -// Cart (continue to checkout) -app.get("/preview", (req, res) => - res.render("preview", { - type: req.query.type, - }) -); - -// Checkout page (make a payment) -app.get("/checkout", (req, res) => - res.render("checkout", { - type: req.query.type, - clientKey: process.env.ADYEN_CLIENT_KEY - }) -); - -// Result page -app.get("/result/:type", (req, res) => - res.render("result", { - type: req.params.type, - }) -); - -/* ################# end CLIENT SIDE ENDPOINTS ###################### */ - -/* ################# WEBHOOK ###################### */ - -app.post("/api/webhooks/notifications", async (req, res) => { - - // YOUR_HMAC_KEY from the Customer Area - const hmacKey = process.env.ADYEN_HMAC_KEY; - const validator = new hmacValidator() - // Notification Request JSON - const notificationRequest = req.body; - const notificationRequestItems = notificationRequest.notificationItems - - // Handling multiple notificationRequests - notificationRequestItems.forEach(function(notificationRequestItem) { - - const notification = notificationRequestItem.NotificationRequestItem - - // Handle the notification - if( validator.validateHMAC(notification, hmacKey) ) { - // Process the notification based on the eventCode - const merchantReference = notification.merchantReference; - const eventCode = notification.eventCode; - console.log('merchantReference:' + merchantReference + " eventCode:" + eventCode); - } else { - // invalid hmac: do not send [accepted] response - console.log("Invalid HMAC signature: " + notification); - res.status(401).send('Invalid HMAC signature'); - } -}); - - res.send('[accepted]') -}); - - -/* ################# end WEBHOOK ###################### */ - -/* ################# UTILS ###################### */ - function getPort() { return process.env.PORT || 9000; } -/* ################# end UTILS ###################### */ - // Start server app.listen(getPort(), () => console.log(`Server started -> http://localhost:${getPort()}`));