merchant

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

taler-merchant-httpd_get-private-transfers.c (7354B)


      1 /*
      2   This file is part of TALER
      3   (C) 2014-2025 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero 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 src/backend/taler-merchant-httpd_get-private-transfers.c
     18  * @brief implement API for obtaining a list of wire transfers
     19  * @author Marcello Stanisci
     20  * @author Christian Grothoff
     21  */
     22 #include "platform.h"
     23 #include <jansson.h>
     24 #include <taler/taler_json_lib.h>
     25 #include "taler-merchant-httpd_get-private-transfers.h"
     26 #include "merchant-database/lookup_transfers.h"
     27 #include "merchant-database/preflight.h"
     28 
     29 
     30 /**
     31  * Function called with information about a wire transfer.
     32  * Generate a response (array entry) based on the given arguments.
     33  *
     34  * @param cls closure with a `json_t *` array to build up the response
     35  * @param credit_amount amount expected to be wired to the merchant (minus fees), NULL if unknown
     36  * @param wtid wire transfer identifier
     37  * @param payto_uri target account that received the wire transfer
     38  * @param exchange_url base URL of the exchange that made the wire transfer
     39  * @param transfer_serial_id serial number identifying the transfer in the backend
     40  * @param expected_transfer_serial_id serial number identifying the expected transfer in the backend, 0 if not @a expected
     41  * @param execution_time when did the exchange make the transfer, #GNUNET_TIME_UNIT_FOREVER_ABS
     42  *           if it did not yet happen
     43  * @param expected true if the merchant acknowledged the wire transfer reception
     44  */
     45 static void
     46 transfer_cb (void *cls,
     47              const struct TALER_Amount *credit_amount,
     48              const struct TALER_WireTransferIdentifierRawP *wtid,
     49              struct TALER_FullPayto payto_uri,
     50              const char *exchange_url,
     51              uint64_t transfer_serial_id,
     52              uint64_t expected_transfer_serial_id,
     53              struct GNUNET_TIME_Absolute execution_time,
     54              bool expected)
     55 {
     56   json_t *ja = cls;
     57   json_t *r;
     58 
     59   r = GNUNET_JSON_PACK (
     60     TALER_JSON_pack_amount ("credit_amount",
     61                             credit_amount),
     62     GNUNET_JSON_pack_data_auto ("wtid",
     63                                 wtid),
     64     TALER_JSON_pack_full_payto ("payto_uri",
     65                                 payto_uri),
     66     GNUNET_JSON_pack_string ("exchange_url",
     67                              exchange_url),
     68     GNUNET_JSON_pack_uint64 ("transfer_serial_id",
     69                              transfer_serial_id),
     70     (0 == expected_transfer_serial_id)
     71     ? GNUNET_JSON_pack_allow_null (
     72       GNUNET_JSON_pack_string ("dummy",
     73                                NULL))
     74     : GNUNET_JSON_pack_uint64 ("expected_transfer_serial_id",
     75                                expected_transfer_serial_id),
     76     // FIXME: protocol breaking to remove...
     77     GNUNET_JSON_pack_bool ("verified",
     78                            false),
     79     // FIXME: protocol breaking to remove...
     80     GNUNET_JSON_pack_bool ("confirmed",
     81                            true),
     82     GNUNET_JSON_pack_bool ("expected",
     83                            expected),
     84     GNUNET_TIME_absolute_is_zero (execution_time)
     85     ? GNUNET_JSON_pack_allow_null (
     86       GNUNET_JSON_pack_string ("dummy",
     87                                NULL))
     88     : GNUNET_JSON_pack_timestamp (
     89       "execution_time",
     90       GNUNET_TIME_absolute_to_timestamp (execution_time)));
     91   GNUNET_assert (0 ==
     92                  json_array_append_new (ja,
     93                                         r));
     94 }
     95 
     96 
     97 /**
     98  * Manages a GET /private/transfers call.
     99  *
    100  * @param rh context of the handler
    101  * @param connection the MHD connection to handle
    102  * @param[in,out] hc context with further information about the request
    103  * @return MHD result code
    104  */
    105 enum MHD_Result
    106 TMH_private_get_transfers (const struct TMH_RequestHandler *rh,
    107                            struct MHD_Connection *connection,
    108                            struct TMH_HandlerContext *hc)
    109 {
    110   struct TALER_FullPayto payto_uri = {
    111     .full_payto = NULL
    112   };
    113   struct GNUNET_TIME_Timestamp before = GNUNET_TIME_UNIT_FOREVER_TS;
    114   struct GNUNET_TIME_Timestamp after = GNUNET_TIME_UNIT_ZERO_TS;
    115   int64_t limit = -20;
    116   uint64_t offset;
    117   enum TALER_EXCHANGE_YesNoAll expected;
    118 
    119   (void) rh;
    120   TALER_MHD_parse_request_snumber (connection,
    121                                    "limit",
    122                                    &limit);
    123   if (limit < 0)
    124     offset = INT64_MAX;
    125   else
    126     offset = 0;
    127   TALER_MHD_parse_request_number (connection,
    128                                   "offset",
    129                                   &offset);
    130   TALER_MHD_parse_request_yna (connection,
    131                                "expected",
    132                                TALER_EXCHANGE_YNA_ALL,
    133                                &expected);
    134   TALER_MHD_parse_request_timestamp (connection,
    135                                      "before",
    136                                      &before);
    137   TALER_MHD_parse_request_timestamp (connection,
    138                                      "after",
    139                                      &after);
    140   {
    141     const char *esc_payto;
    142 
    143     esc_payto = MHD_lookup_connection_value (connection,
    144                                              MHD_GET_ARGUMENT_KIND,
    145                                              "payto_uri");
    146     if (NULL != esc_payto)
    147     {
    148       payto_uri.full_payto
    149         = GNUNET_strdup (esc_payto);
    150       (void) MHD_http_unescape (payto_uri.full_payto);
    151     }
    152   }
    153   TALER_MERCHANTDB_preflight (TMH_db);
    154   {
    155     json_t *ja;
    156     enum GNUNET_DB_QueryStatus qs;
    157 
    158     ja = json_array ();
    159     GNUNET_assert (NULL != ja);
    160     qs = TALER_MERCHANTDB_lookup_transfers (TMH_db,
    161                                             hc->instance->settings.id,
    162                                             payto_uri,
    163                                             before,
    164                                             after,
    165                                             limit,
    166                                             offset,
    167                                             expected,
    168                                             &transfer_cb,
    169                                             ja);
    170     GNUNET_free (payto_uri.full_payto);
    171     if (0 > qs)
    172     {
    173       /* Simple select queries should not cause serialization issues */
    174       GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
    175       /* Always report on hard error as well to enable diagnostics */
    176       GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
    177       return TALER_MHD_reply_with_error (connection,
    178                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
    179                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
    180                                          "transfers");
    181     }
    182     return TALER_MHD_REPLY_JSON_PACK (
    183       connection,
    184       MHD_HTTP_OK,
    185       GNUNET_JSON_pack_array_steal ("transfers",
    186                                     ja));
    187   }
    188 }
    189 
    190 
    191 /* end of taler-merchant-httpd_track-transfer.c */