taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit bc8d12e92cd78611cccd4b45c2aa1b70fe1d390b
parent 88408599cc4afd10defcfbd990d2bc729b2fa7e0
Author: Florian Dold <dold@taler.net>
Date:   Sun, 13 Sep 2026 23:22:22 +0200

wallet-core: allow cancelling proposed payments

Advertise Abort while a payment proposal awaits confirmation. This lets
the transaction API reach the existing proposal-refused transition.

Diffstat:
Mpackages/taler-wallet-core/src/pay-merchant.test.ts | 15+++++++++++++++
Mpackages/taler-wallet-core/src/pay-merchant.ts | 8++++++--
2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/packages/taler-wallet-core/src/pay-merchant.test.ts b/packages/taler-wallet-core/src/pay-merchant.test.ts @@ -963,6 +963,21 @@ test("refund retry classification includes timeout and throttling", () => { assert.strictEqual(isTransientRefundStatus(HttpStatusCode.Conflict), false); }); +test("an unpaid proposal can be cancelled before selecting coins", () => { + const purchase = { + purchaseStatus: PurchaseStatus.DialogProposed, + } as WalletPurchase; + assert.ok( + computePayMerchantTransactionActions(purchase).includes( + TransactionAction.Abort, + ), + ); + assert.strictEqual( + getPayMerchantAbortTransition(purchase.purchaseStatus, false), + PurchaseStatus.AbortedProposalRefused, + ); +}); + test("every advertised merchant action has a state transition", () => { const statuses = Object.values(PurchaseStatus).filter( (value): value is PurchaseStatus => typeof value === "number", diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2019-2025 Taler Systems S.A. + (C) 2019-2026 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -4928,7 +4928,11 @@ export function computePayMerchantTransactionActions( return [TransactionAction.Fail, TransactionAction.Resume]; // Dialog States case PurchaseStatus.DialogProposed: - return [TransactionAction.Retry, TransactionAction.Delete]; + return [ + TransactionAction.Retry, + TransactionAction.Abort, + TransactionAction.Delete, + ]; case PurchaseStatus.DialogShared: return [TransactionAction.Retry, TransactionAction.Delete]; case PurchaseStatus.DialogUnclaimed: