gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: Factor out 9 new functions (shit


From: gnunet
Subject: [taler-merchant] branch master updated: Factor out 9 new functions (shit job)
Date: Mon, 15 May 2023 21:03:02 +0200

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

ivan-avalos pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new b712481b Factor out 9 new functions (shit job)
b712481b is described below

commit b712481beaeb1dcc2e2a7195d0607a3c0f073665
Author: Iván Ávalos <avalos@disroot.org>
AuthorDate: Mon May 15 13:02:54 2023 -0600

    Factor out 9 new functions (shit job)
---
 src/backenddb/Makefile.am                        |   9 +
 src/backenddb/pg_insert_deposit.c                | 114 +++
 src/backenddb/pg_insert_deposit.h                |  61 ++
 src/backenddb/pg_insert_exchange_signkey.c       |  66 ++
 src/backenddb/pg_insert_exchange_signkey.h       |  48 ++
 src/backenddb/pg_lookup_deposits.c               | 173 +++++
 src/backenddb/pg_lookup_deposits.h               |  46 ++
 src/backenddb/pg_lookup_order_status.c           |  73 ++
 src/backenddb/pg_lookup_order_status.h           |  45 ++
 src/backenddb/pg_lookup_order_status_by_serial.c |  77 ++
 src/backenddb/pg_lookup_order_status_by_serial.h |  48 ++
 src/backenddb/pg_lookup_payment_status.c         |  98 +++
 src/backenddb/pg_lookup_payment_status.h         |  45 ++
 src/backenddb/pg_lookup_refunds.c                | 150 ++++
 src/backenddb/pg_lookup_refunds.h                |  45 ++
 src/backenddb/pg_mark_contract_paid.c            | 112 +++
 src/backenddb/pg_mark_contract_paid.h            |  45 ++
 src/backenddb/pg_refund_coin.c                   |  77 ++
 src/backenddb/pg_refund_coin.h                   |  51 ++
 src/backenddb/plugin_merchantdb_postgres.c       | 863 +----------------------
 20 files changed, 1410 insertions(+), 836 deletions(-)

diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am
index 1b400bce..745e33eb 100644
--- a/src/backenddb/Makefile.am
+++ b/src/backenddb/Makefile.am
@@ -94,6 +94,15 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \
   pg_insert_contract_terms.h pg_insert_contract_terms.c \
   pg_update_contract_terms.h pg_update_contract_terms.c \
   pg_delete_contract_terms.h pg_delete_contract_terms.c \
+  pg_lookup_deposits.h pg_lookup_deposits.c \
+  pg_insert_exchange_signkey.h pg_insert_exchange_signkey.c \
+  pg_insert_deposit.h pg_insert_deposit.c \
+  pg_lookup_refunds.h pg_lookup_refunds.c \
+  pg_mark_contract_paid.h pg_mark_contract_paid.c \
+  pg_refund_coin.h pg_refund_coin.c \
+  pg_lookup_order_status.h pg_lookup_order_status.c \
+  pg_lookup_order_status_by_serial.h pg_lookup_order_status_by_serial.c \
+  pg_lookup_payment_status.h pg_lookup_payment_status.c \
   plugin_merchantdb_postgres.c  pg_helper.h
 libtaler_plugin_merchantdb_postgres_la_LIBADD = \
   $(LTLIBINTL)
diff --git a/src/backenddb/pg_insert_deposit.c 
b/src/backenddb/pg_insert_deposit.c
new file mode 100644
index 00000000..f7f20d47
--- /dev/null
+++ b/src/backenddb/pg_insert_deposit.c
@@ -0,0 +1,114 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_insert_deposit.c
+ * @brief Implementation of the insert_deposit function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_insert_deposit.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_insert_deposit (
+  void *cls,
+  const char *instance_id,
+  struct GNUNET_TIME_Timestamp deposit_timestamp,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const char *exchange_url,
+  const struct TALER_Amount *amount_with_fee,
+  const struct TALER_Amount *deposit_fee,
+  const struct TALER_Amount *refund_fee,
+  const struct TALER_Amount *wire_fee,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_ExchangeSignatureP *exchange_sig,
+  const struct TALER_ExchangePublicKeyP *exchange_pub)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_timestamp (&deposit_timestamp), /* $3 */
+    GNUNET_PQ_query_param_auto_from_type (coin_pub),
+    GNUNET_PQ_query_param_string (exchange_url),
+    TALER_PQ_query_param_amount (amount_with_fee), /* $6/$7 */
+    TALER_PQ_query_param_amount (deposit_fee),  /* $8, $9 */
+    TALER_PQ_query_param_amount (refund_fee), /* $10, $11 */
+    TALER_PQ_query_param_amount (wire_fee),  /* $12, $13 */
+    GNUNET_PQ_query_param_auto_from_type (h_wire), /* $14 */
+    GNUNET_PQ_query_param_auto_from_type (exchange_sig), /* $15 */
+    GNUNET_PQ_query_param_auto_from_type (exchange_pub), /* $16 */
+    GNUNET_PQ_query_param_end
+  };
+
+  /* no preflight check here, run in transaction by caller! */
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Storing deposit for instance `%s' h_contract_terms `%s', 
coin_pub: `%s', amount_with_fee: %s\n",
+              instance_id,
+              GNUNET_h2s (&h_contract_terms->hash),
+              TALER_B2S (coin_pub),
+              TALER_amount2s (amount_with_fee));
+  check_connection (pg);
+  PREPARE (pg,
+           "insert_deposit",
+           "WITH md AS"
+           "  (SELECT account_serial, merchant_serial"
+           "   FROM merchant_accounts"
+           "   WHERE h_wire=$14"
+           "    AND merchant_serial="
+           "     (SELECT merchant_serial"
+           "        FROM merchant_instances"
+           "        WHERE merchant_id=$1))"
+           ", ed AS"
+           "  (SELECT signkey_serial"
+           "   FROM merchant_exchange_signing_keys"
+           "   WHERE exchange_pub=$16"
+           "   ORDER BY start_date DESC"
+           "   LIMIT 1)"
+           "INSERT INTO merchant_deposits"
+           "(order_serial"
+           ",deposit_timestamp"
+           ",coin_pub"
+           ",exchange_url"
+           ",amount_with_fee_val"
+           ",amount_with_fee_frac"
+           ",deposit_fee_val"
+           ",deposit_fee_frac"
+           ",refund_fee_val"
+           ",refund_fee_frac"
+           ",wire_fee_val"
+           ",wire_fee_frac"
+           ",exchange_sig"
+           ",signkey_serial"
+           ",account_serial)"
+           " SELECT "
+           "   order_serial"
+           "  ,$3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $15"
+           "  ,ed.signkey_serial"
+           "  ,md.account_serial"
+           "  FROM merchant_contract_terms"
+           "   JOIN md USING (merchant_serial)"
+           "   FULL OUTER JOIN ed ON TRUE"
+           "  WHERE h_contract_terms=$2");
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_deposit",
+                                             params);
+
+}
diff --git a/src/backenddb/pg_insert_deposit.h 
b/src/backenddb/pg_insert_deposit.h
new file mode 100644
index 00000000..49d783aa
--- /dev/null
+++ b/src/backenddb/pg_insert_deposit.h
@@ -0,0 +1,61 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_insert_deposit.h
+ * @brief implementation of the insert_deposit function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_INSERT_DEPOSIT_H
+#define PG_INSERT_DEPOSIT_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Insert payment confirmation from the exchange into the database.
+ *
+ * @param cls closure
+ * @param instance_id instance to lookup deposits for
+ * @param deposit_timestamp time when the exchange generated the deposit 
confirmation
+ * @param h_contract_terms proposal data's hashcode
+ * @param coin_pub public key of the coin
+ * @param exchange_url URL of the exchange that issued @a coin_pub
+ * @param amount_with_fee amount the exchange will deposit for this coin
+ * @param deposit_fee fee the exchange will charge for this coin
+ * @param wire_fee wire fee the exchange charges
+ * @param refund_fee fee the exchange charges to refund this coin
+ * @param h_wire hash of the wire details of the target account of the merchant
+ * @param exchange_sig signature from exchange that coin was accepted
+ * @param exchange_pub signgin key that was used for @a exchange_sig
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_insert_deposit (void *cls,
+                       const char *instance_id,
+                       struct GNUNET_TIME_Timestamp deposit_timestamp,
+                       const struct TALER_PrivateContractHashP 
*h_contract_terms,
+                       const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                       const char *exchange_url,
+                       const struct TALER_Amount *amount_with_fee,
+                       const struct TALER_Amount *deposit_fee,
+                       const struct TALER_Amount *refund_fee,
+                       const struct TALER_Amount *wire_fee,
+                       const struct TALER_MerchantWireHashP *h_wire,
+                       const struct TALER_ExchangeSignatureP *exchange_sig,
+                       const struct TALER_ExchangePublicKeyP *exchange_pub);
+
+#endif
diff --git a/src/backenddb/pg_insert_exchange_signkey.c 
b/src/backenddb/pg_insert_exchange_signkey.c
new file mode 100644
index 00000000..81d27d60
--- /dev/null
+++ b/src/backenddb/pg_insert_exchange_signkey.c
@@ -0,0 +1,66 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_insert_exchange_signkey.c
+ * @brief Implementation of the insert_exchange_signkey function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_insert_exchange_signkey.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_insert_exchange_signkey (
+  void *cls,
+  const struct TALER_MasterPublicKeyP *master_pub,
+  const struct TALER_ExchangePublicKeyP *exchange_pub,
+  struct GNUNET_TIME_Timestamp start_date,
+  struct GNUNET_TIME_Timestamp expire_date,
+  struct GNUNET_TIME_Timestamp end_date,
+  const struct TALER_MasterSignatureP *master_sig)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (master_pub),
+    GNUNET_PQ_query_param_auto_from_type (exchange_pub),
+    GNUNET_PQ_query_param_timestamp (&start_date),
+    GNUNET_PQ_query_param_timestamp (&expire_date),
+    GNUNET_PQ_query_param_timestamp (&end_date),
+    GNUNET_PQ_query_param_auto_from_type (master_sig),
+    GNUNET_PQ_query_param_end
+  };
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  PREPARE (pg,
+           "insert_exchange_signkey",
+           "INSERT INTO merchant_exchange_signing_keys"
+           "(master_pub"
+           ",exchange_pub"
+           ",start_date"
+           ",expire_date"
+           ",end_date"
+           ",master_sig)"
+           "VALUES"
+           "($1, $2, $3, $4, $5, $6)");
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_exchange_signkey",
+                                             params);
+
+}
diff --git a/src/backenddb/pg_insert_exchange_signkey.h 
b/src/backenddb/pg_insert_exchange_signkey.h
new file mode 100644
index 00000000..78f84846
--- /dev/null
+++ b/src/backenddb/pg_insert_exchange_signkey.h
@@ -0,0 +1,48 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_insert_exchange_signkey.h
+ * @brief implementation of the insert_exchange_signkey function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_INSERT_EXCHANGE_SIGNKEY_H
+#define PG_INSERT_EXCHANGE_SIGNKEY_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Insert an exchange signing key into our database.
+ *
+ * @param cls closure
+ * @param master_pub exchange master public key used for @a master_sig
+ * @param exchange_pub exchange signing key to insert
+ * @param start_date when does the signing key become valid
+ * @param expire_date when does the signing key stop being used
+ * @param end_date when does the signing key become void as proof
+ * @param master_sig signature of @a master_pub over the @a exchange_pub and 
the dates
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_insert_exchange_signkey (void *cls,
+                                const struct TALER_MasterPublicKeyP 
*master_pub,
+                                const struct TALER_ExchangePublicKeyP 
*exchange_pub,
+                                struct GNUNET_TIME_Timestamp start_date,
+                                struct GNUNET_TIME_Timestamp expire_date,
+                                struct GNUNET_TIME_Timestamp end_date,
+                                const struct TALER_MasterSignatureP 
*master_sig);
+
+#endif
diff --git a/src/backenddb/pg_lookup_deposits.c 
b/src/backenddb/pg_lookup_deposits.c
new file mode 100644
index 00000000..27647dda
--- /dev/null
+++ b/src/backenddb/pg_lookup_deposits.c
@@ -0,0 +1,173 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_deposits.c
+ * @brief Implementation of the lookup_deposits function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_lookup_deposits.h"
+#include "pg_helper.h"
+
+/**
+ * Closure for #lookup_deposits_cb().
+ */
+struct LookupDepositsContext
+{
+  /**
+   * Function to call with results.
+   */
+  TALER_MERCHANTDB_DepositsCallback cb;
+
+  /**
+   * Closure for @e cls.
+   */
+  void *cb_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Transaction status (set).
+   */
+  enum GNUNET_DB_QueryStatus qs;
+};
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param[in,out] cls of type `struct LookupDepositsContext *`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lookup_deposits_cb (void *cls,
+                    PGresult *result,
+                    unsigned int num_results)
+{
+  struct LookupDepositsContext *ldc = cls;
+  struct PostgresClosure *pg = ldc->pg;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_Amount amount_with_fee;
+    struct TALER_Amount deposit_fee;
+    struct TALER_Amount refund_fee;
+    struct TALER_Amount wire_fee;
+    char *exchange_url;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_string ("exchange_url",
+                                    &exchange_url),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                            &coin_pub),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &amount_with_fee),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee",
+                                   &deposit_fee),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("refund_fee",
+                                   &refund_fee),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
+                                   &wire_fee),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      ldc->qs = GNUNET_DB_STATUS_HARD_ERROR;
+      return;
+    }
+    ldc->cb (ldc->cb_cls,
+             exchange_url,
+             &coin_pub,
+             &amount_with_fee,
+             &deposit_fee,
+             &refund_fee,
+             &wire_fee);
+    GNUNET_PQ_cleanup_result (rs);
+  }
+  ldc->qs = num_results;
+}
+
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_deposits (
+  void *cls,
+  const char *instance_id,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  TALER_MERCHANTDB_DepositsCallback cb,
+  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_end
+  };
+  struct LookupDepositsContext ldc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .pg = pg
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  /* no preflight check here, run in its own transaction by the caller! */
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Finding deposits for h_contract_terms '%s'\n",
+              GNUNET_h2s (&h_contract_terms->hash));
+  check_connection (pg);
+  PREPARE (pg,
+           "lookup_deposits",
+           "SELECT"
+           " exchange_url"
+           ",coin_pub"
+           ",amount_with_fee_val"
+           ",amount_with_fee_frac"
+           ",deposit_fee_val"
+           ",deposit_fee_frac"
+           ",refund_fee_val"
+           ",refund_fee_frac"
+           ",wire_fee_val"
+           ",wire_fee_frac"
+           " FROM merchant_deposits"
+           " WHERE order_serial="
+           "     (SELECT order_serial"
+           "        FROM merchant_contract_terms"
+           "        WHERE h_contract_terms=$2"
+           "          AND merchant_serial="
+           "          (SELECT merchant_serial"
+           "             FROM merchant_instances"
+           "            WHERE merchant_id=$1))");
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "lookup_deposits",
+                                             params,
+                                             &lookup_deposits_cb,
+                                             &ldc);
+  if (qs <= 0)
+    return qs;
+  return ldc.qs;
+}
diff --git a/src/backenddb/pg_lookup_deposits.h 
b/src/backenddb/pg_lookup_deposits.h
new file mode 100644
index 00000000..891a1093
--- /dev/null
+++ b/src/backenddb/pg_lookup_deposits.h
@@ -0,0 +1,46 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_deposits.h
+ * @brief implementation of the lookup_deposits function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_LOOKUP_DEPOSITS_H
+#define PG_LOOKUP_DEPOSITS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Lookup information about coins that were successfully deposited for a
+ * given contract.
+ *
+ * @param cls closure
+ * @param instance_id instance to lookup deposits for
+ * @param h_contract_terms proposal data's hashcode
+ * @param cb function to call with payment data
+ * @param cb_cls closure for @a cb
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_deposits (void *cls,
+                        const char *instance_id,
+                        const struct TALER_PrivateContractHashP 
*h_contract_terms,
+                        TALER_MERCHANTDB_DepositsCallback cb,
+                        void *cb_cls);
+
+#endif
diff --git a/src/backenddb/pg_lookup_order_status.c 
b/src/backenddb/pg_lookup_order_status.c
new file mode 100644
index 00000000..be6f0a15
--- /dev/null
+++ b/src/backenddb/pg_lookup_order_status.c
@@ -0,0 +1,73 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_order_status.c
+ * @brief Implementation of the lookup_order_status function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_lookup_order_status.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_order_status (
+  void *cls,
+  const char *instance_id,
+  const char *order_id,
+  struct TALER_PrivateContractHashP *h_contract_terms,
+  bool *paid)
+{
+  struct PostgresClosure *pg = cls;
+  uint8_t paid8;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_string (order_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                          h_contract_terms),
+    GNUNET_PQ_result_spec_auto_from_type ("paid",
+                                          &paid8),
+    GNUNET_PQ_result_spec_end
+  };
+
+  check_connection (pg);
+  PREPARE (pg,
+           "lookup_order_status",
+           "SELECT"
+           " h_contract_terms"
+           ",paid"
+           " FROM merchant_contract_terms"
+           " WHERE merchant_serial="
+           "     (SELECT merchant_serial "
+           "        FROM merchant_instances"
+           "        WHERE merchant_id=$1)"
+           "   AND order_id=$2");
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 "lookup_order_status",
+                                                 params,
+                                                 rs);
+  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+    *paid = (0 != paid8);
+  else
+    *paid = false; /* just to be safe(r) */
+  return qs;
+}
diff --git a/src/backenddb/pg_lookup_order_status.h 
b/src/backenddb/pg_lookup_order_status.h
new file mode 100644
index 00000000..acf8fe31
--- /dev/null
+++ b/src/backenddb/pg_lookup_order_status.h
@@ -0,0 +1,45 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_order_status.h
+ * @brief implementation of the lookup_order_status function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_LOOKUP_ORDER_STATUS_H
+#define PG_LOOKUP_ORDER_STATUS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Retrieve contract terms given its @a order_id
+ *
+ * @param cls closure
+ * @param instance_id instance's identifier
+ * @param order_id order to lookup contract for
+ * @param[out] h_contract_terms set to the hash of the contract.
+ * @param[out] paid set to the payment status of the contract
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_order_status (void *cls,
+                            const char *instance_id,
+                            const char *order_id,
+                            struct TALER_PrivateContractHashP 
*h_contract_terms,
+                            bool *paid);
+
+#endif
diff --git a/src/backenddb/pg_lookup_order_status_by_serial.c 
b/src/backenddb/pg_lookup_order_status_by_serial.c
new file mode 100644
index 00000000..b6a4ebb0
--- /dev/null
+++ b/src/backenddb/pg_lookup_order_status_by_serial.c
@@ -0,0 +1,77 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_order_status_by_serial.c
+ * @brief Implementation of the lookup_order_status_by_serial function for 
Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_lookup_order_status_by_serial.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_order_status_by_serial (void *cls,
+                                      const char *instance_id,
+                                      uint64_t order_serial,
+                                      char **order_id,
+                                      struct TALER_PrivateContractHashP *
+                                      h_contract_terms,
+                                      bool *paid)
+{
+  struct PostgresClosure *pg = cls;
+  uint8_t paid8;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_uint64 (&order_serial),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                          h_contract_terms),
+    GNUNET_PQ_result_spec_auto_from_type ("paid",
+                                          &paid8),
+    GNUNET_PQ_result_spec_string ("order_id",
+                                  order_id),
+    GNUNET_PQ_result_spec_end
+  };
+
+  check_connection (pg);
+  PREPARE (pg,
+           "lookup_order_status_by_serial",
+           "SELECT"
+           " h_contract_terms"
+           ",order_id"
+           ",paid"
+           " FROM merchant_contract_terms"
+           " WHERE merchant_serial="
+           "     (SELECT merchant_serial "
+           "        FROM merchant_instances"
+           "        WHERE merchant_id=$1)"
+           "   AND order_serial=$2");
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 
"lookup_order_status_by_serial",
+                                                 params,
+                                                 rs);
+  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+    *paid = (0 != paid8);
+  else
+    *paid = false; /* just to be safe(r) */
+  return qs;
+}
diff --git a/src/backenddb/pg_lookup_order_status_by_serial.h 
b/src/backenddb/pg_lookup_order_status_by_serial.h
new file mode 100644
index 00000000..eb60e97f
--- /dev/null
+++ b/src/backenddb/pg_lookup_order_status_by_serial.h
@@ -0,0 +1,48 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_order_status_by_serial.h
+ * @brief implementation of the lookup_order_status_by_serial function for 
Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_LOOKUP_ORDER_STATUS_BY_SERIAL_H
+#define PG_LOOKUP_ORDER_STATUS_BY_SERIAL_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Retrieve contract terms given its @a order_serial
+ *
+ * @param cls closure
+ * @param instance_id instance's identifier
+ * @param order_serial serial ID of the order to look up
+ * @param[out] order_id set to ID of the order
+ * @param[out] h_contract_terms set to the hash of the contract.
+ * @param[out] paid set to the payment status of the contract
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_order_status_by_serial (void *cls,
+                                      const char *instance_id,
+                                      uint64_t order_serial,
+                                      char **order_id,
+                                      struct TALER_PrivateContractHashP *
+                                      h_contract_terms,
+                                      bool *paid);
+
+#endif
diff --git a/src/backenddb/pg_lookup_payment_status.c 
b/src/backenddb/pg_lookup_payment_status.c
new file mode 100644
index 00000000..fc4e5d94
--- /dev/null
+++ b/src/backenddb/pg_lookup_payment_status.c
@@ -0,0 +1,98 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_payment_status.c
+ * @brief Implementation of the lookup_payment_status function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_lookup_payment_status.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_payment_status (void *cls,
+                              uint64_t order_serial,
+                              const char *session_id,
+                              bool *paid,
+                              bool *wired)
+{
+  struct PostgresClosure *pg = cls;
+  uint8_t paid8;
+  uint8_t wired8;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_auto_from_type ("paid",
+                                          &paid8),
+    GNUNET_PQ_result_spec_auto_from_type ("wired",
+                                          &wired8),
+    GNUNET_PQ_result_spec_end
+  };
+  check_connection (pg);
+  if (NULL == session_id)
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_uint64 (&order_serial),
+      GNUNET_PQ_query_param_end
+    };
+
+    PREPARE (pg,
+             "lookup_payment_status",
+             "SELECT"
+             " wired"
+             ",paid"
+             " FROM merchant_contract_terms"
+             " WHERE order_serial=$1");
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "lookup_payment_status",
+                                                   params,
+                                                   rs);
+  }
+  else
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_uint64 (&order_serial),
+      GNUNET_PQ_query_param_string (session_id),
+      GNUNET_PQ_query_param_end
+    };
+
+    PREPARE (pg,
+             "lookup_payment_status_session_id",
+             "SELECT"
+             " wired"
+             ",paid"
+             " FROM merchant_contract_terms"
+             " WHERE order_serial=$1"
+             "   AND session_id=$2");
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   
"lookup_payment_status_session_id",
+                                                   params,
+                                                   rs);
+  }
+  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+  {
+    *paid = (0 != paid8);
+    *wired = (0 != wired8);
+  }
+  else
+  {
+    *paid = false; /* just to be safe(r) */
+    *wired = false; /* just to be safe(r) */
+  }
+  return qs;
+}
diff --git a/src/backenddb/pg_lookup_payment_status.h 
b/src/backenddb/pg_lookup_payment_status.h
new file mode 100644
index 00000000..a46ee31e
--- /dev/null
+++ b/src/backenddb/pg_lookup_payment_status.h
@@ -0,0 +1,45 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_payment_status.h
+ * @brief implementation of the lookup_payment_status function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_LOOKUP_PAYMENT_STATUS_H
+#define PG_LOOKUP_PAYMENT_STATUS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Retrieve payment and wire status for a given @a order_serial and session ID.
+ *
+ * @param cls closure
+ * @param order_serial identifies the order
+ * @param session_id session for which to check the payment status, NULL for 
any
+ * @param[out] paid set to the payment status of the contract
+ * @param[out] wired set to the wire transfer status of the exchange payment
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_payment_status (void *cls,
+                              uint64_t order_serial,
+                              const char *session_id,
+                              bool *paid,
+                              bool *wired);
+
+#endif
diff --git a/src/backenddb/pg_lookup_refunds.c 
b/src/backenddb/pg_lookup_refunds.c
new file mode 100644
index 00000000..bc943162
--- /dev/null
+++ b/src/backenddb/pg_lookup_refunds.c
@@ -0,0 +1,150 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_refunds.c
+ * @brief Implementation of the lookup_refunds function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_lookup_refunds.h"
+#include "pg_helper.h"
+
+/**
+ * Closure for #lookup_refunds_cb().
+ */
+struct LookupRefundsContext
+{
+  /**
+   * Function to call for each refund.
+   */
+  TALER_MERCHANTDB_RefundCallback rc;
+
+  /**
+   * Closure for @e rc.
+   */
+  void *rc_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Transaction result.
+   */
+  enum GNUNET_DB_QueryStatus qs;
+};
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls of type `struct LookupRefundsContext *`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lookup_refunds_cb (void *cls,
+                   PGresult *result,
+                   unsigned int num_results)
+{
+  struct LookupRefundsContext *lrc = cls;
+  struct PostgresClosure *pg = lrc->pg;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_Amount refund_amount;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                            &coin_pub),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("refund_amount",
+                                   &refund_amount),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      lrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
+      return;
+    }
+    lrc->rc (lrc->rc_cls,
+             &coin_pub,
+             &refund_amount);
+    GNUNET_PQ_cleanup_result (rs); /* technically useless here */
+  }
+  lrc->qs = num_results;
+}
+
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_refunds (
+  void *cls,
+  const char *instance_id,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  TALER_MERCHANTDB_RefundCallback rc,
+  void *rc_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_end
+  };
+  struct LookupRefundsContext lrc = {
+    .rc = rc,
+    .rc_cls = rc_cls,
+    .pg = pg
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  /* no preflight check here, run in transaction by caller! */
+  TALER_LOG_DEBUG ("Looking for refund of h_contract_terms %s at `%s'\n",
+                   GNUNET_h2s (&h_contract_terms->hash),
+                   instance_id);
+  check_connection (pg);
+  PREPARE (pg,
+           "lookup_refunds",
+           "SELECT"
+           " coin_pub"
+           ",refund_amount_val"
+           ",refund_amount_frac"
+           " FROM merchant_refunds"
+           " WHERE order_serial="
+           "  (SELECT order_serial"
+           "     FROM merchant_contract_terms"
+           "    WHERE h_contract_terms=$2"
+           "      AND merchant_serial="
+           "        (SELECT merchant_serial"
+           "           FROM merchant_instances"
+           "          WHERE merchant_id=$1))");
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "lookup_refunds",
+                                             params,
+                                             &lookup_refunds_cb,
+                                             &lrc);
+  if (0 >= qs)
+    return qs;
+  return lrc.qs;
+}
diff --git a/src/backenddb/pg_lookup_refunds.h 
b/src/backenddb/pg_lookup_refunds.h
new file mode 100644
index 00000000..dcd0d203
--- /dev/null
+++ b/src/backenddb/pg_lookup_refunds.h
@@ -0,0 +1,45 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_lookup_refunds.h
+ * @brief implementation of the lookup_refunds function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_LOOKUP_REFUNDS_H
+#define PG_LOOKUP_REFUNDS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Obtain refunds associated with a contract.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param instance_id instance to lookup refunds for
+ * @param h_contract_terms hash code of the contract
+ * @param rc function to call for each coin on which there is a refund
+ * @param rc_cls closure for @a rc
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_lookup_refunds (void *cls,
+                       const char *instance_id,
+                       const struct TALER_PrivateContractHashP 
*h_contract_terms,
+                       TALER_MERCHANTDB_RefundCallback rc,
+                       void *rc_cls);
+
+#endif
diff --git a/src/backenddb/pg_mark_contract_paid.c 
b/src/backenddb/pg_mark_contract_paid.c
new file mode 100644
index 00000000..1119dd76
--- /dev/null
+++ b/src/backenddb/pg_mark_contract_paid.c
@@ -0,0 +1,112 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_mark_contract_paid.c
+ * @brief Implementation of the mark_contract_paid function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_mark_contract_paid.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_mark_contract_paid (
+  void *cls,
+  const char *instance_id,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const char *session_id)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_string (session_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_QueryParam uparams[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_end
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  /* Session ID must always be given by the caller. */
+  GNUNET_assert (NULL != session_id);
+
+  /* no preflight check here, run in transaction by caller! */
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Marking h_contract_terms '%s' of %s as paid for session `%s'\n",
+              GNUNET_h2s (&h_contract_terms->hash),
+              instance_id,
+              session_id);
+  PREPARE (pg,
+           "mark_contract_paid",
+           "UPDATE merchant_contract_terms SET"
+           " paid=TRUE"
+           ",session_id=$3"
+           " WHERE h_contract_terms=$2"
+           "   AND merchant_serial="
+           "     (SELECT merchant_serial"
+           "        FROM merchant_instances"
+           "       WHERE merchant_id=$1)");
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                           "mark_contract_paid",
+                                           params);
+  if (qs <= 0)
+    return qs;
+  PREPARE (pg,
+           "mark_inventory_sold",
+           "UPDATE merchant_inventory SET"
+           " total_sold=total_sold + order_locks.total_locked"
+           " FROM (SELECT total_locked,product_serial"
+           "       FROM merchant_order_locks"
+           "       WHERE order_serial="
+           "       (SELECT order_serial"
+           "          FROM merchant_contract_terms"
+           "         WHERE h_contract_terms=$2"
+           "           AND merchant_serial="
+           "           (SELECT merchant_serial"
+           "              FROM merchant_instances"
+           "             WHERE merchant_id=$1))"
+           "       ) AS order_locks"
+           " WHERE merchant_inventory.product_serial"
+           "             =order_locks.product_serial");
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                           "mark_inventory_sold",
+                                           uparams);
+  if (qs < 0)
+    return qs; /* 0: no inventory management, that's OK! */
+  /* ON DELETE CASCADE deletes from merchant_order_locks */
+  PREPARE (pg,
+           "delete_completed_order",
+           "WITH md AS"
+           "  (SELECT merchant_serial"
+           "     FROM merchant_instances"
+           "    WHERE merchant_id=$1) "
+           "DELETE"
+           " FROM merchant_orders"
+           " WHERE order_serial="
+           "       (SELECT order_serial"
+           "          FROM merchant_contract_terms"
+           "          JOIN md USING (merchant_serial)"
+           "         WHERE h_contract_terms=$2)");
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "delete_completed_order",
+                                             uparams);
+}
diff --git a/src/backenddb/pg_mark_contract_paid.h 
b/src/backenddb/pg_mark_contract_paid.h
new file mode 100644
index 00000000..20c87bd2
--- /dev/null
+++ b/src/backenddb/pg_mark_contract_paid.h
@@ -0,0 +1,45 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_mark_contract_paid.h
+ * @brief implementation of the mark_contract_paid function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_MARK_CONTRACT_PAID_H
+#define PG_MARK_CONTRACT_PAID_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Mark contract as paid and store the current @a session_id
+ * for which the contract was paid. Deletes the underlying order
+ * and marks the locked stocks of the order as sold.
+ *
+ * @param cls closure
+ * @param instance_id instance to mark contract as paid for
+ * @param h_contract_terms hash of the contract that is now paid
+ * @param session_id the session that paid the contract
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_mark_contract_paid (void *cls,
+                           const char *instance_id,
+                           const struct TALER_PrivateContractHashP 
*h_contract_terms,
+                           const char *session_id);
+
+#endif
diff --git a/src/backenddb/pg_refund_coin.c b/src/backenddb/pg_refund_coin.c
new file mode 100644
index 00000000..3b124612
--- /dev/null
+++ b/src/backenddb/pg_refund_coin.c
@@ -0,0 +1,77 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_refund_coin.c
+ * @brief Implementation of the refund_coin function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "pg_refund_coin.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TMH_PG_refund_coin (void *cls,
+                    const char *instance_id,
+                    const struct TALER_PrivateContractHashP *h_contract_terms,
+                    struct GNUNET_TIME_Timestamp refund_timestamp,
+                    const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                    const char *reason)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_timestamp (&refund_timestamp),
+    GNUNET_PQ_query_param_auto_from_type (coin_pub),
+    GNUNET_PQ_query_param_string (reason),
+    GNUNET_PQ_query_param_end
+  };
+  PREPARE (pg,
+           "refund_coin",
+           "INSERT INTO merchant_refunds"
+           "(order_serial"
+           ",rtransaction_id"
+           ",refund_timestamp"
+           ",coin_pub"
+           ",reason"
+           ",refund_amount_val"
+           ",refund_amount_frac"
+           ") "
+           "SELECT "
+           " order_serial"
+           ",0" /* rtransaction_id always 0 for /abort */
+           ",$3"
+           ",coin_pub"
+           ",$5"
+           ",amount_with_fee_val"
+           ",amount_with_fee_frac"
+           " FROM merchant_deposits"
+           " WHERE coin_pub=$4"
+           "   AND order_serial="
+           "  (SELECT order_serial"
+           "     FROM merchant_contract_terms"
+           "    WHERE h_contract_terms=$2"
+           "      AND merchant_serial="
+           "        (SELECT merchant_serial"
+           "           FROM merchant_instances"
+           "          WHERE merchant_id=$1))");
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "refund_coin",
+                                             params);
+}
diff --git a/src/backenddb/pg_refund_coin.h b/src/backenddb/pg_refund_coin.h
new file mode 100644
index 00000000..6b5c5d30
--- /dev/null
+++ b/src/backenddb/pg_refund_coin.h
@@ -0,0 +1,51 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file backenddb/pg_refund_coin.h
+ * @brief implementation of the refund_coin function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef PG_REFUND_COIN_H
+#define PG_REFUND_COIN_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler_merchantdb_plugin.h"
+
+/**
+ * Function called during aborts to refund a coin. Marks the
+ * respective coin as refunded.
+ *
+ * @param cls closure
+ * @param instance_id instance to refund payment for
+ * @param h_contract_terms hash of the contract to refund coin for
+ * @param refund_timestamp timestamp of the refund
+ * @param coin_pub public key of the coin to refund (fully)
+ * @param reason text justifying the refund
+ * @return transaction status
+ *        #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a coin_pub is unknown to us;
+ *        #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid,
+ *        regardless of whether it actually increased the refund
+ */
+enum GNUNET_DB_QueryStatus
+TMH_PG_refund_coin (void *cls,
+                    const char *instance_id,
+                    const struct TALER_PrivateContractHashP *h_contract_terms,
+                    struct GNUNET_TIME_Timestamp refund_timestamp,
+                    const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                    const char *reason);
+
+#endif
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 757a303c..3dbdae48 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -72,6 +72,15 @@
 #include "pg_insert_contract_terms.h"
 #include "pg_update_contract_terms.h"
 #include "pg_delete_contract_terms.h"
+#include "pg_lookup_deposits.h"
+#include "pg_insert_exchange_signkey.h"
+#include "pg_insert_deposit.h"
+#include "pg_lookup_refunds.h"
+#include "pg_mark_contract_paid.h"
+#include "pg_refund_coin.h"
+#include "pg_lookup_order_status.h"
+#include "pg_lookup_order_status_by_serial.h"
+#include "pg_lookup_payment_status.h"
 #include "pg_set_transfer_status_to_confirmed.h"
 
 
@@ -349,633 +358,6 @@ postgres_commit (void *cls)
 }
 
 
-/**
- * Closure for #lookup_deposits_cb().
- */
-struct LookupDepositsContext
-{
-  /**
-   * Function to call with results.
-   */
-  TALER_MERCHANTDB_DepositsCallback cb;
-
-  /**
-   * Closure for @e cls.
-   */
-  void *cb_cls;
-
-  /**
-   * Plugin context.
-   */
-  struct PostgresClosure *pg;
-
-  /**
-   * Transaction status (set).
-   */
-  enum GNUNET_DB_QueryStatus qs;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param[in,out] cls of type `struct LookupDepositsContext *`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-lookup_deposits_cb (void *cls,
-                    PGresult *result,
-                    unsigned int num_results)
-{
-  struct LookupDepositsContext *ldc = cls;
-  struct PostgresClosure *pg = ldc->pg;
-
-  for (unsigned int i = 0; i<num_results; i++)
-  {
-    struct TALER_CoinSpendPublicKeyP coin_pub;
-    struct TALER_Amount amount_with_fee;
-    struct TALER_Amount deposit_fee;
-    struct TALER_Amount refund_fee;
-    struct TALER_Amount wire_fee;
-    char *exchange_url;
-    struct GNUNET_PQ_ResultSpec rs[] = {
-      GNUNET_PQ_result_spec_string ("exchange_url",
-                                    &exchange_url),
-      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
-                                            &coin_pub),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &amount_with_fee),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee",
-                                   &deposit_fee),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("refund_fee",
-                                   &refund_fee),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
-                                   &wire_fee),
-      GNUNET_PQ_result_spec_end
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_PQ_extract_result (result,
-                                  rs,
-                                  i))
-    {
-      GNUNET_break (0);
-      ldc->qs = GNUNET_DB_STATUS_HARD_ERROR;
-      return;
-    }
-    ldc->cb (ldc->cb_cls,
-             exchange_url,
-             &coin_pub,
-             &amount_with_fee,
-             &deposit_fee,
-             &refund_fee,
-             &wire_fee);
-    GNUNET_PQ_cleanup_result (rs);
-  }
-  ldc->qs = num_results;
-}
-
-
-/**
- * Lookup information about coins that were successfully deposited for a
- * given contract.
- *
- * @param cls closure
- * @param instance_id instance to lookup deposits for
- * @param h_contract_terms proposal data's hashcode
- * @param cb function to call with payment data
- * @param cb_cls closure for @a cb
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_deposits (
-  void *cls,
-  const char *instance_id,
-  const struct TALER_PrivateContractHashP *h_contract_terms,
-  TALER_MERCHANTDB_DepositsCallback cb,
-  void *cb_cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_end
-  };
-  struct LookupDepositsContext ldc = {
-    .cb = cb,
-    .cb_cls = cb_cls,
-    .pg = pg
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  /* no preflight check here, run in its own transaction by the caller! */
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Finding deposits for h_contract_terms '%s'\n",
-              GNUNET_h2s (&h_contract_terms->hash));
-  check_connection (pg);
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "lookup_deposits",
-                                             params,
-                                             &lookup_deposits_cb,
-                                             &ldc);
-  if (qs <= 0)
-    return qs;
-  return ldc.qs;
-}
-
-
-/**
- * Insert an exchange signing key into our database.
- *
- * @param cls closure
- * @param master_pub exchange master public key used for @a master_sig
- * @param exchange_pub exchange signing key to insert
- * @param start_date when does the signing key become valid
- * @param expire_date when does the signing key stop being used
- * @param end_date when does the signing key become void as proof
- * @param master_sig signature of @a master_pub over the @a exchange_pub and 
the dates
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_exchange_signkey (
-  void *cls,
-  const struct TALER_MasterPublicKeyP *master_pub,
-  const struct TALER_ExchangePublicKeyP *exchange_pub,
-  struct GNUNET_TIME_Timestamp start_date,
-  struct GNUNET_TIME_Timestamp expire_date,
-  struct GNUNET_TIME_Timestamp end_date,
-  const struct TALER_MasterSignatureP *master_sig)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (master_pub),
-    GNUNET_PQ_query_param_auto_from_type (exchange_pub),
-    GNUNET_PQ_query_param_timestamp (&start_date),
-    GNUNET_PQ_query_param_timestamp (&expire_date),
-    GNUNET_PQ_query_param_timestamp (&end_date),
-    GNUNET_PQ_query_param_auto_from_type (master_sig),
-    GNUNET_PQ_query_param_end
-  };
-
-  check_connection (pg);
-  postgres_preflight (pg);
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "insert_exchange_signkey",
-                                             params);
-
-}
-
-
-/**
- * Insert payment confirmation from the exchange into the database.
- *
- * @param cls closure
- * @param instance_id instance to lookup deposits for
- * @param deposit_timestamp time when the exchange generated the deposit 
confirmation
- * @param h_contract_terms proposal data's hashcode
- * @param coin_pub public key of the coin
- * @param exchange_url URL of the exchange that issued @a coin_pub
- * @param amount_with_fee amount the exchange will deposit for this coin
- * @param deposit_fee fee the exchange will charge for this coin
- * @param wire_fee wire fee the exchange charges
- * @param refund_fee fee the exchange charges to refund this coin
- * @param h_wire hash of the wire details of the target account of the merchant
- * @param exchange_sig signature from exchange that coin was accepted
- * @param exchange_pub signgin key that was used for @a exchange_sig
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_deposit (
-  void *cls,
-  const char *instance_id,
-  struct GNUNET_TIME_Timestamp deposit_timestamp,
-  const struct TALER_PrivateContractHashP *h_contract_terms,
-  const struct TALER_CoinSpendPublicKeyP *coin_pub,
-  const char *exchange_url,
-  const struct TALER_Amount *amount_with_fee,
-  const struct TALER_Amount *deposit_fee,
-  const struct TALER_Amount *refund_fee,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_MerchantWireHashP *h_wire,
-  const struct TALER_ExchangeSignatureP *exchange_sig,
-  const struct TALER_ExchangePublicKeyP *exchange_pub)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_timestamp (&deposit_timestamp), /* $3 */
-    GNUNET_PQ_query_param_auto_from_type (coin_pub),
-    GNUNET_PQ_query_param_string (exchange_url),
-    TALER_PQ_query_param_amount (amount_with_fee), /* $6/$7 */
-    TALER_PQ_query_param_amount (deposit_fee),  /* $8, $9 */
-    TALER_PQ_query_param_amount (refund_fee), /* $10, $11 */
-    TALER_PQ_query_param_amount (wire_fee),  /* $12, $13 */
-    GNUNET_PQ_query_param_auto_from_type (h_wire), /* $14 */
-    GNUNET_PQ_query_param_auto_from_type (exchange_sig), /* $15 */
-    GNUNET_PQ_query_param_auto_from_type (exchange_pub), /* $16 */
-    GNUNET_PQ_query_param_end
-  };
-
-  /* no preflight check here, run in transaction by caller! */
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Storing deposit for instance `%s' h_contract_terms `%s', 
coin_pub: `%s', amount_with_fee: %s\n",
-              instance_id,
-              GNUNET_h2s (&h_contract_terms->hash),
-              TALER_B2S (coin_pub),
-              TALER_amount2s (amount_with_fee));
-  check_connection (pg);
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "insert_deposit",
-                                             params);
-
-}
-
-
-/**
- * Closure for #lookup_refunds_cb().
- */
-struct LookupRefundsContext
-{
-  /**
-   * Function to call for each refund.
-   */
-  TALER_MERCHANTDB_RefundCallback rc;
-
-  /**
-   * Closure for @e rc.
-   */
-  void *rc_cls;
-
-  /**
-   * Plugin context.
-   */
-  struct PostgresClosure *pg;
-
-  /**
-   * Transaction result.
-   */
-  enum GNUNET_DB_QueryStatus qs;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls of type `struct LookupRefundsContext *`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-lookup_refunds_cb (void *cls,
-                   PGresult *result,
-                   unsigned int num_results)
-{
-  struct LookupRefundsContext *lrc = cls;
-  struct PostgresClosure *pg = lrc->pg;
-
-  for (unsigned int i = 0; i<num_results; i++)
-  {
-    struct TALER_CoinSpendPublicKeyP coin_pub;
-    struct TALER_Amount refund_amount;
-    struct GNUNET_PQ_ResultSpec rs[] = {
-      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
-                                            &coin_pub),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("refund_amount",
-                                   &refund_amount),
-      GNUNET_PQ_result_spec_end
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_PQ_extract_result (result,
-                                  rs,
-                                  i))
-    {
-      GNUNET_break (0);
-      lrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
-      return;
-    }
-    lrc->rc (lrc->rc_cls,
-             &coin_pub,
-             &refund_amount);
-    GNUNET_PQ_cleanup_result (rs); /* technically useless here */
-  }
-  lrc->qs = num_results;
-}
-
-
-/**
- * Obtain refunds associated with a contract.
- *
- * @param cls closure, typically a connection to the db
- * @param instance_id instance to lookup refunds for
- * @param h_contract_terms hash code of the contract
- * @param rc function to call for each coin on which there is a refund
- * @param rc_cls closure for @a rc
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_refunds (
-  void *cls,
-  const char *instance_id,
-  const struct TALER_PrivateContractHashP *h_contract_terms,
-  TALER_MERCHANTDB_RefundCallback rc,
-  void *rc_cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_end
-  };
-  struct LookupRefundsContext lrc = {
-    .rc = rc,
-    .rc_cls = rc_cls,
-    .pg = pg
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  /* no preflight check here, run in transaction by caller! */
-  TALER_LOG_DEBUG ("Looking for refund of h_contract_terms %s at `%s'\n",
-                   GNUNET_h2s (&h_contract_terms->hash),
-                   instance_id);
-  check_connection (pg);
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "lookup_refunds",
-                                             params,
-                                             &lookup_refunds_cb,
-                                             &lrc);
-  if (0 >= qs)
-    return qs;
-  return lrc.qs;
-}
-
-
-/**
- * Mark contract as paid and store the current @a session_id
- * for which the contract was paid. Deletes the underlying order
- * and marks the locked stocks of the order as sold.
- *
- * @param cls closure
- * @param instance_id instance to mark contract as paid for
- * @param h_contract_terms hash of the contract that is now paid
- * @param session_id the session that paid the contract
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_mark_contract_paid (
-  void *cls,
-  const char *instance_id,
-  const struct TALER_PrivateContractHashP *h_contract_terms,
-  const char *session_id)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_string (session_id),
-    GNUNET_PQ_query_param_end
-  };
-  struct GNUNET_PQ_QueryParam uparams[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_end
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  /* Session ID must always be given by the caller. */
-  GNUNET_assert (NULL != session_id);
-
-  /* no preflight check here, run in transaction by caller! */
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Marking h_contract_terms '%s' of %s as paid for session `%s'\n",
-              GNUNET_h2s (&h_contract_terms->hash),
-              instance_id,
-              session_id);
-  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                           "mark_contract_paid",
-                                           params);
-  if (qs <= 0)
-    return qs;
-  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                           "mark_inventory_sold",
-                                           uparams);
-  if (qs < 0)
-    return qs; /* 0: no inventory management, that's OK! */
-  /* ON DELETE CASCADE deletes from merchant_order_locks */
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "delete_completed_order",
-                                             uparams);
-}
-
-
-/**
- * Function called during aborts to refund a coin. Marks the
- * respective coin as refunded.
- *
- * @param cls closure
- * @param instance_id instance to refund payment for
- * @param h_contract_terms hash of the contract to refund coin for
- * @param refund_timestamp timestamp of the refund
- * @param coin_pub public key of the coin to refund (fully)
- * @param reason text justifying the refund
- * @return transaction status
- *        #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a coin_pub is unknown to us;
- *        #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid,
- *        regardless of whether it actually increased the refund
- */
-static enum GNUNET_DB_QueryStatus
-postgres_refund_coin (void *cls,
-                      const char *instance_id,
-                      const struct TALER_PrivateContractHashP 
*h_contract_terms,
-                      struct GNUNET_TIME_Timestamp refund_timestamp,
-                      const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                      const char *reason)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_timestamp (&refund_timestamp),
-    GNUNET_PQ_query_param_auto_from_type (coin_pub),
-    GNUNET_PQ_query_param_string (reason),
-    GNUNET_PQ_query_param_end
-  };
-
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "refund_coin",
-                                             params);
-}
-
-
-/**
- * Retrieve contract terms given its @a order_id
- *
- * @param cls closure
- * @param instance_id instance's identifier
- * @param order_id order to lookup contract for
- * @param[out] h_contract_terms set to the hash of the contract.
- * @param[out] paid set to the payment status of the contract
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_order_status (
-  void *cls,
-  const char *instance_id,
-  const char *order_id,
-  struct TALER_PrivateContractHashP *h_contract_terms,
-  bool *paid)
-{
-  struct PostgresClosure *pg = cls;
-  uint8_t paid8;
-  enum GNUNET_DB_QueryStatus qs;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_string (order_id),
-    GNUNET_PQ_query_param_end
-  };
-  struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
-                                          h_contract_terms),
-    GNUNET_PQ_result_spec_auto_from_type ("paid",
-                                          &paid8),
-    GNUNET_PQ_result_spec_end
-  };
-
-  check_connection (pg);
-  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                 "lookup_order_status",
-                                                 params,
-                                                 rs);
-  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
-    *paid = (0 != paid8);
-  else
-    *paid = false; /* just to be safe(r) */
-  return qs;
-}
-
-
-/**
- * Retrieve contract terms given its @a order_serial
- *
- * @param cls closure
- * @param instance_id instance's identifier
- * @param order_serial serial ID of the order to look up
- * @param[out] order_id set to ID of the order
- * @param[out] h_contract_terms set to the hash of the contract.
- * @param[out] paid set to the payment status of the contract
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_order_status_by_serial (void *cls,
-                                        const char *instance_id,
-                                        uint64_t order_serial,
-                                        char **order_id,
-                                        struct TALER_PrivateContractHashP *
-                                        h_contract_terms,
-                                        bool *paid)
-{
-  struct PostgresClosure *pg = cls;
-  uint8_t paid8;
-  enum GNUNET_DB_QueryStatus qs;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_uint64 (&order_serial),
-    GNUNET_PQ_query_param_end
-  };
-  struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
-                                          h_contract_terms),
-    GNUNET_PQ_result_spec_auto_from_type ("paid",
-                                          &paid8),
-    GNUNET_PQ_result_spec_string ("order_id",
-                                  order_id),
-    GNUNET_PQ_result_spec_end
-  };
-
-  check_connection (pg);
-  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                 
"lookup_order_status_by_serial",
-                                                 params,
-                                                 rs);
-  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
-    *paid = (0 != paid8);
-  else
-    *paid = false; /* just to be safe(r) */
-  return qs;
-}
-
-
-/**
- * Retrieve payment and wire status for a given @a order_serial and session ID.
- *
- * @param cls closure
- * @param order_serial identifies the order
- * @param session_id session for which to check the payment status, NULL for 
any
- * @param[out] paid set to the payment status of the contract
- * @param[out] wired set to the wire transfer status of the exchange payment
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_payment_status (void *cls,
-                                uint64_t order_serial,
-                                const char *session_id,
-                                bool *paid,
-                                bool *wired)
-{
-  struct PostgresClosure *pg = cls;
-  uint8_t paid8;
-  uint8_t wired8;
-  enum GNUNET_DB_QueryStatus qs;
-  struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_auto_from_type ("paid",
-                                          &paid8),
-    GNUNET_PQ_result_spec_auto_from_type ("wired",
-                                          &wired8),
-    GNUNET_PQ_result_spec_end
-  };
-  check_connection (pg);
-  if (NULL == session_id)
-  {
-    struct GNUNET_PQ_QueryParam params[] = {
-      GNUNET_PQ_query_param_uint64 (&order_serial),
-      GNUNET_PQ_query_param_end
-    };
-
-    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                   "lookup_payment_status",
-                                                   params,
-                                                   rs);
-  }
-  else
-  {
-    struct GNUNET_PQ_QueryParam params[] = {
-      GNUNET_PQ_query_param_uint64 (&order_serial),
-      GNUNET_PQ_query_param_string (session_id),
-      GNUNET_PQ_query_param_end
-    };
-
-    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                   
"lookup_payment_status_session_id",
-                                                   params,
-                                                   rs);
-  }
-  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
-  {
-    *paid = (0 != paid8);
-    *wired = (0 != wired8);
-  }
-  else
-  {
-    *paid = false; /* just to be safe(r) */
-    *wired = false; /* just to be safe(r) */
-  }
-  return qs;
-}
-
-
 /**
  * Closure for lookup_deposits_by_order_cb().
  */
@@ -5428,205 +4810,6 @@ postgres_connect (void *cls)
   struct GNUNET_PQ_PreparedStatement ps[] = {
     GNUNET_PQ_make_prepare ("end_transaction",
                             "COMMIT"),
-    /* for postgres_lookup_deposits() */
-    GNUNET_PQ_make_prepare ("lookup_deposits",
-                            "SELECT"
-                            " exchange_url"
-                            ",coin_pub"
-                            ",amount_with_fee_val"
-                            ",amount_with_fee_frac"
-                            ",deposit_fee_val"
-                            ",deposit_fee_frac"
-                            ",refund_fee_val"
-                            ",refund_fee_frac"
-                            ",wire_fee_val"
-                            ",wire_fee_frac"
-                            " FROM merchant_deposits"
-                            " WHERE order_serial="
-                            "     (SELECT order_serial"
-                            "        FROM merchant_contract_terms"
-                            "        WHERE h_contract_terms=$2"
-                            "          AND merchant_serial="
-                            "          (SELECT merchant_serial"
-                            "             FROM merchant_instances"
-                            "            WHERE merchant_id=$1))"),
-    /* for postgres_insert_exchange_signkey() */
-    GNUNET_PQ_make_prepare ("insert_exchange_signkey",
-                            "INSERT INTO merchant_exchange_signing_keys"
-                            "(master_pub"
-                            ",exchange_pub"
-                            ",start_date"
-                            ",expire_date"
-                            ",end_date"
-                            ",master_sig)"
-                            "VALUES"
-                            "($1, $2, $3, $4, $5, $6)"),
-    /* for postgres_insert_deposit() */
-    GNUNET_PQ_make_prepare ("insert_deposit",
-                            "WITH md AS"
-                            "  (SELECT account_serial, merchant_serial"
-                            "   FROM merchant_accounts"
-                            "   WHERE h_wire=$14"
-                            "    AND merchant_serial="
-                            "     (SELECT merchant_serial"
-                            "        FROM merchant_instances"
-                            "        WHERE merchant_id=$1))"
-                            ", ed AS"
-                            "  (SELECT signkey_serial"
-                            "   FROM merchant_exchange_signing_keys"
-                            "   WHERE exchange_pub=$16"
-                            "   ORDER BY start_date DESC"
-                            "   LIMIT 1)"
-                            "INSERT INTO merchant_deposits"
-                            "(order_serial"
-                            ",deposit_timestamp"
-                            ",coin_pub"
-                            ",exchange_url"
-                            ",amount_with_fee_val"
-                            ",amount_with_fee_frac"
-                            ",deposit_fee_val"
-                            ",deposit_fee_frac"
-                            ",refund_fee_val"
-                            ",refund_fee_frac"
-                            ",wire_fee_val"
-                            ",wire_fee_frac"
-                            ",exchange_sig"
-                            ",signkey_serial"
-                            ",account_serial)"
-                            " SELECT "
-                            "   order_serial"
-                            "  ,$3, $4, $5, $6, $7, $8, $9, $10, $11, $12, 
$13, $15"
-                            "  ,ed.signkey_serial"
-                            "  ,md.account_serial"
-                            "  FROM merchant_contract_terms"
-                            "   JOIN md USING (merchant_serial)"
-                            "   FULL OUTER JOIN ed ON TRUE"
-                            "  WHERE h_contract_terms=$2"),
-    /* for postgres_lookup_refunds() */
-    GNUNET_PQ_make_prepare ("lookup_refunds",
-                            "SELECT"
-                            " coin_pub"
-                            ",refund_amount_val"
-                            ",refund_amount_frac"
-                            " FROM merchant_refunds"
-                            " WHERE order_serial="
-                            "  (SELECT order_serial"
-                            "     FROM merchant_contract_terms"
-                            "    WHERE h_contract_terms=$2"
-                            "      AND merchant_serial="
-                            "        (SELECT merchant_serial"
-                            "           FROM merchant_instances"
-                            "          WHERE merchant_id=$1))"),
-    /* for postgres_mark_contract_paid() */
-    GNUNET_PQ_make_prepare ("mark_contract_paid",
-                            "UPDATE merchant_contract_terms SET"
-                            " paid=TRUE"
-                            ",session_id=$3"
-                            " WHERE h_contract_terms=$2"
-                            "   AND merchant_serial="
-                            "     (SELECT merchant_serial"
-                            "        FROM merchant_instances"
-                            "       WHERE merchant_id=$1)"),
-    /* for postgres_mark_contract_paid() */
-    GNUNET_PQ_make_prepare ("mark_inventory_sold",
-                            "UPDATE merchant_inventory SET"
-                            " total_sold=total_sold + order_locks.total_locked"
-                            " FROM (SELECT total_locked,product_serial"
-                            "       FROM merchant_order_locks"
-                            "       WHERE order_serial="
-                            "       (SELECT order_serial"
-                            "          FROM merchant_contract_terms"
-                            "         WHERE h_contract_terms=$2"
-                            "           AND merchant_serial="
-                            "           (SELECT merchant_serial"
-                            "              FROM merchant_instances"
-                            "             WHERE merchant_id=$1))"
-                            "       ) AS order_locks"
-                            " WHERE merchant_inventory.product_serial"
-                            "             =order_locks.product_serial"),
-    /* for postgres_mark_contract_paid() */
-    GNUNET_PQ_make_prepare ("delete_completed_order",
-                            "WITH md AS"
-                            "  (SELECT merchant_serial"
-                            "     FROM merchant_instances"
-                            "    WHERE merchant_id=$1) "
-                            "DELETE"
-                            " FROM merchant_orders"
-                            " WHERE order_serial="
-                            "       (SELECT order_serial"
-                            "          FROM merchant_contract_terms"
-                            "          JOIN md USING (merchant_serial)"
-                            "         WHERE h_contract_terms=$2)"),
-    /* for postgres_refund_coin() */
-    GNUNET_PQ_make_prepare ("refund_coin",
-                            "INSERT INTO merchant_refunds"
-                            "(order_serial"
-                            ",rtransaction_id"
-                            ",refund_timestamp"
-                            ",coin_pub"
-                            ",reason"
-                            ",refund_amount_val"
-                            ",refund_amount_frac"
-                            ") "
-                            "SELECT "
-                            " order_serial"
-                            ",0" /* rtransaction_id always 0 for /abort */
-                            ",$3"
-                            ",coin_pub"
-                            ",$5"
-                            ",amount_with_fee_val"
-                            ",amount_with_fee_frac"
-                            " FROM merchant_deposits"
-                            " WHERE coin_pub=$4"
-                            "   AND order_serial="
-                            "  (SELECT order_serial"
-                            "     FROM merchant_contract_terms"
-                            "    WHERE h_contract_terms=$2"
-                            "      AND merchant_serial="
-                            "        (SELECT merchant_serial"
-                            "           FROM merchant_instances"
-                            "          WHERE merchant_id=$1))"),
-
-    /* for postgres_lookup_order_status() */
-    GNUNET_PQ_make_prepare ("lookup_order_status",
-                            "SELECT"
-                            " h_contract_terms"
-                            ",paid"
-                            " FROM merchant_contract_terms"
-                            " WHERE merchant_serial="
-                            "     (SELECT merchant_serial "
-                            "        FROM merchant_instances"
-                            "        WHERE merchant_id=$1)"
-                            "   AND order_id=$2"),
-
-    /* for postgres_lookup_order_status_by_serial() */
-    GNUNET_PQ_make_prepare ("lookup_order_status_by_serial",
-                            "SELECT"
-                            " h_contract_terms"
-                            ",order_id"
-                            ",paid"
-                            " FROM merchant_contract_terms"
-                            " WHERE merchant_serial="
-                            "     (SELECT merchant_serial "
-                            "        FROM merchant_instances"
-                            "        WHERE merchant_id=$1)"
-                            "   AND order_serial=$2"),
-
-    /* for postgres_lookup_payment_status() */
-    GNUNET_PQ_make_prepare ("lookup_payment_status",
-                            "SELECT"
-                            " wired"
-                            ",paid"
-                            " FROM merchant_contract_terms"
-                            " WHERE order_serial=$1"),
-    /* for postgres_lookup_payment_status() */
-    GNUNET_PQ_make_prepare ("lookup_payment_status_session_id",
-                            "SELECT"
-                            " wired"
-                            ",paid"
-                            " FROM merchant_contract_terms"
-                            " WHERE order_serial=$1"
-                            "   AND session_id=$2"),
     /* for postgres_lookup_deposits_by_order() */
     GNUNET_PQ_make_prepare ("lookup_deposits_by_order",
                             "SELECT"
@@ -6700,16 +5883,24 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
     = &TMH_PG_update_contract_terms;
   plugin->delete_contract_terms
     = &TMH_PG_delete_contract_terms;
-  plugin->lookup_deposits = &postgres_lookup_deposits;
-  plugin->insert_exchange_signkey = &postgres_insert_exchange_signkey;
-  plugin->insert_deposit = &postgres_insert_deposit;
-  plugin->lookup_refunds = &postgres_lookup_refunds;
-  plugin->mark_contract_paid = &postgres_mark_contract_paid;
-  plugin->refund_coin = &postgres_refund_coin;
-  plugin->lookup_order_status = &postgres_lookup_order_status;
-  plugin->lookup_order_status_by_serial =
-    &postgres_lookup_order_status_by_serial;
-  plugin->lookup_payment_status = &postgres_lookup_payment_status;
+  plugin->lookup_deposits
+    = &TMH_PG_lookup_deposits;
+  plugin->insert_exchange_signkey
+    = &TMH_PG_insert_exchange_signkey;
+  plugin->insert_deposit
+    = &TMH_PG_insert_deposit;
+  plugin->lookup_refunds
+    = &TMH_PG_lookup_refunds;
+  plugin->mark_contract_paid
+    = &TMH_PG_mark_contract_paid;
+  plugin->refund_coin
+    = &TMH_PG_refund_coin;
+  plugin->lookup_order_status
+    = &TMH_PG_lookup_order_status;
+  plugin->lookup_order_status_by_serial
+    = &TMH_PG_lookup_order_status_by_serial;
+  plugin->lookup_payment_status
+    = &TMH_PG_lookup_payment_status;
   plugin->lookup_deposits_by_order = &postgres_lookup_deposits_by_order;
   plugin->lookup_transfer_details_by_order =
     &postgres_lookup_transfer_details_by_order;

-- 
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]