summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-09-06 18:17:12 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-09-06 18:17:12 +0530
commitc0861f0690425308e3e4126093f4edb2b105e64a (patch)
treed57074e18977159fb4883a14f92075dc59232b24 /packages/taler-wallet-core/src/operations
parentcde4d13df8d9af64eccc82dd13965f2045c8f78c (diff)
downloadwallet-core-c0861f0690425308e3e4126093f4edb2b105e64a.tar.gz
wallet-core-c0861f0690425308e3e4126093f4edb2b105e64a.tar.bz2
wallet-core-c0861f0690425308e3e4126093f4edb2b105e64a.zip
handle permanent refund failure
Diffstat (limited to 'packages/taler-wallet-core/src/operations')
-rw-r--r--packages/taler-wallet-core/src/operations/refund.ts60
1 files changed, 57 insertions, 3 deletions
diff --git a/packages/taler-wallet-core/src/operations/refund.ts b/packages/taler-wallet-core/src/operations/refund.ts
index 373e17a10..0c89e5241 100644
--- a/packages/taler-wallet-core/src/operations/refund.ts
+++ b/packages/taler-wallet-core/src/operations/refund.ts
@@ -47,8 +47,6 @@ import {
MerchantCoinRefundStatus,
MerchantCoinRefundSuccessStatus,
MerchantCoinRefundFailureStatus,
- codecForMerchantOrderStatusPaid,
- AmountString,
codecForMerchantOrderRefundPickupResponse,
} from "../types/talerTypes";
import { guardOperationException } from "./errors";
@@ -202,6 +200,56 @@ async function storePendingRefund(
};
}
+async function storeFailedRefund(
+ tx: TransactionHandle,
+ p: PurchaseRecord,
+ r: MerchantCoinRefundFailureStatus,
+): Promise<void> {
+ const refundKey = getRefundKey(r);
+
+ const coin = await tx.get(Stores.coins, r.coin_pub);
+ if (!coin) {
+ console.warn("coin not found, can't apply refund");
+ return;
+ }
+ const denom = await tx.getIndexed(
+ Stores.denominations.denomPubHashIndex,
+ coin.denomPubHash,
+ );
+
+ if (!denom) {
+ throw Error("inconsistent database");
+ }
+
+ const allDenoms = await tx
+ .iterIndexed(
+ Stores.denominations.exchangeBaseUrlIndex,
+ coin.exchangeBaseUrl,
+ )
+ .toArray();
+
+ const amountLeft = Amounts.sub(
+ Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount))
+ .amount,
+ denom.feeRefund,
+ ).amount;
+
+ const totalRefreshCostBound = getTotalRefreshCost(
+ allDenoms,
+ denom,
+ amountLeft,
+ );
+
+ p.refunds[refundKey] = {
+ type: RefundState.Failed,
+ obtainedTime: getTimestampNow(),
+ executionTime: r.execution_time,
+ refundAmount: Amounts.parseOrThrow(r.refund_amount),
+ refundFee: denom.feeRefund,
+ totalRefreshCostBound,
+ };
+}
+
async function acceptRefunds(
ws: InternalWalletState,
proposalId: string,
@@ -232,6 +280,10 @@ async function acceptRefunds(
const refundKey = getRefundKey(refundStatus);
const existingRefundInfo = p.refunds[refundKey];
+ const isPermanentFailure =
+ refundStatus.type === "failure" &&
+ refundStatus.exchange_status === 410;
+
// Already failed.
if (existingRefundInfo?.type === RefundState.Failed) {
continue;
@@ -244,7 +296,7 @@ async function acceptRefunds(
// Still pending.
if (
- refundStatus.type === "failure" &&
+ refundStatus.type === "failure" && !isPermanentFailure &&
existingRefundInfo?.type === RefundState.Pending
) {
continue;
@@ -254,6 +306,8 @@ async function acceptRefunds(
if (refundStatus.type === "success") {
await applySuccessfulRefund(tx, p, refreshCoinsMap, refundStatus);
+ } else if (isPermanentFailure) {
+ await storeFailedRefund(tx, p, refundStatus);
} else {
await storePendingRefund(tx, p, refundStatus);
}