aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/pay-merchant.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/pay-merchant.ts')
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts73
1 files changed, 55 insertions, 18 deletions
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
index 5e01ae716..09e9e1fb3 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -103,8 +103,8 @@ import {
DbRetryInfo,
PendingTaskType,
spendCoins,
- TaskId,
TaskIdentifiers,
+ TaskIdStr,
TaskRunResult,
TaskRunResultType,
TombstoneTag,
@@ -150,7 +150,7 @@ const logger = new Logger("pay-merchant.ts");
export class PayMerchantTransactionContext implements TransactionContext {
readonly transactionId: TransactionIdStr;
- readonly taskId: TaskId;
+ readonly taskId: TaskIdStr;
constructor(
public ws: InternalWalletState,
@@ -391,7 +391,8 @@ export class PayMerchantTransactionContext implements TransactionContext {
}
export class RefundTransactionContext implements TransactionContext {
- public transactionId: string;
+ public transactionId: TransactionIdStr;
+ public taskId: TaskIdStr | undefined = undefined;
constructor(
public ws: InternalWalletState,
public refundGroupId: string,
@@ -612,6 +613,7 @@ export function extractContractData(
async function processDownloadProposal(
ws: InternalWalletState,
proposalId: string,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposal = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
return await tx.purchases.get(proposalId);
@@ -662,6 +664,7 @@ async function processDownloadProposal(
method: "POST",
body: requestBody,
timeout: getProposalRequestTimeout(retryRecord?.retryInfo),
+ cancellationToken,
});
const r = await readSuccessResponseJsonOrErrorCode(
httpResponse,
@@ -861,6 +864,7 @@ async function createOrReusePurchase(
sessionId: string | undefined,
claimToken: string | undefined,
noncePriv: string | undefined,
+ cancellationToken: CancellationToken,
): Promise<string> {
const oldProposals = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.indexes.byUrlAndOrderId.getAll([
@@ -891,7 +895,11 @@ async function createOrReusePurchase(
);
if (oldProposal.purchaseStatus === PurchaseStatus.DialogShared) {
const download = await expectProposalDownload(ws, oldProposal);
- const paid = await checkIfOrderIsAlreadyPaid(ws, download.contractData);
+ const paid = await checkIfOrderIsAlreadyPaid(
+ ws,
+ download.contractData,
+ cancellationToken,
+ );
logger.info(`old proposal paid: ${paid}`);
if (paid) {
// if this transaction was shared and the order is paid then it
@@ -1466,6 +1474,7 @@ export async function preparePayForUri(
uriResult.sessionId,
uriResult.claimToken,
uriResult.noncePriv,
+ CancellationToken.CONTINUE,
);
await waitProposalDownloaded(ws, proposalId);
@@ -1951,20 +1960,20 @@ export async function processPurchase(
switch (purchase.purchaseStatus) {
case PurchaseStatus.PendingDownloadingProposal:
- return processDownloadProposal(ws, proposalId);
+ return processDownloadProposal(ws, proposalId, cancellationToken);
case PurchaseStatus.PendingPaying:
case PurchaseStatus.PendingPayingReplay:
- return processPurchasePay(ws, proposalId);
+ return processPurchasePay(ws, proposalId, cancellationToken);
case PurchaseStatus.PendingQueryingRefund:
- return processPurchaseQueryRefund(ws, purchase);
+ return processPurchaseQueryRefund(ws, purchase, cancellationToken);
case PurchaseStatus.PendingQueryingAutoRefund:
- return processPurchaseAutoRefund(ws, purchase);
+ return processPurchaseAutoRefund(ws, purchase, cancellationToken);
case PurchaseStatus.AbortingWithRefund:
- return processPurchaseAbortingRefund(ws, purchase);
+ return processPurchaseAbortingRefund(ws, purchase, cancellationToken);
case PurchaseStatus.PendingAcceptRefund:
- return processPurchaseAcceptRefund(ws, purchase);
+ return processPurchaseAcceptRefund(ws, purchase, cancellationToken);
case PurchaseStatus.DialogShared:
- return processPurchaseDialogShared(ws, purchase);
+ return processPurchaseDialogShared(ws, purchase, cancellationToken);
case PurchaseStatus.FailedClaim:
case PurchaseStatus.Done:
case PurchaseStatus.DoneRepurchaseDetected:
@@ -1990,6 +1999,7 @@ export async function processPurchase(
async function processPurchasePay(
ws: InternalWalletState,
proposalId: string,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const purchase = await ws.db.runReadOnlyTx(["purchases"], async (tx) => {
return tx.purchases.get(proposalId);
@@ -2024,7 +2034,11 @@ async function processPurchasePay(
const download = await expectProposalDownload(ws, purchase);
if (purchase.shared) {
- const paid = await checkIfOrderIsAlreadyPaid(ws, download.contractData);
+ const paid = await checkIfOrderIsAlreadyPaid(
+ ws,
+ download.contractData,
+ cancellationToken,
+ );
if (paid) {
const transitionInfo = await ws.db.runReadWriteTx(
@@ -2088,6 +2102,7 @@ async function processPurchasePay(
method: "POST",
body: reqBody,
timeout: getPayRequestTimeout(purchase),
+ cancellationToken,
}),
);
@@ -2163,7 +2178,11 @@ async function processPurchasePay(
};
logger.trace(`/paid request body: ${j2s(reqBody)}`);
const resp = await ws.runSequentialized([EXCHANGE_COINS_LOCK], () =>
- ws.http.fetch(payAgainUrl, { method: "POST", body: reqBody }),
+ ws.http.fetch(payAgainUrl, {
+ method: "POST",
+ body: reqBody,
+ cancellationToken,
+ }),
);
logger.trace(`/paid response status: ${resp.status}`);
if (
@@ -2499,6 +2518,7 @@ export async function sharePayment(
async function checkIfOrderIsAlreadyPaid(
ws: InternalWalletState,
contract: WalletContractData,
+ cancellationToken: CancellationToken,
) {
const requestUrl = new URL(
`orders/${contract.orderId}`,
@@ -2508,7 +2528,9 @@ async function checkIfOrderIsAlreadyPaid(
requestUrl.searchParams.set("timeout_ms", "1000");
- const resp = await ws.http.fetch(requestUrl.href);
+ const resp = await ws.http.fetch(requestUrl.href, {
+ cancellationToken,
+ });
if (
resp.status === HttpStatusCode.Ok ||
resp.status === HttpStatusCode.Accepted ||
@@ -2518,13 +2540,14 @@ async function checkIfOrderIsAlreadyPaid(
} else if (resp.status === HttpStatusCode.PaymentRequired) {
return false;
}
- //forbidden, not found, not acceptable
+ // forbidden, not found, not acceptable
throw Error(`this order cant be paid: ${resp.status}`);
}
async function processPurchaseDialogShared(
ws: InternalWalletState,
purchase: PurchaseRecord,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
logger.trace(`processing dialog-shared for proposal ${proposalId}`);
@@ -2534,7 +2557,11 @@ async function processPurchaseDialogShared(
return TaskRunResult.finished();
}
- const paid = await checkIfOrderIsAlreadyPaid(ws, download.contractData);
+ const paid = await checkIfOrderIsAlreadyPaid(
+ ws,
+ download.contractData,
+ cancellationToken,
+ );
if (paid) {
const transitionInfo = await ws.db.runReadWriteTx(
["purchases"],
@@ -2565,6 +2592,7 @@ async function processPurchaseDialogShared(
async function processPurchaseAutoRefund(
ws: InternalWalletState,
purchase: PurchaseRecord,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
logger.trace(`processing auto-refund for proposal ${proposalId}`);
@@ -2624,7 +2652,9 @@ async function processPurchaseAutoRefund(
requestUrl.searchParams.set("timeout_ms", "1000");
requestUrl.searchParams.set("await_refund_obtained", "yes");
- const resp = await ws.http.fetch(requestUrl.href);
+ const resp = await ws.http.fetch(requestUrl.href, {
+ cancellationToken,
+ });
// FIXME: Check other status codes!
@@ -2661,6 +2691,7 @@ async function processPurchaseAutoRefund(
async function processPurchaseAbortingRefund(
ws: InternalWalletState,
purchase: PurchaseRecord,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
const download = await expectProposalDownload(ws, purchase);
@@ -2701,6 +2732,7 @@ async function processPurchaseAbortingRefund(
const abortHttpResp = await ws.http.fetch(requestUrl.href, {
method: "POST",
body: abortReq,
+ cancellationToken,
});
if (abortHttpResp.status === HttpStatusCode.NotFound) {
@@ -2753,6 +2785,7 @@ async function processPurchaseAbortingRefund(
async function processPurchaseQueryRefund(
ws: InternalWalletState,
purchase: PurchaseRecord,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const proposalId = purchase.proposalId;
logger.trace(`processing query-refund for proposal ${proposalId}`);
@@ -2768,7 +2801,9 @@ async function processPurchaseQueryRefund(
download.contractData.contractTermsHash,
);
- const resp = await ws.http.fetch(requestUrl.href);
+ const resp = await ws.http.fetch(requestUrl.href, {
+ cancellationToken,
+ });
const orderStatus = await readSuccessResponseJsonOrThrow(
resp,
codecForMerchantOrderStatusPaid(),
@@ -2834,6 +2869,7 @@ async function processPurchaseQueryRefund(
async function processPurchaseAcceptRefund(
ws: InternalWalletState,
purchase: PurchaseRecord,
+ cancellationToken: CancellationToken,
): Promise<TaskRunResult> {
const download = await expectProposalDownload(ws, purchase);
@@ -2849,6 +2885,7 @@ async function processPurchaseAcceptRefund(
body: {
h_contract: download.contractData.contractTermsHash,
},
+ cancellationToken,
});
const refundResponse = await readSuccessResponseJsonOrThrow(