merchant

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

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


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