From 79d0c2f928e3b9a73d07f30a9ab63468c5f3634b Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 15 May 2020 16:39:40 +0530 Subject: include refund fees in effective refund amount calculation --- src/operations/pay.ts | 1 + src/operations/refund.ts | 31 +++++++++++++++++++++++++++++++ src/operations/transactions.ts | 8 ++++++++ src/types/dbTypes.ts | 5 +++++ 4 files changed, 45 insertions(+) (limited to 'src') diff --git a/src/operations/pay.ts b/src/operations/pay.ts index 20d62dea2..372d012d8 100644 --- a/src/operations/pay.ts +++ b/src/operations/pay.ts @@ -456,6 +456,7 @@ async function recordConfirmPay( refundsDone: {}, refundsFailed: {}, refundsPending: {}, + refundsRefreshCost: {}, }; await ws.db.runWithWriteTransaction( diff --git a/src/operations/refund.ts b/src/operations/refund.ts index cbcb96446..b5d611b07 100644 --- a/src/operations/refund.ts +++ b/src/operations/refund.ts @@ -144,6 +144,8 @@ async function acceptRefundResponse( const unfinishedRefunds: MerchantRefundDetails[] = []; const failedRefunds: MerchantRefundDetails[] = []; + const refundsRefreshCost: { [refundKey: string]: AmountJson } = {}; + for (const rd of refunds) { if (rd.exchange_http_status === 200) { // FIXME: also verify signature if necessary. @@ -158,6 +160,33 @@ async function acceptRefundResponse( } } + for (const rd of [...finishedRefunds, ...unfinishedRefunds]) { + const key = getRefundKey(rd); + const coin = await ws.db.get(Stores.coins, rd.coin_pub); + if (!coin) { + continue; + } + const denom = await ws.db.getIndexed( + Stores.denominations.denomPubHashIndex, + coin.denomPubHash, + ); + if (!denom) { + throw Error("inconsistent database"); + } + const amountLeft = Amounts.sub( + Amounts.add(coin.currentAmount, Amounts.parseOrThrow(rd.refund_amount)) + .amount, + Amounts.parseOrThrow(rd.refund_fee), + ).amount; + const allDenoms = await ws.db + .iterIndex( + Stores.denominations.exchangeBaseUrlIndex, + coin.exchangeBaseUrl, + ) + .toArray(); + refundsRefreshCost[key] = getTotalRefreshCost(allDenoms, denom, amountLeft); + } + const now = getTimestampNow(); await ws.db.runWithWriteTransaction( @@ -282,6 +311,8 @@ async function acceptRefundResponse( console.log("refund query not done"); } + p.refundsRefreshCost = {...p.refundsRefreshCost, ...refundsRefreshCost }; + await tx.put(Stores.purchases, p); const coinsPubsToBeRefreshed = Object.values(refreshCoinsMap); diff --git a/src/operations/transactions.ts b/src/operations/transactions.ts index fd7679621..9e07d4ff5 100644 --- a/src/operations/transactions.ts +++ b/src/operations/transactions.ts @@ -63,6 +63,8 @@ function getRefundStats( .amount; } + // Subtract fees from effective refund amount + for (const rk of Object.keys(pr.refundsDone)) { const perm = pr.refundsDone[rk].perm; if (pr.refundsDone[rk].refundGroupId !== refundGroupId) { @@ -72,6 +74,12 @@ function getRefundStats( amountEffective, Amounts.parseOrThrow(perm.refund_fee), ).amount; + if (pr.refundsRefreshCost[rk]) { + amountEffective = Amounts.sub( + amountEffective, + pr.refundsRefreshCost[rk], + ).amount; + } } for (const rk of Object.keys(pr.refundsFailed)) { diff --git a/src/types/dbTypes.ts b/src/types/dbTypes.ts index 79966eb34..82649d9f6 100644 --- a/src/types/dbTypes.ts +++ b/src/types/dbTypes.ts @@ -1269,6 +1269,11 @@ export interface PurchaseRecord { */ refundsFailed: { [refundKey: string]: RefundInfo }; + /** + * Refresh cost for each refund permission. + */ + refundsRefreshCost: { [refundKey: string]: AmountJson }; + /** * When was the last refund made? * Set to 0 if no refund was made on the purchase. -- cgit v1.2.3