From b3cca3e37bc654d364736db66732a6aa38ccfd84 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 21 Feb 2023 08:25:35 -0800 Subject: credit failed payments --- routes/invoices.js | 2 +- routes/payments.js | 67 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/routes/invoices.js b/routes/invoices.js index 133da057..bbbae760 100644 --- a/routes/invoices.js +++ b/routes/invoices.js @@ -14,7 +14,7 @@ export default { if (invoice) { invoice.user = await g(`user:${invoice.uid}`); invoice.id = hash; - } else { + } else if(config.classic) { invoice = await got(`${config.classic}/invoice/${hash}`).json(); if (!invoice) fail("invoice not found"); invoice.id = invoice.uuid; diff --git a/routes/payments.js b/routes/payments.js index 51172251..e0372092 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -32,7 +32,7 @@ export default { await got .post(`${config.classic}/admin/credit`, { json: { username, amount, source }, - headers: { authorization: `Bearer ${config.admin}` }, + headers: { authorization: `Bearer ${config.admin}` } }) .json(); } else if (payreq) { @@ -53,15 +53,27 @@ export default { types.lightning ); - let r = await ln.pay(payreq, msatoshi ? undefined : `${amount}sats`); - - p.amount = -amount; - p.hash = r.payment_hash; - p.fee = Math.round((r.msatoshi_sent - r.msatoshi) / 1000); - p.ref = r.payment_preimage; - - await s(`payment:${p.id}`, p); - await db.incrBy(`balance:${p.uid}`, maxfee - p.fee); + let r; + try { + r = await ln.pay(payreq, msatoshi ? undefined : `${amount}sats`); + + p.amount = -amount; + p.hash = r.payment_hash; + p.fee = Math.round((r.msatoshi_sent - r.msatoshi) / 1000); + p.ref = r.payment_preimage; + + await s(`payment:${p.id}`, p); + await db.incrBy(`balance:${p.uid}`, maxfee - p.fee); + } catch (e) { + if (!(r && r.status === "complete")) { + let credit = Math.round(amount * config.fee) - p.ourfee; + await db.incrBy(`balance:${p.uid}`, amount + maxfee + p.ourfee); + await db.incrBy(`credit:${types.lightning}:${p.uid}`, credit); + await db.lRem(`${p.uid}:payments`, 0, p.id); + await db.del(`payment:${p.id}`); + } + throw e; + } } } @@ -88,7 +100,7 @@ export default { let payments = (await db.lRange(`${id}:payments`, 0, -1)) || []; payments = ( await Promise.all( - payments.map(async (id) => { + payments.map(async id => { let p = await g(`payment:${id}`); if (p.created < start || p.created > end) return; if (p.type === types.internal) p.with = await g(`user:${p.ref}`); @@ -96,7 +108,7 @@ export default { }) ) ) - .filter((p) => p) + .filter(p => p) .sort((a, b) => b.created - a.created); let total = payments.length; @@ -123,7 +135,7 @@ export default { let twoWeeksAgo = new Date(new Date().setDate(new Date().getDate() - 14)); let decoded = await ln.decodepay(payreq); let { msatoshi, payee } = decoded; - let node = nodes.find((n) => n.nodeid === payee); + let node = nodes.find(n => n.nodeid === payee); let alias = node ? node.alias : payee.substr(0, 12); res.send({ alias, amount: Math.round(msatoshi / 1000) }); @@ -133,13 +145,13 @@ export default { let amount = await g(`pot:${name}`); if (!amount) fail("pot not found"); let payments = (await db.lRange(`pot:${name}:payments`, 0, -1)) || []; - payments = await Promise.all(payments.map((hash) => g(`payment:${hash}`))); + payments = await Promise.all(payments.map(hash => g(`payment:${hash}`))); await Promise.all( - payments.map(async (p) => (p.user = await g(`user:${p.uid}`))) + payments.map(async p => (p.user = await g(`user:${p.uid}`))) ); - payments = payments.filter((p) => p); + payments = payments.filter(p => p); res.send({ amount, payments }); }, @@ -147,13 +159,16 @@ export default { amount = parseInt(amount); await t(`pot:${name}`, async (balance, db) => { if (balance < amount) fail("Insufficient funds"); - await db.multi().decrBy(`pot:${name}`, amount).exec(); + await db + .multi() + .decrBy(`pot:${name}`, amount) + .exec(); }); let hash = v4(); await s(`invoice:${hash}`, { uid: user.id, - received: 0, + received: 0 }); let payment = await credit(hash, amount, "", name, types.pot); @@ -196,7 +211,7 @@ export default { let tx = await bc.fundRawTransaction(raw, { feeRate, subtractFeeFromOutputs, - replaceable, + replaceable }); if (config.bitcoin.walletpass) @@ -235,7 +250,7 @@ export default { for (let { scriptPubKey: { address }, - value, + value } of tx.vout) { total += sats(value); if ( @@ -266,13 +281,13 @@ export default { "card[number]": number, "card[exp_month]": month, "card[exp_year]": year, - "card[cvc]": cvc, + "card[cvc]": cvc }; let { id: source } = await got .post(`${stripe}/tokens`, { form, - username, + username }) .json(); @@ -281,13 +296,13 @@ export default { amount, currency, source, - description: "starter coupon", + description: "starter coupon" }; let r = await got .post(`${stripe}/charges`, { form, - username, + username }) .json(); @@ -297,7 +312,7 @@ export default { let memo = "stripe"; await s(`invoice:${hash}`, { uid: user.id, - received: 0, + received: 0 }); amount = sats(amount / store.rates[currency]); let uid = await g("user:coinos"); @@ -307,5 +322,5 @@ export default { } else fail("Card payment failed"); res.send({ status }); - }, + } }; -- cgit v1.2.3