From e55ce5cd0dfa4e56e8e0cf1c5580f09f82754a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20FAMIBELLE-PRONZOLA?= Date: Sat, 19 Feb 2022 22:10:44 +0400 Subject: [PATCH] Add stripes server endpoint --- server.js | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 136 insertions(+), 8 deletions(-) diff --git a/server.js b/server.js index 2f8e780..869fc7f 100644 --- a/server.js +++ b/server.js @@ -1,33 +1,161 @@ +require('dotenv').config() const express = require('express') +const bodyParser = require('body-parser') const next = require('next') const compression = require('compression') +const pick = require('lodash.pick') +const stripe = require('stripe')(process.env.STRIPE_SECRETE_KEY) + +const endpointSecret = process.env.STRIPE_ENDPOINT_SECRET + +const w = require('./lib/utils/w') +const createSucceededEmail = require('./lib/emails/payment-succeeded') +const {sendMail} = require('./lib/sendmail') const port = process.env.PORT || 3001 const dev = process.env.NODE_ENV !== 'production' +const donProduct = process.env.STRIPE_DON_PRODUCT const app = next({dev}) const handle = app.getRequestHandler() app.prepare().then(() => { const server = express() + server.use((req, res, next) => { + if (req.originalUrl === '/stripe/webhook') { + next() + } else { + express.json()(req, res, next) + } + }) if (!dev) { server.use(compression()) } - server.get('/awtis', (request, response) => { - response.redirect('/awtis/paj/1') + server.get('/awtis', (req, res) => { + res.redirect('/awtis/paj/1') }) - server.get('/awtis/paj/:paj', (request, response) => { - app.render(request, response, '/awtis', { - ...request.query, - paj: request.params.paj + server.get('/awtis/paj/:paj', (req, res) => { + app.render(req, res, '/awtis', { + ...req.query, + paj: req.params.paj }) }) - server.get('*', (request, response) => handle(request, response)) + // Stripe routes - server.post('*', (request, response) => handle(request, response)) + server.get('/stripe/dons-list', w(async (req, res) => { + const prices = await stripe.prices.list({ + active: true, + product: donProduct + }) + const {data} = prices + const filteredData = data.map(d => pick(d, ['id', 'unit_amount'])) + const sortedData = filteredData.sort((a, b) => a.unit_amount - b.unit_amount) + res.send(sortedData) + })) + + server.post('/stripe/valid-payment', w(async (req, res) => { + let customer + const {id, email} = req.body + const price = await stripe.prices.retrieve( + id + ) + if (!price) { + throw new Error('Une erreur s’est produite') + } + + const customerSearch = await stripe.customers.list({ + email + }) + + if (customerSearch.data.length > 0) { + customer = customerSearch.data.find(c => c.email === email) + } else { + customer = await stripe.customers.create({ + email + }) + } + + if (!customer) { + return res.sendStatus(400) + } + + const paymentIntent = await stripe.paymentIntents.create({ + amount: price.unit_amount, + currency: 'eur', + automatic_payment_methods: { + enabled: true + }, + customer: customer.id, + receipt_email: email, + description: 'Don fait à Organisation KA Internationale' + }) + + res.send({ + clientSecret: paymentIntent.client_secret, + paymentIntent: paymentIntent.id + }) + })) + + server.post('/stripe/check-payment', w(async (req, res) => { + const {payment_intent} = req.body + const paymentFromStripe = await stripe.paymentIntents.retrieve( + payment_intent + ) + res.send(paymentFromStripe) + })) + + server.post('/stripe/cancel-payment', w(async (req, res) => { + const {paymentIntent} = req.body + const paymentCanceled = await stripe.paymentIntents.cancel(paymentIntent, { + cancellation_reason: 'abandoned' + }) + + if (!paymentCanceled) { + res.sendStatus(404) + } + + if (paymentCanceled.status === 'canceled') { + res.sendStatus(200) + } else { + res.sendStatus(400) + } + })) + + server.post('/stripe/webhook', bodyParser.raw({type: 'application/json'}), async (req, res) => { + let event = req.body + if (endpointSecret) { + const signature = req.headers['stripe-signature'] + try { + event = stripe.webhooks.constructEvent( + req.body, + signature, + endpointSecret + ) + } catch (error) { + console.log('⚠️ Webhook signature verification failed.', error.message) + return res.sendStatus(400) + } + } + + const paymentIntent = event.data.object + + const email = createSucceededEmail(paymentIntent.amount / 100) + switch (event.type) { + case 'payment_intent.succeeded': + await sendMail(email, paymentIntent.receipt_email) + break + + default: + console.log(`Unhandled event type ${event.type}`) + } + + res.json({received: true}) + }) + + server.get('*', (req, res) => handle(req, res)) server.listen(port, error => { if (error) {