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/valid-payment' || req.originalUrl === '/stripe/check-payment' || req.originalUrl === '/stripe/cancel-payment') { express.json()(req, res, next) } else { next() } }) if (!dev) { server.use(compression()) } server.get('/awtis', (req, res) => { res.redirect('/awtis/paj/1') }) server.get('/awtis/paj/:paj', (req, res) => { app.render(req, res, '/awtis', { ...req.query, paj: req.params.paj }) }) // Stripe routes 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.post('*', (req, res) => handle(req, res)) server.listen(port, error => { if (error) { throw error } }) console.log(`> Ready on http://localhost:${port}`) })