aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-06-22 15:30:19 +0200
committerFlorian Dold <florian@dold.me>2021-06-22 15:30:19 +0200
commit39c4b42dafc5d8fc5f455e7ed936c45ec2340cfc (patch)
treeac76b84527dc7e21bcaea1b0a963b0bf34f5ac4f
parentc51b372abeba8cab9500d6cc7198ba38bee30737 (diff)
implement long-polling for auto-refunds
-rw-r--r--packages/taler-wallet-core/src/operations/refund.ts35
1 files changed, 33 insertions, 2 deletions
diff --git a/packages/taler-wallet-core/src/operations/refund.ts b/packages/taler-wallet-core/src/operations/refund.ts
index 4ea80689c..0bff29863 100644
--- a/packages/taler-wallet-core/src/operations/refund.ts
+++ b/packages/taler-wallet-core/src/operations/refund.ts
@@ -44,6 +44,8 @@ import {
TalerErrorDetails,
URL,
timestampAddDuration,
+ codecForMerchantOrderStatusPaid,
+ isTimestampExpired,
} from "@gnu-taler/taler-util";
import {
AbortStatus,
@@ -493,7 +495,7 @@ export async function applyRefund(
ws.notify({
type: NotificationType.RefundStarted,
});
- await processPurchaseQueryRefund(ws, proposalId);
+ await processPurchaseQueryRefundImpl(ws, proposalId, true, false);
}
purchase = await ws.db
@@ -571,7 +573,7 @@ export async function processPurchaseQueryRefund(
const onOpErr = (e: TalerErrorDetails): Promise<void> =>
incrementPurchaseQueryRefundRetry(ws, proposalId, e);
await guardOperationException(
- () => processPurchaseQueryRefundImpl(ws, proposalId, forceNow),
+ () => processPurchaseQueryRefundImpl(ws, proposalId, forceNow, true),
onOpErr,
);
}
@@ -597,6 +599,7 @@ async function processPurchaseQueryRefundImpl(
ws: InternalWalletState,
proposalId: string,
forceNow: boolean,
+ waitForAutoRefund: boolean,
): Promise<void> {
if (forceNow) {
await resetPurchaseQueryRefundRetry(ws, proposalId);
@@ -617,6 +620,34 @@ async function processPurchaseQueryRefundImpl(
}
if (purchase.timestampFirstSuccessfulPay) {
+ if (
+ waitForAutoRefund &&
+ purchase.autoRefundDeadline &&
+ !isTimestampExpired(purchase.autoRefundDeadline)
+ ) {
+ const requestUrl = new URL(
+ `orders/${purchase.download.contractData.orderId}`,
+ purchase.download.contractData.merchantBaseUrl,
+ );
+ requestUrl.searchParams.set(
+ "h_contract",
+ purchase.download.contractData.contractTermsHash,
+ );
+ // Long-poll for one second
+ requestUrl.searchParams.set("timeout_ms", "1000");
+ requestUrl.searchParams.set("await_refund_obtained", "yes");
+ logger.trace("making long-polling request for auto-refund");
+ const resp = await ws.http.get(requestUrl.href);
+ const orderStatus = await readSuccessResponseJsonOrThrow(
+ resp,
+ codecForMerchantOrderStatusPaid(),
+ );
+ if (!orderStatus.refunded) {
+ incrementPurchaseQueryRefundRetry(ws, proposalId, undefined);
+ return;
+ }
+ }
+
const requestUrl = new URL(
`orders/${purchase.download.contractData.orderId}/refund`,
purchase.download.contractData.merchantBaseUrl,