summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-wallet-core/src/db.ts6
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts24
2 files changed, 25 insertions, 5 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index 9efc9fbe0..7e4f9fa4a 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -1326,6 +1326,12 @@ export interface PurchaseRecord {
* did not picked up yet
*/
refundAmountAwaiting: AmountString | undefined;
+
+ /**
+ * When the purchase has been shared to other wallet
+ * and the other wallet completed before this one.
+ */
+ paidByOther: boolean | undefined;
}
export enum ConfigRecordKey {
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
index 05cbd26b7..8eff7e17b 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -880,7 +880,7 @@ async function createOrReusePurchase(
);
if (oldProposal.purchaseStatus === PurchaseStatus.DialogShared) {
const download = await expectProposalDownload(wex, oldProposal);
- const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData);
+ 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
@@ -895,6 +895,7 @@ async function createOrReusePurchase(
}
const oldTxState = computePayMerchantTransactionState(p);
p.purchaseStatus = PurchaseStatus.FailedClaim;
+ p.paidByOther = true;
const newTxState = computePayMerchantTransactionState(p);
await tx.purchases.put(p);
return { oldTxState, newTxState };
@@ -942,6 +943,7 @@ async function createOrReusePurchase(
lastSessionId: undefined,
merchantPaySig: undefined,
payInfo: undefined,
+ paidByOther: undefined,
refundAmountAwaiting: undefined,
timestampAccept: undefined,
timestampFirstSuccessfulPay: undefined,
@@ -1377,7 +1379,7 @@ async function checkPaymentByProposalId(
status: PreparePayResultType.AlreadyConfirmed,
contractTerms: download.contractTermsRaw,
contractTermsHash: download.contractData.contractTermsHash,
- paid: false,
+ paid: purchase.paidByOther === true,
amountRaw: Amounts.stringify(download.contractData.amount),
amountEffective: purchase.payInfo
? Amounts.stringify(purchase.payInfo.totalPayCost)
@@ -2009,7 +2011,7 @@ async function processPurchasePay(
const download = await expectProposalDownload(wex, purchase);
if (purchase.shared) {
- const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData);
+ const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData, false);
if (paid) {
const transitionInfo = await wex.db.runReadWriteTx(
@@ -2022,6 +2024,7 @@ async function processPurchasePay(
}
const oldTxState = computePayMerchantTransactionState(p);
p.purchaseStatus = PurchaseStatus.FailedClaim;
+ p.paidByOther = true;
const newTxState = computePayMerchantTransactionState(p);
await tx.purchases.put(p);
return { oldTxState, newTxState };
@@ -2467,6 +2470,7 @@ export async function sharePayment(
}
return {
+ proposalId: p.proposalId,
nonce: p.noncePriv,
session: p.lastSessionId ?? p.downloadSessionId,
token: p.claimToken,
@@ -2476,6 +2480,11 @@ export async function sharePayment(
if (result === undefined) {
throw Error("This purchase can't be shared");
}
+
+ // schedule a task to watch for the status
+ const ctx = new PayMerchantTransactionContext(wex, result.proposalId);
+ wex.taskScheduler.startShepherdTask(ctx.taskId);
+
const privatePayUri = stringifyPayUri({
merchantBaseUrl,
orderId,
@@ -2483,12 +2492,14 @@ export async function sharePayment(
noncePriv: result.nonce,
claimToken: result.token,
});
+
return { privatePayUri };
}
async function checkIfOrderIsAlreadyPaid(
wex: WalletExecutionContext,
contract: WalletContractData,
+ doLongPolling: boolean,
) {
const requestUrl = new URL(
`orders/${contract.orderId}`,
@@ -2496,7 +2507,9 @@ async function checkIfOrderIsAlreadyPaid(
);
requestUrl.searchParams.set("h_contract", contract.contractTermsHash);
- requestUrl.searchParams.set("timeout_ms", "1000");
+ if (doLongPolling) {
+ requestUrl.searchParams.set("timeout_ms", "30000");
+ }
const resp = await wex.http.fetch(requestUrl.href, {
cancellationToken: wex.cancellationToken,
@@ -2526,7 +2539,7 @@ async function processPurchaseDialogShared(
return TaskRunResult.finished();
}
- const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData);
+ const paid = await checkIfOrderIsAlreadyPaid(wex, download.contractData, true);
if (paid) {
const transitionInfo = await wex.db.runReadWriteTx(
["purchases"],
@@ -2538,6 +2551,7 @@ async function processPurchaseDialogShared(
}
const oldTxState = computePayMerchantTransactionState(p);
p.purchaseStatus = PurchaseStatus.FailedClaim;
+ p.paidByOther = true
const newTxState = computePayMerchantTransactionState(p);
await tx.purchases.put(p);
return { oldTxState, newTxState };