merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

pg_account_kyc_get_status.c (6692B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2022 Taler Systems SA
      4 
      5    TALER is free software; you can redistribute it and/or modify it under the
      6    terms of the GNU General Public License as published by the Free Software
      7    Foundation; either version 3, or (at your option) any later version.
      8 
      9    TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License along with
     14    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 /**
     17  * @file backenddb/pg_account_kyc_get_status.c
     18  * @brief Implementation of the account_kyc_get_status function for Postgres
     19  * @author Iván Ávalos
     20  */
     21 #include "platform.h"
     22 #include <taler/taler_error_codes.h>
     23 #include <taler/taler_dbevents.h>
     24 #include <taler/taler_pq_lib.h>
     25 #include "pg_account_kyc_get_status.h"
     26 #include "pg_helper.h"
     27 
     28 /**
     29  * Closure for kyc_status_cb().
     30  */
     31 struct KycStatusContext
     32 {
     33   /**
     34    * Function to call with results.
     35    */
     36   TALER_MERCHANTDB_KycCallback kyc_cb;
     37 
     38   /**
     39    * Closure for @e kyc_cb.
     40    */
     41   void *kyc_cb_cls;
     42 
     43   /**
     44    * Number of results found.
     45    */
     46   unsigned int count;
     47 
     48   /**
     49    * Set to true on failure(s).
     50    */
     51   bool failure;
     52 };
     53 
     54 
     55 /**
     56  * Function to be called with the results of a SELECT statement
     57  * that has returned @a num_results results about accounts.
     58  *
     59  * @param[in,out] cls of type `struct KycStatusContext *`
     60  * @param result the postgres result
     61  * @param num_results the number of results in @a result
     62  */
     63 static void
     64 kyc_status_cb (void *cls,
     65                PGresult *result,
     66                unsigned int num_results)
     67 {
     68   struct KycStatusContext *ksc = cls;
     69 
     70   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     71               "Got %u KYC records\n",
     72               num_results);
     73   for (unsigned int i = 0; i < num_results; i++)
     74   {
     75     struct TALER_MerchantWireHashP h_wire;
     76     char *exchange_url = NULL;
     77     struct TALER_FullPayto payto_uri;
     78     struct GNUNET_TIME_Timestamp last_check;
     79     bool kyc_ok = false;
     80     struct TALER_AccountAccessTokenP access_token;
     81     bool no_auth = false;
     82     uint32_t h32 = 0;
     83     uint32_t e32 = 0;
     84     bool in_aml_review = false;
     85     bool no_mk; /* left join on merchant_kyc table yielded nothing */
     86     json_t *jlimits = NULL;
     87     struct GNUNET_PQ_ResultSpec rs[] = {
     88       GNUNET_PQ_result_spec_auto_from_type ("h_wire",
     89                                             &h_wire),
     90       GNUNET_PQ_result_spec_string ("payto_uri",
     91                                     &payto_uri.full_payto),
     92       GNUNET_PQ_result_spec_allow_null (
     93         GNUNET_PQ_result_spec_string ("exchange_url",
     94                                       &exchange_url),
     95         &no_mk),
     96       GNUNET_PQ_result_spec_allow_null (
     97         GNUNET_PQ_result_spec_timestamp ("kyc_timestamp",
     98                                          &last_check),
     99         &no_mk),
    100       GNUNET_PQ_result_spec_allow_null (
    101         GNUNET_PQ_result_spec_bool ("kyc_ok",
    102                                     &kyc_ok),
    103         &no_mk),
    104       GNUNET_PQ_result_spec_allow_null (
    105         GNUNET_PQ_result_spec_auto_from_type ("access_token",
    106                                               &access_token),
    107         &no_auth),
    108       GNUNET_PQ_result_spec_allow_null (
    109         GNUNET_PQ_result_spec_uint32 ("exchange_http_status",
    110                                       &h32),
    111         &no_mk),
    112       GNUNET_PQ_result_spec_allow_null (
    113         GNUNET_PQ_result_spec_uint32 ("exchange_ec_code",
    114                                       &e32),
    115         &no_mk),
    116       GNUNET_PQ_result_spec_allow_null (
    117         GNUNET_PQ_result_spec_bool ("aml_review",
    118                                     &in_aml_review),
    119         &no_mk),
    120       GNUNET_PQ_result_spec_allow_null (
    121         TALER_PQ_result_spec_json ("jaccount_limits",
    122                                    &jlimits),
    123         NULL),
    124       GNUNET_PQ_result_spec_end
    125     };
    126     unsigned int last_http_status;
    127     enum TALER_ErrorCode last_ec;
    128 
    129     if (GNUNET_OK !=
    130         GNUNET_PQ_extract_result (result,
    131                                   rs,
    132                                   i))
    133     {
    134       GNUNET_break (0);
    135       ksc->failure = true;
    136       return;
    137     }
    138     last_http_status = (unsigned int) h32;
    139     last_ec = (enum TALER_ErrorCode) (int) e32;
    140     ksc->count++;
    141     ksc->kyc_cb (ksc->kyc_cb_cls,
    142                  &h_wire,
    143                  payto_uri,
    144                  exchange_url,
    145                  last_check,
    146                  kyc_ok,
    147                  (no_auth)
    148                  ? NULL
    149                  : &access_token,
    150                  last_http_status,
    151                  last_ec,
    152                  in_aml_review,
    153                  jlimits);
    154     GNUNET_PQ_cleanup_result (rs);
    155   }
    156 }
    157 
    158 
    159 enum GNUNET_DB_QueryStatus
    160 TMH_PG_account_kyc_get_status (
    161   void *cls,
    162   const char *merchant_id,
    163   const struct TALER_MerchantWireHashP *h_wire,
    164   const char *exchange_url,
    165   TALER_MERCHANTDB_KycCallback kyc_cb,
    166   void *kyc_cb_cls)
    167 {
    168   struct PostgresClosure *pg = cls;
    169   struct KycStatusContext ksc = {
    170     .kyc_cb = kyc_cb,
    171     .kyc_cb_cls = kyc_cb_cls
    172   };
    173   struct GNUNET_PQ_QueryParam params[] = {
    174     GNUNET_PQ_query_param_string (merchant_id),
    175     NULL == exchange_url
    176     ? GNUNET_PQ_query_param_null ()
    177     : GNUNET_PQ_query_param_string (exchange_url),
    178     NULL == h_wire
    179     ? GNUNET_PQ_query_param_null ()
    180     : GNUNET_PQ_query_param_auto_from_type (h_wire),
    181     GNUNET_PQ_query_param_end
    182   };
    183   enum GNUNET_DB_QueryStatus qs;
    184 
    185   check_connection (pg);
    186   PREPARE (pg,
    187            "lookup_kyc_status",
    188            "SELECT"
    189            " ma.h_wire"
    190            ",ma.payto_uri"
    191            ",mk.exchange_url"
    192            ",mk.kyc_timestamp"
    193            ",mk.kyc_ok"
    194            ",mk.access_token"
    195            ",mk.exchange_http_status"
    196            ",mk.exchange_ec_code"
    197            ",mk.aml_review"
    198            ",mk.jaccount_limits::TEXT"
    199            " FROM merchant_instances mi"
    200            " JOIN merchant_accounts ma"
    201            "   USING (merchant_serial)"
    202            " LEFT JOIN merchant_kyc mk"
    203            "   USING (account_serial)"
    204            " WHERE (mi.merchant_id=$1)"
    205            "   AND ma.active"
    206            "   AND ( ($2::TEXT IS NULL)"
    207            "      OR (mk.exchange_url=$2) )"
    208            "   AND ( ($3::BYTEA IS NULL)"
    209            "      OR (ma.h_wire=$3) );");
    210   qs = GNUNET_PQ_eval_prepared_multi_select (
    211     pg->conn,
    212     "lookup_kyc_status",
    213     params,
    214     &kyc_status_cb,
    215     &ksc);
    216   if (ksc.failure)
    217   {
    218     GNUNET_break (0);
    219     return GNUNET_DB_STATUS_HARD_ERROR;
    220   }
    221   if (0 > qs)
    222     return qs;
    223   return ksc.count;
    224 }