summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations/pay-merchant.ts
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-05-30 09:33:32 +0200
committerFlorian Dold <florian@dold.me>2023-05-30 09:33:38 +0200
commit0323067c0757262084e16a9bba9d58bcd773fc23 (patch)
tree667a0e03825e40189b7ec9d84eb7a8b99ccad997 /packages/taler-wallet-core/src/operations/pay-merchant.ts
parent246f914ca62906b463dfe98e834b5ade379a97e0 (diff)
downloadwallet-core-0323067c0757262084e16a9bba9d58bcd773fc23.tar.gz
wallet-core-0323067c0757262084e16a9bba9d58bcd773fc23.tar.bz2
wallet-core-0323067c0757262084e16a9bba9d58bcd773fc23.zip
wallet-core: add missing resume/suspend implementations
Diffstat (limited to 'packages/taler-wallet-core/src/operations/pay-merchant.ts')
-rw-r--r--packages/taler-wallet-core/src/operations/pay-merchant.ts179
1 files changed, 147 insertions, 32 deletions
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts
index 4ea41c695..30c75f695 100644
--- a/packages/taler-wallet-core/src/operations/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts
@@ -131,6 +131,7 @@ import {
import {
constructTransactionIdentifier,
notifyTransition,
+ stopLongpolling,
} from "./transactions.js";
/**
@@ -339,7 +340,7 @@ async function processDownloadProposal(
};
}
- if (proposal.purchaseStatus != PurchaseStatus.DownloadingProposal) {
+ if (proposal.purchaseStatus != PurchaseStatus.PendingDownloadingProposal) {
return {
type: OperationAttemptResultType.Finished,
result: undefined,
@@ -516,7 +517,7 @@ async function processDownloadProposal(
if (!p) {
return;
}
- if (p.purchaseStatus !== PurchaseStatus.DownloadingProposal) {
+ if (p.purchaseStatus !== PurchaseStatus.PendingDownloadingProposal) {
return;
}
const oldTxState = computePayMerchantTransactionState(p);
@@ -626,7 +627,7 @@ async function createPurchase(
merchantBaseUrl,
orderId,
proposalId: proposalId,
- purchaseStatus: PurchaseStatus.DownloadingProposal,
+ purchaseStatus: PurchaseStatus.PendingDownloadingProposal,
repurchaseProposalId: undefined,
downloadSessionId: sessionId,
autoRefundDeadline: undefined,
@@ -699,7 +700,7 @@ async function storeFirstPaySuccess(
return;
}
const oldTxState = computePayMerchantTransactionState(purchase);
- if (purchase.purchaseStatus === PurchaseStatus.Paying) {
+ if (purchase.purchaseStatus === PurchaseStatus.PendingPaying) {
purchase.purchaseStatus = PurchaseStatus.Done;
}
purchase.timestampFirstSuccessfulPay = now;
@@ -721,7 +722,7 @@ async function storeFirstPaySuccess(
if (protoAr) {
const ar = Duration.fromTalerProtocolDuration(protoAr);
logger.info("auto_refund present");
- purchase.purchaseStatus = PurchaseStatus.QueryingAutoRefund;
+ purchase.purchaseStatus = PurchaseStatus.PendingQueryingAutoRefund;
purchase.autoRefundDeadline = AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(AbsoluteTime.now(), ar),
);
@@ -760,8 +761,8 @@ async function storePayReplaySuccess(
}
const oldTxState = computePayMerchantTransactionState(purchase);
if (
- purchase.purchaseStatus === PurchaseStatus.Paying ||
- purchase.purchaseStatus === PurchaseStatus.PayingReplay
+ purchase.purchaseStatus === PurchaseStatus.PendingPaying ||
+ purchase.purchaseStatus === PurchaseStatus.PendingPayingReplay
) {
purchase.purchaseStatus = PurchaseStatus.Done;
}
@@ -1058,7 +1059,7 @@ export async function checkPaymentByProposalId(
}
const oldTxState = computePayMerchantTransactionState(p);
p.lastSessionId = sessionId;
- p.purchaseStatus = PurchaseStatus.PayingReplay;
+ p.purchaseStatus = PurchaseStatus.PendingPayingReplay;
await tx.purchases.put(p);
const newTxState = computePayMerchantTransactionState(p);
return { oldTxState, newTxState };
@@ -1098,8 +1099,8 @@ export async function checkPaymentByProposalId(
} else {
const paid =
purchase.purchaseStatus === PurchaseStatus.Done ||
- purchase.purchaseStatus === PurchaseStatus.QueryingRefund ||
- purchase.purchaseStatus === PurchaseStatus.QueryingAutoRefund;
+ purchase.purchaseStatus === PurchaseStatus.PendingQueryingRefund ||
+ purchase.purchaseStatus === PurchaseStatus.PendingQueryingAutoRefund;
const download = await expectProposalDownload(ws, purchase);
return {
status: PreparePayResultType.AlreadyConfirmed,
@@ -1348,7 +1349,7 @@ export async function confirmPay(
logger.trace(`changing session ID to ${sessionIdOverride}`);
purchase.lastSessionId = sessionIdOverride;
if (purchase.purchaseStatus === PurchaseStatus.Done) {
- purchase.purchaseStatus = PurchaseStatus.PayingReplay;
+ purchase.purchaseStatus = PurchaseStatus.PendingPayingReplay;
}
await tx.purchases.put(purchase);
}
@@ -1424,7 +1425,7 @@ export async function confirmPay(
};
p.lastSessionId = sessionId;
p.timestampAccept = TalerPreciseTimestamp.now();
- p.purchaseStatus = PurchaseStatus.Paying;
+ p.purchaseStatus = PurchaseStatus.PendingPaying;
await tx.purchases.put(p);
await spendCoins(ws, tx, {
//`txn:proposal:${p.proposalId}`
@@ -1440,7 +1441,7 @@ export async function confirmPay(
});
break;
case PurchaseStatus.Done:
- case PurchaseStatus.Paying:
+ case PurchaseStatus.PendingPaying:
default:
break;
}
@@ -1481,14 +1482,14 @@ export async function processPurchase(
}
switch (purchase.purchaseStatus) {
- case PurchaseStatus.DownloadingProposal:
+ case PurchaseStatus.PendingDownloadingProposal:
return processDownloadProposal(ws, proposalId);
- case PurchaseStatus.Paying:
- case PurchaseStatus.PayingReplay:
+ case PurchaseStatus.PendingPaying:
+ case PurchaseStatus.PendingPayingReplay:
return processPurchasePay(ws, proposalId);
- case PurchaseStatus.QueryingRefund:
+ case PurchaseStatus.PendingQueryingRefund:
return processPurchaseQueryRefund(ws, purchase);
- case PurchaseStatus.QueryingAutoRefund:
+ case PurchaseStatus.PendingQueryingAutoRefund:
return processPurchaseAutoRefund(ws, purchase);
case PurchaseStatus.AbortingWithRefund:
return processPurchaseAbortingRefund(ws, purchase);
@@ -1540,8 +1541,8 @@ export async function processPurchasePay(
};
}
switch (purchase.purchaseStatus) {
- case PurchaseStatus.Paying:
- case PurchaseStatus.PayingReplay:
+ case PurchaseStatus.PendingPaying:
+ case PurchaseStatus.PendingPayingReplay:
break;
default:
return OperationAttemptResult.finishedEmpty();
@@ -1757,11 +1758,11 @@ export async function abortPayMerchant(
logger.warn(`tried to abort successful payment`);
return;
}
- if (oldStatus === PurchaseStatus.Paying) {
+ if (oldStatus === PurchaseStatus.PendingPaying) {
purchase.purchaseStatus = PurchaseStatus.AbortingWithRefund;
}
await tx.purchases.put(purchase);
- if (oldStatus === PurchaseStatus.Paying) {
+ if (oldStatus === PurchaseStatus.PendingPaying) {
if (purchase.payInfo) {
const coinSel = purchase.payInfo.payCoinSelection;
const currency = Amounts.currencyOf(purchase.payInfo.totalPayCost);
@@ -1789,32 +1790,146 @@ export async function abortPayMerchant(
ws.workAvailable.trigger();
}
+
+const transitionSuspend: { [x in PurchaseStatus]?: {
+ next: PurchaseStatus | undefined,
+} } = {
+ [PurchaseStatus.PendingDownloadingProposal]: {
+ next: PurchaseStatus.SuspendedDownloadingProposal,
+ },
+ [PurchaseStatus.AbortingWithRefund]: {
+ next: PurchaseStatus.SuspendedAbortingWithRefund,
+ },
+ [PurchaseStatus.PendingPaying]: {
+ next: PurchaseStatus.SuspendedPaying,
+ },
+ [PurchaseStatus.PendingPayingReplay]: {
+ next: PurchaseStatus.SuspendedPayingReplay,
+ },
+ [PurchaseStatus.PendingQueryingAutoRefund]: {
+ next: PurchaseStatus.SuspendedQueryingAutoRefund,
+ }
+}
+
+const transitionResume: { [x in PurchaseStatus]?: {
+ next: PurchaseStatus | undefined,
+} } = {
+ [PurchaseStatus.SuspendedDownloadingProposal]: {
+ next: PurchaseStatus.PendingDownloadingProposal,
+ },
+ [PurchaseStatus.SuspendedAbortingWithRefund]: {
+ next: PurchaseStatus.AbortingWithRefund,
+ },
+ [PurchaseStatus.SuspendedPaying]: {
+ next: PurchaseStatus.PendingPaying,
+ },
+ [PurchaseStatus.SuspendedPayingReplay]: {
+ next: PurchaseStatus.PendingPayingReplay,
+ },
+ [PurchaseStatus.SuspendedQueryingAutoRefund]: {
+ next: PurchaseStatus.PendingQueryingAutoRefund,
+ }
+}
+
+
+export async function suspendPayMerchant(
+ ws: InternalWalletState,
+ proposalId: string,
+): Promise<void> {
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.Payment,
+ proposalId,
+ });
+ const opId = constructTaskIdentifier({
+ tag: PendingTaskType.Purchase,
+ proposalId,
+ });
+ stopLongpolling(ws, opId);
+ const transitionInfo = await ws.db
+ .mktx((x) => [
+ x.purchases,
+ ])
+ .runReadWrite(async (tx) => {
+ const purchase = await tx.purchases.get(proposalId);
+ if (!purchase) {
+ throw Error("purchase not found");
+ }
+ const oldTxState = computePayMerchantTransactionState(purchase);
+ let newStatus = transitionSuspend[purchase.purchaseStatus];
+ if (!newStatus) {
+ return undefined;
+ }
+ await tx.purchases.put(purchase);
+ const newTxState = computePayMerchantTransactionState(purchase);
+ return { oldTxState, newTxState };
+ });
+ notifyTransition(ws, transactionId, transitionInfo);
+ ws.workAvailable.trigger();
+}
+
+
+export async function resumePayMerchant(
+ ws: InternalWalletState,
+ proposalId: string,
+): Promise<void> {
+ const transactionId = constructTransactionIdentifier({
+ tag: TransactionType.Payment,
+ proposalId,
+ });
+ const opId = constructTaskIdentifier({
+ tag: PendingTaskType.Purchase,
+ proposalId,
+ });
+ stopLongpolling(ws, opId);
+ const transitionInfo = await ws.db
+ .mktx((x) => [
+ x.purchases,
+ ])
+ .runReadWrite(async (tx) => {
+ const purchase = await tx.purchases.get(proposalId);
+ if (!purchase) {
+ throw Error("purchase not found");
+ }
+ const oldTxState = computePayMerchantTransactionState(purchase);
+ let newStatus = transitionResume[purchase.purchaseStatus];
+ if (!newStatus) {
+ return undefined;
+ }
+ await tx.purchases.put(purchase);
+ const newTxState = computePayMerchantTransactionState(purchase);
+ return { oldTxState, newTxState };
+ });
+ ws.workAvailable.trigger();
+ notifyTransition(ws, transactionId, transitionInfo);
+ ws.workAvailable.trigger();
+}
+
export function computePayMerchantTransactionState(
purchaseRecord: PurchaseRecord,
): TransactionState {
switch (purchaseRecord.purchaseStatus) {
// Pending States
- case PurchaseStatus.DownloadingProposal:
+ case PurchaseStatus.PendingDownloadingProposal:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.ClaimProposal,
};
- case PurchaseStatus.Paying:
+ case PurchaseStatus.PendingPaying:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.SubmitPayment,
};
- case PurchaseStatus.PayingReplay:
+ case PurchaseStatus.PendingPayingReplay:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.RebindSession,
};
- case PurchaseStatus.QueryingAutoRefund:
+ case PurchaseStatus.PendingQueryingAutoRefund:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.AutoRefund,
};
- case PurchaseStatus.QueryingRefund:
+ case PurchaseStatus.PendingQueryingRefund:
return {
major: TransactionMajorState.Pending,
minor: TransactionMinorState.CheckRefund,
@@ -1937,7 +2052,7 @@ async function processPurchaseAutoRefund(
logger.warn("purchase does not exist anymore");
return;
}
- if (p.purchaseStatus !== PurchaseStatus.QueryingRefund) {
+ if (p.purchaseStatus !== PurchaseStatus.PendingQueryingRefund) {
return;
}
const oldTxState = computePayMerchantTransactionState(p);
@@ -1982,7 +2097,7 @@ async function processPurchaseAutoRefund(
logger.warn("purchase does not exist anymore");
return;
}
- if (p.purchaseStatus !== PurchaseStatus.QueryingAutoRefund) {
+ if (p.purchaseStatus !== PurchaseStatus.PendingQueryingAutoRefund) {
return;
}
const oldTxState = computePayMerchantTransactionState(p);
@@ -2118,7 +2233,7 @@ async function processPurchaseQueryRefund(
logger.warn("purchase does not exist anymore");
return undefined;
}
- if (p.purchaseStatus !== PurchaseStatus.QueryingRefund) {
+ if (p.purchaseStatus !== PurchaseStatus.PendingQueryingRefund) {
return undefined;
}
const oldTxState = computePayMerchantTransactionState(p);
@@ -2143,7 +2258,7 @@ async function processPurchaseQueryRefund(
logger.warn("purchase does not exist anymore");
return;
}
- if (p.purchaseStatus !== PurchaseStatus.QueryingRefund) {
+ if (p.purchaseStatus !== PurchaseStatus.PendingQueryingRefund) {
return;
}
const oldTxState = computePayMerchantTransactionState(p);
@@ -2242,7 +2357,7 @@ export async function startQueryRefund(
return;
}
const oldTxState = computePayMerchantTransactionState(p);
- p.purchaseStatus = PurchaseStatus.QueryingRefund;
+ p.purchaseStatus = PurchaseStatus.PendingQueryingRefund;
const newTxState = computePayMerchantTransactionState(p);
await tx.purchases.put(p);
return { oldTxState, newTxState };