gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-docs] branch master updated: public-orders-get.ts


From: gnunet
Subject: [taler-docs] branch master updated: public-orders-get.ts
Date: Sun, 08 Aug 2021 18:26:45 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository docs.

The following commit(s) were added to refs/heads/master by this push:
     new cf7e099  public-orders-get.ts
cf7e099 is described below

commit cf7e099367137923b2764f38fd32aa0fd1e7c2ab
Author: Florian Dold <florian@dold.me>
AuthorDate: Sun Aug 8 18:26:39 2021 +0200

    public-orders-get.ts
---
 merchant-spec/public-orders-get.ts | 145 +++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)

diff --git a/merchant-spec/public-orders-get.ts 
b/merchant-spec/public-orders-get.ts
new file mode 100644
index 0000000..d46475f
--- /dev/null
+++ b/merchant-spec/public-orders-get.ts
@@ -0,0 +1,145 @@
+// Merchant's DB state for one particular order.
+// Invariants:
+// paid => claimed
+// claimed => !!contractHash
+// requireClaimToken => !!claimToken
+// !!lastPaidSessionId => paid
+interface MerchantOrderInfo {
+  orderId: string;
+  requireClaimToken: boolean;
+  claimToken?: string;
+  contractHash?: string;
+  claimed: boolean;
+  paid: boolean;
+  fulfillmentUrl?: string;
+  publicReorderUrl?: string;
+  lastPaidSessionId?: string;
+}
+
+interface Req {
+  orderId: string;
+  contractHash?: string;
+  claimToken?: string;
+  sessionId?: string;
+  accept: "json" | "html";
+}
+
+interface Resp {
+  httpStatus: string;
+  responseType: string;
+  // Additional details about response
+  response?: any;
+}
+
+type MerchantOrderStore = { [orderId: string]: MerchantOrderInfo };
+
+function handlePublicOrdersGet(mos: MerchantOrderStore, req: Req): Resp {
+  const ord = mos[req.orderId];
+  if (!ord) {
+    return {
+      httpStatus: "404 Not Found",
+      responseType: "TalerErrorResponse",
+    };
+  }
+  if (!ord.claimed) {
+    if (ord.requireClaimToken && ord.claimToken !== req.claimToken) {
+      return {
+        httpStatus: "403 Forbidden",
+        responseType: "TalerErrorResponse",
+      };
+    }
+    return {
+      httpStatus: "402 Payment Required",
+      responseType: "StatusUnpaidResponse",
+      response: {
+        fulfillmentUrl: ord.fulfillmentUrl,
+        // FIXME: do we include claim token here?
+        talerPayUri: "taler://pay/",
+      },
+    };
+  }
+
+  if (!ord.paid) {
+    if (ord.requireClaimToken && ord.claimToken !== req.claimToken) {
+      // This can happen when the fulfillment URL page detects
+      // the user has not paid under the current session.
+      return {
+        httpStatus: "202 Accepted",
+        responseType: "StatusGotoResponse",
+        response: {
+          public_reorder_url: ord.publicReorderUrl,
+        },
+      };
+    }
+    return {
+      httpStatus: "402 Payment Required",
+      responseType: "StatusUnpaidResponse",
+      response: {
+        fulfillmentUrl: ord.fulfillmentUrl,
+        // FIXME: do we include claim token here?
+        talerPayUri: "taler://pay/",
+      },
+    };
+  }
+
+  // Here, we know that the order is paid for.
+  // But we still need the ord.claimToken, because
+  // the QR code page will poll until it gets a
+  // fulfillment URL, but we decided that the
+  // fulfillment URL should only be returned
+  // when the client is authenticated.
+  // (Otherwise, guessing the order ID might leak the
+  // fulfillment URL).
+
+  const authOk =
+    ord.contractHash === req.contractHash ||
+    (ord.requireClaimToken && ord.claimToken === req.claimToken);
+
+  if (authOk) {
+    if (!!req.sessionId && req.sessionId !== ord.lastPaidSessionId) {
+      const alreadyPaidOrd = findAlreadyPaid(mos, req.sessionId);
+      if (alreadyPaidOrd) {
+        return {
+          httpStatus: "202 Accepted",
+          responseType: "StatusGotoResponse",
+          response: {
+            already_paid_order_id: alreadyPaidOrd.orderId,
+          }
+        }
+      }
+      return {
+        httpStatus: "402 Payment Required",
+        responseType: "StatusUnpaidResponse",
+        response: {
+          fulfillmentUrl: ord.fulfillmentUrl,
+          // TO DISCUSS: do we include claim token here?
+          talerPayUri: "taler://pay/",
+        },
+      };
+    }
+    return {
+      httpStatus: "200 OK",
+      responseType: "StatusPaidResponse",
+      response: {
+        fulfillmentUrl: ord.fulfillmentUrl,
+      },
+    };
+  }
+
+  return {
+    httpStatus: "403 Forbidden",
+    responseType: "TalerErrorResponse",
+  };
+}
+
+function findAlreadyPaid(
+  mos: MerchantOrderStore,
+  sessionId: string
+): MerchantOrderInfo | undefined {
+  for (const orderId of Object.keys(mos)) {
+    if (mos[orderId].lastPaidSessionId === sessionId) {
+      return mos[orderId];
+    }
+  }
+  return undefined;
+}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]