merchant

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

contract_serialize.c (5945B)


      1 /*
      2   This file is part of GNU Taler
      3   Copyright (C) 2024, 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 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/util/contract_serialize.c
     18  * @brief shared logic for contract terms serialization
     19  * @author Iván Ávalos
     20  * @author Christian Grothoff
     21  */
     22 #include "platform.h"
     23 #include <gnunet/gnunet_json_lib.h>
     24 #include <gnunet/gnunet_common.h>
     25 #include <taler/taler_json_lib.h>
     26 #include <jansson.h>
     27 #include "taler/taler_util.h"
     28 #include "taler/taler_merchant_util.h"
     29 
     30 
     31 /**
     32  * Get JSON object with contract terms v0-specific fields.
     33  *
     34  * @param[in] input contract terms v0
     35  * @return JSON object with @a input v0 fields; NULL on error
     36  */
     37 static json_t *
     38 json_from_contract_v0 (
     39   const struct TALER_MERCHANT_ProtoContract *input)
     40 {
     41   return GNUNET_JSON_PACK (
     42     TALER_JSON_pack_amount ("amount",
     43                             &input->details.v0.brutto),
     44     GNUNET_JSON_pack_allow_null (
     45       TALER_JSON_pack_amount ("tip",
     46                               input->details.v0.no_tip
     47                               ? NULL
     48                               : &input->details.v0.tip)),
     49     TALER_JSON_pack_amount ("max_fee",
     50                             &input->details.v0.max_fee));
     51 }
     52 
     53 
     54 /**
     55  * Get JSON object with contract terms v1-specific fields.
     56  *
     57  * @param[in] input contract terms v1
     58  * @return JSON object with @a input v1 fields; NULL on error
     59  */
     60 static json_t *
     61 json_from_contract_v1 (
     62   const struct TALER_MERCHANT_ProtoContract *input)
     63 {
     64   json_t *choices;
     65   json_t *families;
     66 
     67   choices = json_array ();
     68   GNUNET_assert (0 != choices);
     69   for (unsigned i = 0; i < input->details.v1.choices_len; i++)
     70     GNUNET_assert (0 == json_array_append_new (
     71                      choices,
     72                      TALER_MERCHANT_json_from_contract_choice (
     73                        &input->details.v1.choices[i])));
     74 
     75   families = json_object ();
     76   GNUNET_assert (0 != families);
     77   for (unsigned i = 0; i < input->details.v1.token_authorities_len; i++)
     78     GNUNET_assert (0 == json_object_set_new (
     79                      families,
     80                      input->details.v1.token_authorities[i].slug,
     81                      TALER_MERCHANT_json_from_token_family (
     82                        &input->details.v1.token_authorities[i])));
     83 
     84   return GNUNET_JSON_PACK (
     85     GNUNET_JSON_pack_array_steal ("choices",
     86                                   choices),
     87     GNUNET_JSON_pack_object_steal ("token_families",
     88                                    families));
     89 }
     90 
     91 
     92 /**
     93  * Serialize proto contract into JSON object.
     94  *
     95  * @param[in] pc proto contract to serialize
     96  * @return JSON representation of @a pc; NULL on error
     97  */
     98 json_t *
     99 TALER_MERCHANT_proto_contract_serialize (
    100   const struct TALER_MERCHANT_ProtoContract *pc)
    101 {
    102   json_t *bj;
    103   json_t *details;
    104   json_t *products;
    105 
    106   bj = TALER_MERCHANT_base_terms_serialize (pc->base);
    107   switch (pc->base->version)
    108   {
    109   case TALER_MERCHANT_CONTRACT_VERSION_0:
    110     details = json_from_contract_v0 (pc);
    111     goto success;
    112   case TALER_MERCHANT_CONTRACT_VERSION_1:
    113     details = json_from_contract_v1 (pc);
    114     goto success;
    115   }
    116 
    117   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    118               "unknown contract type version %d",
    119               pc->base->version);
    120   GNUNET_assert (0);
    121   return NULL;
    122 
    123 success:
    124   products = json_array ();
    125   GNUNET_assert (NULL != products);
    126   for (size_t i = 0; i<pc->products_len; i++)
    127   {
    128     GNUNET_assert (
    129       0 ==
    130       json_array_append_new (products,
    131                              TALER_MERCHANT_product_sold_serialize (
    132                                &pc->products[i])));
    133   }
    134 
    135   return GNUNET_JSON_PACK (
    136     GNUNET_JSON_pack_string ("order_id",
    137                              pc->order_id),
    138     GNUNET_JSON_pack_object_steal (NULL,
    139                                    bj),
    140     GNUNET_JSON_pack_timestamp ("timestamp",
    141                                 pc->timestamp),
    142     GNUNET_JSON_pack_timestamp ("refund_deadline",
    143                                 pc->refund_deadline),
    144     GNUNET_JSON_pack_timestamp ("pay_deadline",
    145                                 pc->pay_deadline),
    146     GNUNET_JSON_pack_timestamp ("wire_transfer_deadline",
    147                                 pc->wire_deadline),
    148     GNUNET_JSON_pack_data_auto ("merchant_pub",
    149                                 &pc->merchant_pub.eddsa_pub),
    150     GNUNET_JSON_pack_string ("merchant_base_url",
    151                              pc->merchant_base_url),
    152     GNUNET_JSON_pack_object_steal (
    153       "merchant",
    154       TALER_MERCHANT_metadata_to_json (
    155         &pc->merchant)),
    156     GNUNET_JSON_pack_array_steal ("products",
    157                                   products),
    158     GNUNET_JSON_pack_data_auto ("h_wire",
    159                                 &pc->h_wire),
    160     GNUNET_JSON_pack_string ("wire_method",
    161                              pc->wire_method),
    162     GNUNET_JSON_pack_array_incref ("exchanges",
    163                                    pc->exchanges),
    164     GNUNET_JSON_pack_object_steal (NULL,
    165                                    details));
    166 }
    167 
    168 
    169 json_t *
    170 TALER_MERCHANT_contract_serialize (
    171   const struct TALER_MERCHANT_Contract *input)
    172 {
    173   json_t *pj;
    174 
    175   pj = TALER_MERCHANT_proto_contract_serialize (input->pc);
    176   if (NULL == pj)
    177   {
    178     GNUNET_break (0);
    179     return NULL;
    180   }
    181   return GNUNET_JSON_PACK (
    182     GNUNET_JSON_pack_string ("nonce",
    183                              input->nonce),
    184     GNUNET_JSON_pack_object_steal (NULL,
    185                                    pj));
    186 }