From 4ffb4a94e8279896a11d65b66d71beb66ed6d009 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 5 Mar 2024 01:28:30 +0100 Subject: wallet-core: simplify shepherd, handle results of cancelled tasks properly --- packages/taler-wallet-core/src/pay-merchant.ts | 38 ++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'packages/taler-wallet-core/src/pay-merchant.ts') diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts index 8eff7e17b..be3f7f106 100644 --- a/packages/taler-wallet-core/src/pay-merchant.ts +++ b/packages/taler-wallet-core/src/pay-merchant.ts @@ -880,7 +880,11 @@ async function createOrReusePurchase( ); if (oldProposal.purchaseStatus === PurchaseStatus.DialogShared) { const download = await expectProposalDownload(wex, oldProposal); - const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData, false); + const paid = await checkIfOrderIsAlreadyPaid( + wex, + download.contractData, + false, + ); logger.info(`old proposal paid: ${paid}`); if (paid) { // if this transaction was shared and the order is paid then it @@ -1912,6 +1916,11 @@ export async function confirmPay( hintTransactionId: transactionId, }); + const ctx = new PayMerchantTransactionContext(wex, proposalId); + + // In case we're sharing the payment and we're long-polling + wex.taskScheduler.stopShepherdTask(ctx.taskId); + // Wait until we have completed the first attempt to pay. return waitPaymentResult(wex, proposalId); } @@ -2011,7 +2020,11 @@ async function processPurchasePay( const download = await expectProposalDownload(wex, purchase); if (purchase.shared) { - const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData, false); + const paid = await checkIfOrderIsAlreadyPaid( + wex, + download.contractData, + false, + ); if (paid) { const transitionInfo = await wex.db.runReadWriteTx( @@ -2463,17 +2476,24 @@ export async function sharePayment( // FIXME: purchase can be shared before being paid return undefined; } + const oldTxState = computePayMerchantTransactionState(p); if (p.purchaseStatus === PurchaseStatus.DialogProposed) { p.purchaseStatus = PurchaseStatus.DialogShared; p.shared = true; tx.purchases.put(p); } + const newTxState = computePayMerchantTransactionState(p); + return { proposalId: p.proposalId, nonce: p.noncePriv, session: p.lastSessionId ?? p.downloadSessionId, token: p.claimToken, + transitionInfo: { + oldTxState, + newTxState, + }, }; }); @@ -2481,8 +2501,11 @@ export async function sharePayment( throw Error("This purchase can't be shared"); } - // schedule a task to watch for the status const ctx = new PayMerchantTransactionContext(wex, result.proposalId); + + notifyTransition(wex, ctx.transactionId, result.transitionInfo); + + // schedule a task to watch for the status wex.taskScheduler.startShepherdTask(ctx.taskId); const privatePayUri = stringifyPayUri({ @@ -2514,6 +2537,7 @@ async function checkIfOrderIsAlreadyPaid( const resp = await wex.http.fetch(requestUrl.href, { cancellationToken: wex.cancellationToken, }); + if ( resp.status === HttpStatusCode.Ok || resp.status === HttpStatusCode.Accepted || @@ -2539,7 +2563,11 @@ async function processPurchaseDialogShared( return TaskRunResult.finished(); } - const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData, true); + const paid = await checkIfOrderIsAlreadyPaid( + wex, + download.contractData, + true, + ); if (paid) { const transitionInfo = await wex.db.runReadWriteTx( ["purchases"], @@ -2551,7 +2579,7 @@ async function processPurchaseDialogShared( } const oldTxState = computePayMerchantTransactionState(p); p.purchaseStatus = PurchaseStatus.FailedClaim; - p.paidByOther = true + p.paidByOther = true; const newTxState = computePayMerchantTransactionState(p); await tx.purchases.put(p); return { oldTxState, newTxState }; -- cgit v1.2.3