170 lines
4.3 KiB
JavaScript
170 lines
4.3 KiB
JavaScript
require('dotenv').config()
|
||
const express = require('express')
|
||
const bodyParser = require('body-parser')
|
||
const next = require('next')
|
||
const compression = require('compression')
|
||
const {pick} = require('lodash')
|
||
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}`)
|
||
})
|