From 165486a11268ab3d8009506916cd22d233cd248b Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sat, 7 Dec 2019 18:42:18 +0100 Subject: auto-refund --- src/wallet-impl/pay.ts | 45 ++++++++++++++++++++++++++++++++++++++++----- src/wallet-impl/tip.ts | 4 ++-- 2 files changed, 42 insertions(+), 7 deletions(-) (limited to 'src/wallet-impl') diff --git a/src/wallet-impl/pay.ts b/src/wallet-impl/pay.ts index 7076f905d..c39feeec3 100644 --- a/src/wallet-impl/pay.ts +++ b/src/wallet-impl/pay.ts @@ -62,6 +62,8 @@ import { strcmp, canonicalJson, extractTalerStampOrThrow, + extractTalerDurationOrThrow, + extractTalerDuration, } from "../util/helpers"; import { Logger } from "../util/logging"; import { InternalWalletState } from "./state"; @@ -359,6 +361,7 @@ async function recordConfirmPay( lastRefundApplyError: undefined, refundApplyRetryInfo: initRetryInfo(), firstSuccessfulPayTimestamp: undefined, + autoRefundDeadline: undefined, }; await runWithWriteTransaction( @@ -704,9 +707,23 @@ export async function submitPay( // FIXME: properly display error throw Error("merchant payment signature invalid"); } + const isFirst = purchase.firstSuccessfulPayTimestamp === undefined; purchase.firstSuccessfulPayTimestamp = getTimestampNow(); purchase.lastPayError = undefined; purchase.payRetryInfo = initRetryInfo(false); + if (isFirst) { + const ar = purchase.contractTerms.auto_refund; + if (ar) { + const autoRefundDelay = extractTalerDuration(ar); + if (autoRefundDelay) { + purchase.refundStatusRequested = true; + purchase.autoRefundDeadline = { + t_ms: getTimestampNow().t_ms + autoRefundDelay.d_ms, + } + } + } + } + const modifiedCoins: CoinRecord[] = []; for (const pc of purchase.payReq.coins) { const c = await oneShotGet(ws.db, Stores.coins, pc.coin_pub); @@ -1064,11 +1081,6 @@ async function acceptRefundResponse( return; } - p.lastRefundStatusTimestamp = getTimestampNow(); - p.lastRefundStatusError = undefined; - p.refundStatusRetryInfo = initRetryInfo(); - p.refundStatusRequested = false; - for (const perm of refundPermissions) { if ( !p.refundsPending[perm.merchant_sig] && @@ -1079,6 +1091,29 @@ async function acceptRefundResponse( } } + // Are we done with querying yet, or do we need to do another round + // after a retry delay? + let queryDone = true; + + if (numNewRefunds === 0) { + if (p.autoRefundDeadline && p.autoRefundDeadline.t_ms < getTimestampNow().t_ms) { + queryDone = false; + } + } + + if (queryDone) { + p.lastRefundStatusTimestamp = getTimestampNow(); + p.lastRefundStatusError = undefined; + p.refundStatusRetryInfo = initRetryInfo(); + p.refundStatusRequested = false; + } else { + // No error, but we need to try again! + p.lastRefundStatusTimestamp = getTimestampNow(); + p.refundStatusRetryInfo.retryCounter++; + updateRetryInfoTimeout(p.refundStatusRetryInfo); + p.lastRefundStatusError = undefined; + } + if (numNewRefunds) { p.lastRefundApplyError = undefined; p.refundApplyRetryInfo = initRetryInfo(); diff --git a/src/wallet-impl/tip.ts b/src/wallet-impl/tip.ts index 9cfaed930..11e029fcd 100644 --- a/src/wallet-impl/tip.ts +++ b/src/wallet-impl/tip.ts @@ -23,7 +23,7 @@ import { TipPickupGetResponse, TipPlanchetDetail, TipResponse } from "../talerTy import * as Amounts from "../util/amounts"; import { Stores, PlanchetRecord, WithdrawalSessionRecord, initRetryInfo, updateRetryInfoTimeout } from "../dbTypes"; import { getWithdrawDetailsForAmount, getVerifiedWithdrawDenomList, processWithdrawSession } from "./withdraw"; -import { getTalerStampSec } from "../util/helpers"; +import { getTalerStampSec, extractTalerStampOrThrow } from "../util/helpers"; import { updateExchangeFromUrl } from "./exchanges"; import { getRandomBytes, encodeCrock } from "../crypto/talerCrypto"; import { guardOperationException } from "./errors"; @@ -68,7 +68,7 @@ export async function getTipStatus( tipId, accepted: false, amount, - deadline: getTalerStampSec(tipPickupStatus.stamp_expire)!, + deadline: extractTalerStampOrThrow(tipPickupStatus.stamp_expire), exchangeUrl: tipPickupStatus.exchange_url, merchantBaseUrl: res.merchantBaseUrl, nextUrl: undefined, -- cgit v1.2.3