taler-typescript-core

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

commit 36d437f59772497b562bd34f3c5d34259d282f0b
parent c970593ca94063d91495a359390a3fa3b51be682
Author: Florian Dold <dold@taler.net>
Date:   Thu,  3 Sep 2026 15:41:17 +0200

wallet-core: submit a shared payment even if the order reads paid

The coins are already spent; only the /pay response tells whether the
payment was ours or another wallet's, and the already-paid reply
carries the refund permissions that recover the contributions.

Diffstat:
Mpackages/taler-wallet-core/src/pay-merchant.ts | 24+++++-------------------
1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts @@ -3890,30 +3890,16 @@ async function processPurchasePay( const download = await expectProposalDownload(wex, purchase); if (isSharedPurchase(purchase)) { + // Only a deleted order is decided here. An order the merchant reports + // as paid is still submitted: our coins are already spent, and only + // the /pay response says whether the payment was ours (the merchant + // replays the signature) or somebody else's (409 already-paid, whose + // refund permissions recover the contributions). const orderStatus = await checkIfOrderIsAlreadyPaid(wex, download, false); if (orderStatus === "gone") { return abortPayForDeletedOrder(wex, ctx); } - - if (orderStatus === "paid") { - await wex.runWalletDbTx(async (tx) => { - const [p, h] = await ctx.getRecordHandle(tx); - if (!p) { - return; - } - p.purchaseStatus = PurchaseStatus.FailedPaidByOther; - await h.update(p, "pay-paid-by-other"); - }); - - return { - type: TaskRunResultType.Error, - errorDetail: makeErrorDetail(TalerErrorCode.WALLET_ORDER_ALREADY_PAID, { - orderId: purchase.orderId, - fulfillmentUrl: download.contractTerms.fulfillment_url, - }), - }; - } } const choiceIndex = purchase.choiceIndex;