Added monero paid hooks

This commit is contained in:
Keith Irwin 2023-03-25 15:19:49 -06:00
parent a17c5cf686
commit 28bd5d501c
Signed by: ki9
GPG Key ID: DF773B3F4A88DA86
6 changed files with 48 additions and 37 deletions

View File

@ -41,8 +41,7 @@ const getXmrPrice = async () => {
if (res.data.monero.usd)
return XMR_PRICE = Number(res.data.monero.usd)
else return
}
getXmrPrice()
}; getXmrPrice()
setInterval(getXmrPrice,1000*Number(process.env.MONERO_PRICECHECK_SEC))
const usdToXmr = (usd) => Number(usd / XMR_PRICE)
@ -282,6 +281,10 @@ module.exports = async (req, res) => {
fs.chown(orderFile,7000,7000)
} catch (err) { console.error(`ERROR! Failed to save ${orderFile}:\n${err}`) }
// Check for monero payments
if (processedOrder.paymentMethod==='XMR')
require('../listeners/monero')(processedOrder)
}
}).catch((err) => {
// This catch block runs if the subtotal/shipping/taxes don't add up

View File

@ -3,6 +3,7 @@ require('dotenv').config()
const formatUSD = require('../lib/formatUSD')
const mailer = require('../lib/mailer')
module.exports = async (order) => {
const amt = (order.paymentMethod==='XMR')?`${order.totalxmr} XMR`:formatUSD(order.total)
const customer_mail_items_string = await order.items.reduce((acc,cur) =>
acc += `${cur.qty} ${formatUSD(cur.price)} ${cur.subtotal} ${cur.name}\n`
, 'Qty Price Subtotal Item\n')
@ -12,8 +13,8 @@ module.exports = async (order) => {
from: process.env.SALES_MAIL_FROM,
to: order.contact.email,
replyTo: process.env.SALES_EMAIL,
subject: `Order ${order.id} for ${formatUSD(order.total)} has been processed`,
text: `Dear ${order.contact.name},\n\nThank you for your payment. We will ship your order as soon as possible and send the tracking info to this email address. For now, keep this copy of your order details as proof of your payment. \n\n---\n\nITEMS: \n${customer_mail_items_string}\nTOTALS: \nSubtotal: ${formatUSD(order.subtotal)}\nTax: ${formatUSD(order.taxAmount)}\nShipping: ${formatUSD(order.shipping.amount)}\nProcessing: ${formatUSD(order.processing)}\n\nCONTACT: \n${order.contact.name}\n${order.contact.phone}\n${order.contact.email}\n\nSHIPPING ADDRESS:\n${order.shipping.address.name}\n${order.shipping.address.addr1}${(order.shipping.address.addr2)?'\n'+order.shipping.address.addr2:''}\n${order.shipping.address.city}, ${order.shipping.address.state} ${order.shipping.address.zip}\n\n---\n\nTo view your order info anytime, visit this page: ${process.env.SITE_URL}/shop/order/stripe/?order=${order.id}\n\nFor questions, comments, or to cancel this order, reply to this email or call 719-936-7778 x1. \n\nThank you!\n\n`,
subject: `Order ${order.id} for ${amt} has been processed`,
text: `Dear ${order.contact.name},\n\nThank you for your payment. We will ship your order as soon as possible and send the tracking info to this email address. For now, keep this copy of your order details as proof of your payment. \n\n---\n\nITEMS: \n${customer_mail_items_string}\nTOTALS: \nSubtotal: ${formatUSD(order.subtotal)}\nTax: ${formatUSD(order.taxAmount)}\nShipping: ${formatUSD(order.shipping.amount)}\nProcessing: ${formatUSD(order.processing)}\nTOTAL: ${formatUSD(order.total)}${(order.paymentMethod==='XMR')?'\nMONERO TOTAL: '+amt:''}\n\nCONTACT: \n${order.contact.name}\n${order.contact.phone}\n${order.contact.email}\n\nSHIPPING ADDRESS:\n${order.shipping.address.name}\n${order.shipping.address.addr1}${(order.shipping.address.addr2)?'\n'+order.shipping.address.addr2:''}\n${order.shipping.address.city}, ${order.shipping.address.state} ${order.shipping.address.zip}\n\n---\n\nTo view your order info anytime, visit this page: ${process.env.SITE_URL}/shop/order/stripe/?order=${order.id}\n\nFor questions, comments, or to cancel this order, reply to this email or call 719-936-7778 x1. \n\nThank you!\n\n`,
})
console.log(`Sent email ${customer_mail_res.messageId} to customer for order ${order.id}`)
} catch (err) { console.error(err) }

View File

@ -3,6 +3,7 @@ require('dotenv').config()
const mailer = require('../lib/mailer')
const formatUSD = require('../lib/formatUSD')
module.exports = async (order) => {
const amt = (order.paymentMethod==='XMR')?`${order.totalxmr} XMR`:formatUSD(order.total)
const sales_mail_items_string = await order.items.reduce((acc,cur) =>
acc += `${cur.pid}/${cur.sid} ${cur.qty} ${cur.weight} ${cur.volume}\n`
, 'PID/SID qty lbs in³\n')
@ -11,7 +12,7 @@ module.exports = async (order) => {
sales_mail_res = await mailer.sendMail({
from: process.env.SALES_MAIL_FROM,
to: process.env.SALES_EMAIL,
subject: `Order for ${formatUSD(order.total)} processed`,
subject: `Order for ${amt} processed`,
text: `Order ${order.id} needs ${order.items.length} items shipped: \n\n${sales_mail_items_string}\nSHIP TO:\n${order.shipping.address.name}\n${order.shipping.address.addr1}${(order.shipping.address.addr2)?'\n'+order.shipping.address.addr2:''}\n${order.shipping.address.city}, ${order.shipping.address.state} ${order.shipping.address.zip}\n\nCONTACT:\n${order.contact.name}\n${order.contact.phone}\n${order.contact.email}\n`,
})
console.log(`Sent email ${sales_mail_res.messageId} to sales team for order ${order.id}`)

View File

@ -1,13 +1,12 @@
'use strict'
require('dotenv').config()
const axios = require('axios')
module.exports = (order) => {
module.exports = (order) =>
axios.post(
`${process.env.NTFY_DOMAIN}/${process.env.NTFY_TOPIC}`,
`Order ${order.id} needs ${order.items.length} items shipped.`,
{ headers: {
Title: `Order for ${require('../lib/formatUSD')(order.total)} processed`,
Title: `Order for ${(order.paymentMethod==='XMR')?order.totalxmr+' XMR':require('../lib/formatUSD')(order.total)} processed`,
Tags: 'moneybag,package'
} }
)
}

View File

@ -1,37 +1,37 @@
'use strict'
require('dotenv').config()
const fs = require('fs').promises
const express = require('express')
const app = express()
const ORDERS_DIR = `${__dirname}/../orders`
app.listen(process.env.MONERO_LISTENER_PORT)
.post('/', express.json(), async (req) => {
if (req.body.data.object.object==='charge') {
const axios = require('axios')
const CHECK_EVERY = 5 * 60 * 1000 // 5 minutes
// Check if paid
if (!req.body.data.object.paid)
return console.log(`[${req.body.id}] Charge unpaid!`)
let interval
// Get order ID
const orderId = req.body.data.object.metadata.id
if (orderId == null)
return console.error(`[${req.body.id}] Charge has no metadata.id!`)
else
console.log(`[${req.body.id}] Charge paid for order ${orderId}`)
// Get order file
const orderFile = `${ORDERS_DIR}/${orderId}.json`
let order; try {
order = await JSON.parse(await fs.readFile(orderFile))
} catch (err) {
return console.error(`[${req.body.id}] Failed to retrieve order from ${orderFile}:\n${err}`)
}
const xmrPaidCheck = async (order) => {
if (order.paidDate!=null)
return console.error('Already paid')
// Get status from MoneroPay
let res; try {
res = await axios.get(`${process.env.MONEROPAY_URL}/receive/${order.xmr_address}`)
} catch (err) {
return console.error(`Failed to get update about xmr address ${order.xmr_address}\n${err}`)
}
let parsedRes; try {
parsedRes = await JSON.parse(res)
} catch (err) {
return console.error(`Failed to parse JSON\n${err}`)
}
// Check if paid
if (parsedRes.amount.expected<=resData.amount.covered.unlocked) {
console.log(`Order ${order.id} has been paid with ${resData.amount.expected/1000000000000} XMR`)
// Save paidDate to order
const orderFile = `${ORDERS_DIR}/${orderId}.json`
try { order.paidDate = new Date()
fs.writeFile(orderFile, JSON.stringify(order,null,2))
} catch (err) {
console.error(`[${req.body.id}] Failed to write paidDate to ${orderFile}:\n${err}`)
console.error(`Failed to write paidDate to ${orderFile}:\n${err}`)
}
// Email customer
@ -45,7 +45,15 @@ app.listen(process.env.MONERO_LISTENER_PORT)
// Remove single products from store
require('./remove-sid')(order)
}
})
// Remove this listener
clearInterval(interval)
}
}
module.exports = (order) => {
if (order.paymentMethod!=='XMR')
return console.log(`Invalid paymentMethod: ${order.paymentMethod}`)
interval = setInterval(xmrPaidCheck(order), CHECK_EVERY)
}

View File

@ -11,8 +11,7 @@
"serve": "npx @11ty/eleventy --quiet --serve",
"json": "npx @11ty/eleventy --to=json",
"api": "node api/index.js",
"stripe-listener": "node listeners/stripe.js",
"monero-listener": "node listeners/monero.js"
"stripe-listener": "node listeners/stripe.js"
},
"author": {
"name": "Keith Irwin",