You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
4.0 KiB
JavaScript

const router = module.exports = require('express-promise-router')()
const parseJSON = require('body-parser').json()
const db = require('../db')
const stripe = require('stripe')(process.env.STRIPE_PRIVATE_KEY);
const validate = require('./middleware/validators')
router.use(require('./middleware/ensureCart'))
router.put('/', async (req, res) => {
const order = await db.order.create(req.cart.uuid);
res.json(order)
})
router.get('/current', async (req, res) => {
const order = await db.order.findForCart(req.cart.uuid);
res.json(order)
})
router.post('/current/address', parseJSON, validate.address, validate.handleApiError, async (req, res) => {
const origOrder = await db.order.findForCart(req.cart.uuid);
if(!origOrder) throw new Error("Unable to find current order");
const currentTransaction = origOrder
.transactions.find(transaction => (
transaction.payment_state === 'started'
))
const {name, street1, street2, city, state, zip, country} = req.body;
// Create address, update order
const address = await db.address.create(name, street1, street2, city, state, zip, country)
const order = await db.order.addAddress(currentTransaction, address)
res.json(order)
})
router.post('/current/coupon', parseJSON, validate.coupon, validate.handleApiError, async (req, res) => {
const origOrder = await db.order.findForCart(req.cart.uuid);
if(!origOrder) throw new Error("Unable to find current order");
const coupon = await db.coupon.find(req.body.code)
const currentTransaction = origOrder
.transactions.find(transaction => (
transaction.payment_state === 'started'
))
const order = await db.order.addCoupon(currentTransaction, coupon)
res.json(order)
})
router.post('/current/checkout/stripe', async (req, res) => {
const order = await db.order.findForCart(req.cart.uuid);
if(!order) throw new Error("Unable to find current order");
const currentTransaction = order
.transactions.find(transaction => (
transaction.payment_state === 'started'
))
const {item_total_price, shipping_price, tax_price, coupon_effective_discount} = currentTransaction
const {free_shipping} = currentTransaction.coupon || {}
const numberOfItems = currentTransaction.cart.items.map(i => i.count).reduce((a,b) => a+b)
const itemPriceWithDiscount = item_total_price - (coupon_effective_discount || 0)
const shippingPrice = (free_shipping ? 0 : shipping_price)
const line_items = [{
name: `Cart Total (${numberOfItems} item${numberOfItems > 1 ? 's' : ''})`,
amount: itemPriceWithDiscount,
currency: 'usd',
quantity: 1
}, {
name: 'Shipping',
amount: shippingPrice,
currency: 'usd',
quantity: 1
}]
if(tax_price > 0)
line_items.push({
name: 'Sales Tax (Utah)',
amount: tax_price,
currency: 'usd',
quantity: 1
})
const session = await stripe.checkout.sessions.create({
client_reference_id: currentTransaction.uuid,
customer_email: req.user ? req.user.email : undefined,
payment_method_types: ['card'],
line_items,
success_url: `${process.env.EXTERNAL_URL}/store/checkout/complete?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.EXTERNAL_URL}/cancel`,
});
res.json(session.id)
})
router.post('/current/checkout/verify', parseJSON, async (req, res) => {
const {session_id} = req.body
if(!session_id) throw new Error("No session id given")
let order = await db.order.findForCart(req.cart.uuid);
if(!order) throw new Error("Unable to find current order");
const currentTransaction = order
.transactions.find(transaction => (
transaction.payment_state === 'started'
))
const {payment_intent} = await stripe.checkout.sessions.retrieve(session_id);
const payment = await stripe.paymentIntents.retrieve(payment_intent)
if(payment.status === "succeeded"){
order = await db.order.addPayment(currentTransaction, payment)
await db.session.clearCart(req.sessionObj.uuid)
}
res.json({status: payment.status, order})
})