merchant

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

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


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