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:
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: