summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-04-16 15:07:22 -0300
committerSebastian <sebasjm@gmail.com>2024-04-16 15:07:22 -0300
commitd5b7c732df6c0181c90d17b9550902961a78727b (patch)
tree3ca996f192eb969333898d2710304b688921f804
parent20dcf05e4216b8e71a3d024aa248789ad514a3a8 (diff)
downloadwallet-core-d5b7c732df6c0181c90d17b9550902961a78727b.tar.gz
wallet-core-d5b7c732df6c0181c90d17b9550902961a78727b.tar.bz2
wallet-core-d5b7c732df6c0181c90d17b9550902961a78727b.zip
fix #8746
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts52
-rw-r--r--packages/taler-wallet-core/src/shepherd.ts11
2 files changed, 48 insertions, 15 deletions
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
index 80e88337e..e08f23beb 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -2752,14 +2752,36 @@ async function processPurchaseAutoRefund(
const download = await expectProposalDownload(wex, purchase);
- if (
- !purchase.autoRefundDeadline ||
- AbsoluteTime.isExpired(
- AbsoluteTime.fromProtocolTimestamp(
- timestampProtocolFromDb(purchase.autoRefundDeadline),
- ),
- )
- ) {
+ const noAutoRefundOrExpired = !purchase.autoRefundDeadline ||
+ AbsoluteTime.isExpired(
+ AbsoluteTime.fromProtocolTimestamp(
+ timestampProtocolFromDb(purchase.autoRefundDeadline),
+ ),
+ )
+
+ const totalKnownRefund = await wex.db.runReadOnlyTx(
+ ["refundGroups"],
+ async (tx) => {
+ const refunds = await tx.refundGroups.indexes.byProposalId.getAll(
+ purchase.proposalId,
+ );
+ const am = Amounts.parseOrThrow(download.contractData.amount);
+ return refunds.reduce((prev, cur) => {
+ if (
+ cur.status === RefundGroupStatus.Done ||
+ cur.status === RefundGroupStatus.Pending
+ ) {
+ return Amounts.add(prev, cur.amountEffective).amount;
+ }
+ return prev;
+ }, Amounts.zeroOfAmount(am));
+ },
+ );
+
+ const refundedIsLessThanPrice = Amounts.cmp(download.contractData.amount, totalKnownRefund) === +1
+ const nothingMoreToRefund = !refundedIsLessThanPrice
+
+ if (noAutoRefundOrExpired || nothingMoreToRefund) {
const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
async (tx) => {
@@ -2792,8 +2814,9 @@ async function processPurchaseAutoRefund(
download.contractData.contractTermsHash,
);
- requestUrl.searchParams.set("timeout_ms", "1000");
+ requestUrl.searchParams.set("timeout_ms", "10000");
requestUrl.searchParams.set("await_refund_obtained", "yes");
+ requestUrl.searchParams.set("refund", Amounts.stringify(totalKnownRefund));
const resp = await wex.http.fetch(requestUrl.href, {
cancellationToken: wex.cancellationToken,
@@ -3344,9 +3367,20 @@ async function storeRefunds(
}
const oldTxState = computePayMerchantTransactionState(myPurchase);
+
+ const shouldCheckAutoRefund =
+ myPurchase.autoRefundDeadline &&
+ !AbsoluteTime.isExpired(
+ AbsoluteTime.fromProtocolTimestamp(
+ timestampProtocolFromDb(myPurchase.autoRefundDeadline),
+ ),
+ );
+
if (numPendingItemsTotal === 0) {
if (isAborting) {
myPurchase.purchaseStatus = PurchaseStatus.AbortedRefunded;
+ } else if (shouldCheckAutoRefund) {
+ myPurchase.purchaseStatus = PurchaseStatus.PendingQueryingAutoRefund;
} else {
myPurchase.purchaseStatus = PurchaseStatus.Done;
}
diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts
index b2722ce1d..58bdcf0dd 100644
--- a/packages/taler-wallet-core/src/shepherd.ts
+++ b/packages/taler-wallet-core/src/shepherd.ts
@@ -237,7 +237,7 @@ export class TaskSchedulerImpl implements TaskScheduler {
*
* Mostly useful to interrupt all waits when time-travelling.
*/
- reload() {
+ reload(): void {
this.ensureRunning();
const tasksIds = [...this.sheps.keys()];
logger.info(`reloading sheperd with ${tasksIds.length} tasks`);
@@ -372,9 +372,8 @@ export class TaskSchedulerImpl implements TaskScheduler {
taskId,
res.errorDetail,
);
- let delay: Duration;
const t = timestampAbsoluteFromDb(retryRecord.retryInfo.nextRetry);
- delay = AbsoluteTime.remaining(t);
+ const delay = AbsoluteTime.remaining(t);
logger.trace(`Waiting for ${delay.d_ms} ms`);
await this.wait(taskId, info, delay);
break;
@@ -382,9 +381,8 @@ export class TaskSchedulerImpl implements TaskScheduler {
case TaskRunResultType.Backoff: {
logger.trace(`Shepherd for ${taskId} got backoff result.`);
const retryRecord = await storePendingTaskPending(this.ws, taskId);
- let delay: Duration;
const t = timestampAbsoluteFromDb(retryRecord.retryInfo.nextRetry);
- delay = AbsoluteTime.remaining(t);
+ const delay = AbsoluteTime.remaining(t);
logger.trace(`Waiting for ${delay.d_ms} ms`);
await this.wait(taskId, info, delay);
break;
@@ -396,13 +394,14 @@ export class TaskSchedulerImpl implements TaskScheduler {
await storeTaskProgress(this.ws, taskId);
break;
}
- case TaskRunResultType.ScheduleLater:
+ case TaskRunResultType.ScheduleLater: {
logger.trace(`Shepherd for ${taskId} got schedule-later result.`);
await storeTaskProgress(this.ws, taskId);
const delay = AbsoluteTime.remaining(res.runAt);
logger.trace(`Waiting for ${delay.d_ms} ms`);
await this.wait(taskId, info, delay);
break;
+ }
case TaskRunResultType.Finished:
logger.trace(`Shepherd for ${taskId} got finished result.`);
await storePendingTaskFinished(this.ws, taskId);