merchant

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

taler-merchant-httpd_helper.h (13207B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2021-2023 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 Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero 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_helper.h
     18  * @brief helpers for shared logic
     19  * @author Florian Dold
     20  * @author Benedikt Mueller
     21  * @author Christian Grothoff
     22  */
     23 #ifndef TALER_MERCHANT_HTTPD_HELPER_H
     24 #define TALER_MERCHANT_HTTPD_HELPER_H
     25 
     26 #define TMH_MAX_FRACTIONAL_PRECISION_LEVEL 6
     27 
     28 
     29 #include "taler-merchant-httpd.h"
     30 #include "taler/taler_merchant_util.h"
     31 
     32 
     33 /**
     34  * Serialize the public merchant metadata of an instance.
     35  *
     36  * @param mi merchant instance
     37  * @return newly allocated JSON object
     38  */
     39 json_t *
     40 TMH_instance_metadata_to_json (const struct TMH_MerchantInstance *mi);
     41 
     42 /**
     43  * check @a accounts for well-formedness
     44  *
     45  * @param accounts JSON array of merchant accounts (presumably)
     46  * @return true if they are all valid accounts
     47  */
     48 bool
     49 TMH_accounts_array_valid (const json_t *accounts);
     50 
     51 
     52 /**
     53  * Check if @a location is a valid Location object in the sense of Taler's API
     54  * definition.
     55  *
     56  * @param location object to check
     57  * @return true if @a location is an object
     58  *         representing a Location.
     59  */
     60 bool
     61 TMH_location_object_valid (const json_t *location);
     62 
     63 
     64 /**
     65  * Check if @a products is an array of valid Product(s) in the sense of
     66  * Taler's API definition.
     67  *
     68  * @param products array to check
     69  * @return true if @a products is an array and all
     70  *         entries are valid Products.
     71  */
     72 bool
     73 TMH_products_array_valid (const json_t *products);
     74 
     75 
     76 /**
     77  * Parse decimal quantity expressed as string for request handling.
     78  *
     79  * @param value string to parse
     80  * @param[out] integer_part result integer component
     81  * @param[out] fractional_part result fractional component (0..MERCHANT_UNIT_FRAC_BASE-1)
     82  * @return #GNUNET_OK on success, #GNUNET_SYSERR on validation failure
     83  */
     84 enum GNUNET_GenericReturnValue
     85 TMH_parse_fractional_string (const char *value,
     86                              int64_t *integer_part,
     87                              uint32_t *fractional_part);
     88 
     89 /**
     90  * Check that no two prices use the same currency.
     91  *
     92  * @param prices price list to check
     93  * @param prices_len length of @a prices
     94  * @return #GNUNET_OK if unique, #GNUNET_SYSERR otherwise
     95  */
     96 enum GNUNET_GenericReturnValue
     97 TMH_validate_unit_price_array (const struct TALER_Amount *prices,
     98                                size_t prices_len);
     99 
    100 
    101 /**
    102  * Compute the full value of an order from its contract terms.
    103  *
    104  * The total consists of the Taler amount of the selected choice plus all
    105  * entries in "amount_external".
    106  *
    107  * @param contract_terms contract terms of the order
    108  * @param choice_index selected choice, ignored for v0 contracts; for v1
    109  *        contracts it must be non-negative, as the total is undefined
    110  *        while no choice was selected
    111  * @param[out] total set to the full order total
    112  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the contract is
    113  *         malformed or no choice was selected for a v1 contract
    114  */
    115 enum GNUNET_GenericReturnValue
    116 TMH_compute_order_total (const json_t *contract_terms,
    117                          int16_t choice_index,
    118                          struct TALER_Amount *total);
    119 
    120 
    121 /**
    122  * Set of category IDs.
    123  */
    124 struct TMH_CategorySet
    125 {
    126   /**
    127    * Category IDs.
    128    */
    129   uint64_t *ids;
    130 
    131   /**
    132    * Number of entries in @e ids.
    133    */
    134   unsigned int len;
    135 };
    136 
    137 /**
    138  * Set of unit identifiers.
    139  */
    140 struct TMH_UnitSet
    141 {
    142   /**
    143    * Unit identifiers.
    144    */
    145   char **units;
    146 
    147   /**
    148    * Number of entries in @e units.
    149    */
    150   unsigned int len;
    151 };
    152 /**
    153  * Check if a category set already contains a given ID.
    154  *
    155  * @param set category set
    156  * @param id category id
    157  * @return true if present
    158  */
    159 bool
    160 TMH_category_set_contains (const struct TMH_CategorySet *set,
    161                            uint64_t id);
    162 
    163 /**
    164  * Add a category ID to a set if not already present.
    165  *
    166  * @param set category set
    167  * @param id category id
    168  */
    169 void
    170 TMH_category_set_add (struct TMH_CategorySet *set,
    171                       uint64_t id);
    172 
    173 /**
    174  * Check if a unit set already contains a given unit.
    175  *
    176  * @param set unit set
    177  * @param unit unit identifier
    178  * @return true if present
    179  */
    180 bool
    181 TMH_unit_set_contains (const struct TMH_UnitSet *set,
    182                        const char *unit);
    183 
    184 /**
    185  * Add a unit identifier to a set if not already present.
    186  *
    187  * @param set unit set
    188  * @param unit unit identifier
    189  */
    190 void
    191 TMH_unit_set_add (struct TMH_UnitSet *set,
    192                   const char *unit);
    193 
    194 /**
    195  * Clear a unit set and free its contents.
    196  *
    197  * @param set unit set to clear
    198  */
    199 void
    200 TMH_unit_set_clear (struct TMH_UnitSet *set);
    201 
    202 
    203 /**
    204  * Lookup the defaults for @a unit within @a mi and fall back to sane
    205  * values (disallow fractional quantities, zero precision) if no data
    206  * is available.
    207  *
    208  * @param mi merchant instance whose defaults should be consulted (must not be NULL)
    209  * @param unit textual unit name (must not be NULL or empty)
    210  * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL)
    211  * @param precision_level updated with the supported precision (must not be NULL)
    212  */
    213 void
    214 TMH_quantity_defaults_from_unit (const struct TMH_MerchantInstance *mi,
    215                                  const char *unit,
    216                                  bool *allow_fractional,
    217                                  uint32_t *precision_level);
    218 
    219 /**
    220  * Query the database for precision defaults tied to @a unit within
    221  * @a mi.  Returns #GNUNET_OK even if no unit information exists, in
    222  * which case the out-parameters remain at their implicit defaults.
    223  *
    224  * @param mi merchant instance whose unit table is inspected (must not be NULL)
    225  * @param unit textual unit name (must not be NULL or empty)
    226  * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL)
    227  * @param precision_level updated with the supported precision (must not be NULL)
    228  * @return #GNUNET_OK on success, #GNUNET_SYSERR on database failure
    229  */
    230 enum GNUNET_GenericReturnValue
    231 TMH_unit_defaults_for_instance (const struct TMH_MerchantInstance *mi,
    232                                 const char *unit,
    233                                 bool *allow_fractional,
    234                                 uint32_t *precision_level);
    235 
    236 
    237 /**
    238  * Setup new wire method for the given @ payto_uri.
    239  *
    240  * @param payto_uri already validated payto URI
    241  * @param credit_facade_url where to download credit information for this account (can be NULL)
    242  * @param credit_facade_credentials credentials for the @a credit_facade_url
    243  * @return new wire method object, never fails
    244  */
    245 struct TMH_WireMethod *
    246 TMH_setup_wire_account (
    247   struct TALER_FullPayto payto_uri,
    248   const char *credit_facade_url,
    249   const json_t *credit_facade_credentials);
    250 
    251 
    252 /**
    253  * Test if JSON spec @a account for a wire method is equal to the given @a wm.
    254  *
    255  * @param account JSON spec for a merchant account
    256  * @param wm known wire method
    257  * @return #GNUNET_YES if both specifications are equal
    258  *  #GNUNET_NO if the specifications are for
    259  *      the same account but differ in the credit facade
    260  *  #GNUNET_SYSERR if the specs are for different accounts
    261  *     or if @a account is malformed
    262  */
    263 enum GNUNET_GenericReturnValue
    264 TMH_cmp_wire_account (
    265   const json_t *account,
    266   const struct TMH_WireMethod *wm);
    267 
    268 
    269 /**
    270  * Check that the provided authentication configuration
    271  * is valid.
    272  *
    273  * @param connection connection to use for returning errors
    274  * @param jauth JSON with authentication data
    275  * @param[out] auth_token set to the authentication token
    276  * @return #GNUNET_OK on success,
    277  *   #GNUNET_NO if an error was returned on @a connection
    278  *   #GNUNET_SYSERR if we failed to return an error on @a connection
    279  */
    280 enum GNUNET_GenericReturnValue
    281 TMH_check_auth_config (struct MHD_Connection *connection,
    282                        const json_t *jauth,
    283                        const char **auth_token);
    284 
    285 
    286 /**
    287  * Generate binary UUID from client-provided UUID-string.
    288  *
    289  * @param uuids string intpu
    290  * @param[out] uuid set to binary UUID
    291  */
    292 void
    293 TMH_uuid_from_string (const char *uuids,
    294                       struct GNUNET_Uuid *uuid);
    295 
    296 
    297 /**
    298  * Initializes a buffer with
    299  * the ``http[s]://$HOST/[$PATH/][instances/$INSTANCE/]``
    300  * string using $HOST and $PATH from @a connection.
    301  *
    302  * @param[in] connection connection to base the construction on
    303  * @param instance instance to set, NULL for none
    304  * @param[out] buf buffer to initialize
    305  * @return #GNUNET_OK on success
    306  */
    307 enum GNUNET_GenericReturnValue
    308 TMH_base_url_by_connection (struct MHD_Connection *connection,
    309                             const char *instance,
    310                             struct GNUNET_Buffer *buf);
    311 
    312 
    313 /**
    314  * Initializes a buffer with
    315  * the ``taler[+http]://$METHOD/$HOST/[instances/$INSTANCE/]``
    316  * string using $HOST from @a connection.
    317  *
    318  * @param[in] connection connection to base the construction on
    319  * @param method taler-URI method to inject
    320  * @param instance instance to set, NULL for none
    321  * @param[out] buf buffer to initialize
    322  * @return #GNUNET_OK on success
    323  */
    324 enum GNUNET_GenericReturnValue
    325 TMH_taler_uri_by_connection (struct MHD_Connection *connection,
    326                              const char *method,
    327                              const char *instance,
    328                              struct GNUNET_Buffer *buf);
    329 
    330 
    331 /**
    332  * Create a taler://pay/ URI for the given @a con and @a order_id
    333  * and @a session_id and @a instance_id.
    334  *
    335  * @param con HTTP connection
    336  * @param order_id the order id
    337  * @param session_id session, may be NULL
    338  * @param instance_id instance, may be "default"
    339  * @param claim_token claim token for the order, may be NULL
    340  * @return corresponding taler://pay/ URI, or NULL on missing "host"
    341  */
    342 char *
    343 TMH_make_taler_pay_uri (struct MHD_Connection *con,
    344                         const char *order_id,
    345                         const char *session_id,
    346                         const char *instance_id,
    347                         struct TALER_ClaimTokenP *claim_token);
    348 
    349 /**
    350  * Create a http(s) URL for the given @a con and @a order_id
    351  * and @a instance_id to display the /orders/{order_id} page.
    352  *
    353  * @param con HTTP connection
    354  * @param order_id the order id
    355  * @param session_id session, may be NULL
    356  * @param instance_id instance, may be "default"
    357  * @param claim_token claim token for the order, may be NULL
    358  * @param h_contract contract hash for authentication, may be NULL
    359  * @return corresponding http(s):// URL, or NULL on missing "host"
    360  */
    361 char *
    362 TMH_make_order_status_url (struct MHD_Connection *con,
    363                            const char *order_id,
    364                            const char *session_id,
    365                            const char *instance_id,
    366                            struct TALER_ClaimTokenP *claim_token,
    367                            struct TALER_PrivateContractHashP *h_contract);
    368 
    369 
    370 /**
    371  * Put data from an exchange's HTTP response into
    372  * a JSON reply
    373  *
    374  * @param hr a `TALER_EXCHANGE_HttpResponse`
    375  */
    376 #define TMH_pack_exchange_reply(hr) \
    377   GNUNET_JSON_pack_uint64 ("exchange_code", (hr)->ec),                \
    378   GNUNET_JSON_pack_uint64 ("exchange_http_status", (hr)->http_status), \
    379   GNUNET_JSON_pack_uint64 ("exchange_ec", (hr)->ec),       /* LEGACY */  \
    380   GNUNET_JSON_pack_uint64 ("exchange_hc", (hr)->http_status),       /* LEGACY */ \
    381   GNUNET_JSON_pack_allow_null ( \
    382     GNUNET_JSON_pack_object_incref ("exchange_reply", (json_t *) (hr)-> \
    383                                     reply))
    384 
    385 
    386 /**
    387  * TMH_trigger_webhook is a function that need to be use when someone
    388  * pay. Merchant need to have a notification.
    389  *
    390  * @param instance that we need to send the webhook as a notification
    391  * @param event of the webhook
    392  * @param args argument of the function
    393  */
    394 enum GNUNET_DB_QueryStatus
    395 TMH_trigger_webhook (const char *instance,
    396                      const char *action,
    397                      const json_t *args);
    398 
    399 
    400 /**
    401  * Return JSON array with all of the exchange accounts
    402  * that support the given @a wire_method.
    403  *
    404  * @param master_pub master public key to match exchange by
    405  * @param wire_method NULL for any
    406  * @return JSON array with information about all matching accounts
    407  */
    408 json_t *
    409 TMH_exchange_accounts_by_method (
    410   const struct TALER_MasterPublicKeyP *master_pub,
    411   const char *wire_method);
    412 
    413 /**
    414  * Check validity of login @a token for the given @a instance_id.
    415  *
    416  * @param token the login token given in the request
    417  * @param instance_id the instance the login is to be checked against
    418  * @param[out] as set to scope of the token if it is valid
    419  * @return TALER_EC_NONE on success
    420  */
    421 enum TALER_ErrorCode
    422 TMH_check_token (const char *token,
    423                  const char *instance_id,
    424                  enum TMH_AuthScope *as);
    425 
    426 #endif