merchant

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

taler-merchant-httpd_helper.h (14755B)


      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  * Compute the total transfer amount the merchant expects to have received
    123  * for an order, taking into account refunds and the merchant's maximum
    124  * deposit fee.
    125  *
    126  * The merchant only ever pays up to @a max_fee when one was specified;
    127  * the customer covers any excess deposit fees.
    128  *
    129  * @param contract_amount order amount
    130  * @param refund_amount total refunds (must not exceed @a contract_amount)
    131  * @param deposit_fees_total sum of all deposit fees
    132  * @param deposit_fees_refunded_total sum of refunded deposit fees
    133  * @param max_fee maximum deposit fee the merchant pays (may be NULL)
    134  * @param has_max_fee true if @a max_fee is valid
    135  * @param[out] expected_total set to the expected transfer amount
    136  * @return #GNUNET_OK on success,
    137  *         #GNUNET_SYSERR if refunds exceed the contract value or if refunded
    138  *         deposit fees exceed total deposit fees,
    139  *         #GNUNET_NO if the merchant's share of deposit fees exceeds the
    140  *         amount minus refunds.
    141  */
    142 enum GNUNET_GenericReturnValue
    143 TMH_compute_expected_transfer (const struct TALER_Amount *contract_amount,
    144                                const struct TALER_Amount *refund_amount,
    145                                const struct TALER_Amount *deposit_fees_total,
    146                                const struct TALER_Amount *deposit_fees_refunded_total,
    147                                const struct TALER_Amount *max_fee,
    148                                bool has_max_fee,
    149                                struct TALER_Amount *expected_total);
    150 
    151 
    152 /**
    153  * Set of category IDs.
    154  */
    155 struct TMH_CategorySet
    156 {
    157   /**
    158    * Category IDs.
    159    */
    160   uint64_t *ids;
    161 
    162   /**
    163    * Number of entries in @e ids.
    164    */
    165   unsigned int len;
    166 };
    167 
    168 /**
    169  * Set of unit identifiers.
    170  */
    171 struct TMH_UnitSet
    172 {
    173   /**
    174    * Unit identifiers.
    175    */
    176   char **units;
    177 
    178   /**
    179    * Number of entries in @e units.
    180    */
    181   unsigned int len;
    182 };
    183 /**
    184  * Check if a category set already contains a given ID.
    185  *
    186  * @param set category set
    187  * @param id category id
    188  * @return true if present
    189  */
    190 bool
    191 TMH_category_set_contains (const struct TMH_CategorySet *set,
    192                            uint64_t id);
    193 
    194 /**
    195  * Add a category ID to a set if not already present.
    196  *
    197  * @param set category set
    198  * @param id category id
    199  */
    200 void
    201 TMH_category_set_add (struct TMH_CategorySet *set,
    202                       uint64_t id);
    203 
    204 /**
    205  * Check if a unit set already contains a given unit.
    206  *
    207  * @param set unit set
    208  * @param unit unit identifier
    209  * @return true if present
    210  */
    211 bool
    212 TMH_unit_set_contains (const struct TMH_UnitSet *set,
    213                        const char *unit);
    214 
    215 /**
    216  * Add a unit identifier to a set if not already present.
    217  *
    218  * @param set unit set
    219  * @param unit unit identifier
    220  */
    221 void
    222 TMH_unit_set_add (struct TMH_UnitSet *set,
    223                   const char *unit);
    224 
    225 /**
    226  * Clear a unit set and free its contents.
    227  *
    228  * @param set unit set to clear
    229  */
    230 void
    231 TMH_unit_set_clear (struct TMH_UnitSet *set);
    232 
    233 
    234 /**
    235  * Lookup the defaults for @a unit within @a mi and fall back to sane
    236  * values (disallow fractional quantities, zero precision) if no data
    237  * is available.
    238  *
    239  * @param mi merchant instance whose defaults should be consulted (must not be NULL)
    240  * @param unit textual unit name (must not be NULL or empty)
    241  * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL)
    242  * @param precision_level updated with the supported precision (must not be NULL)
    243  */
    244 void
    245 TMH_quantity_defaults_from_unit (const struct TMH_MerchantInstance *mi,
    246                                  const char *unit,
    247                                  bool *allow_fractional,
    248                                  uint32_t *precision_level);
    249 
    250 /**
    251  * Query the database for precision defaults tied to @a unit within
    252  * @a mi.  Returns #GNUNET_OK even if no unit information exists, in
    253  * which case the out-parameters remain at their implicit defaults.
    254  *
    255  * @param mi merchant instance whose unit table is inspected (must not be NULL)
    256  * @param unit textual unit name (must not be NULL or empty)
    257  * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL)
    258  * @param precision_level updated with the supported precision (must not be NULL)
    259  * @return #GNUNET_OK on success, #GNUNET_SYSERR on database failure
    260  */
    261 enum GNUNET_GenericReturnValue
    262 TMH_unit_defaults_for_instance (const struct TMH_MerchantInstance *mi,
    263                                 const char *unit,
    264                                 bool *allow_fractional,
    265                                 uint32_t *precision_level);
    266 
    267 
    268 /**
    269  * Setup new wire method for the given @ payto_uri.
    270  *
    271  * @param payto_uri already validated payto URI
    272  * @param credit_facade_url where to download credit information for this account (can be NULL)
    273  * @param credit_facade_credentials credentials for the @a credit_facade_url
    274  * @return new wire method object, never fails
    275  */
    276 struct TMH_WireMethod *
    277 TMH_setup_wire_account (
    278   struct TALER_FullPayto payto_uri,
    279   const char *credit_facade_url,
    280   const json_t *credit_facade_credentials);
    281 
    282 
    283 /**
    284  * Test if JSON spec @a account for a wire method is equal to the given @a wm.
    285  *
    286  * @param account JSON spec for a merchant account
    287  * @param wm known wire method
    288  * @return #GNUNET_YES if both specifications are equal
    289  *  #GNUNET_NO if the specifications are for
    290  *      the same account but differ in the credit facade
    291  *  #GNUNET_SYSERR if the specs are for different accounts
    292  *     or if @a account is malformed
    293  */
    294 enum GNUNET_GenericReturnValue
    295 TMH_cmp_wire_account (
    296   const json_t *account,
    297   const struct TMH_WireMethod *wm);
    298 
    299 
    300 /**
    301  * Check that the provided authentication configuration
    302  * is valid.
    303  *
    304  * @param connection connection to use for returning errors
    305  * @param jauth JSON with authentication data
    306  * @param[out] auth_token set to the authentication token
    307  * @return #GNUNET_OK on success,
    308  *   #GNUNET_NO if an error was returned on @a connection
    309  *   #GNUNET_SYSERR if we failed to return an error on @a connection
    310  */
    311 enum GNUNET_GenericReturnValue
    312 TMH_check_auth_config (struct MHD_Connection *connection,
    313                        const json_t *jauth,
    314                        const char **auth_token);
    315 
    316 
    317 /**
    318  * Generate binary UUID from client-provided UUID-string.
    319  *
    320  * @param uuids string intpu
    321  * @param[out] uuid set to binary UUID
    322  */
    323 void
    324 TMH_uuid_from_string (const char *uuids,
    325                       struct GNUNET_Uuid *uuid);
    326 
    327 
    328 /**
    329  * Initializes a buffer with
    330  * the ``http[s]://$HOST/[$PATH/][instances/$INSTANCE/]``
    331  * string using $HOST and $PATH from @a connection.
    332  *
    333  * @param[in] connection connection to base the construction on
    334  * @param instance instance to set, NULL for none
    335  * @param[out] buf buffer to initialize
    336  * @return #GNUNET_OK on success
    337  */
    338 enum GNUNET_GenericReturnValue
    339 TMH_base_url_by_connection (struct MHD_Connection *connection,
    340                             const char *instance,
    341                             struct GNUNET_Buffer *buf);
    342 
    343 
    344 /**
    345  * Initializes a buffer with
    346  * the ``taler[+http]://$METHOD/$HOST/[instances/$INSTANCE/]``
    347  * string using $HOST from @a connection.
    348  *
    349  * @param[in] connection connection to base the construction on
    350  * @param method taler-URI method to inject
    351  * @param instance instance to set, NULL for none
    352  * @param[out] buf buffer to initialize
    353  * @return #GNUNET_OK on success
    354  */
    355 enum GNUNET_GenericReturnValue
    356 TMH_taler_uri_by_connection (struct MHD_Connection *connection,
    357                              const char *method,
    358                              const char *instance,
    359                              struct GNUNET_Buffer *buf);
    360 
    361 
    362 /**
    363  * Create a taler://pay/ URI for the given @a con and @a order_id
    364  * and @a session_id and @a instance_id.
    365  *
    366  * @param con HTTP connection
    367  * @param order_id the order id
    368  * @param session_id session, may be NULL
    369  * @param instance_id instance, may be "default"
    370  * @param claim_token claim token for the order, may be NULL
    371  * @return corresponding taler://pay/ URI, or NULL on missing "host"
    372  */
    373 char *
    374 TMH_make_taler_pay_uri (struct MHD_Connection *con,
    375                         const char *order_id,
    376                         const char *session_id,
    377                         const char *instance_id,
    378                         struct TALER_ClaimTokenP *claim_token);
    379 
    380 /**
    381  * Create a http(s) URL for the given @a con and @a order_id
    382  * and @a instance_id to display the /orders/{order_id} page.
    383  *
    384  * @param con HTTP connection
    385  * @param order_id the order id
    386  * @param session_id session, may be NULL
    387  * @param instance_id instance, may be "default"
    388  * @param claim_token claim token for the order, may be NULL
    389  * @param h_contract contract hash for authentication, may be NULL
    390  * @return corresponding http(s):// URL, or NULL on missing "host"
    391  */
    392 char *
    393 TMH_make_order_status_url (struct MHD_Connection *con,
    394                            const char *order_id,
    395                            const char *session_id,
    396                            const char *instance_id,
    397                            struct TALER_ClaimTokenP *claim_token,
    398                            struct TALER_PrivateContractHashP *h_contract);
    399 
    400 
    401 /**
    402  * Put data from an exchange's HTTP response into
    403  * a JSON reply
    404  *
    405  * @param hr a `TALER_EXCHANGE_HttpResponse`
    406  */
    407 #define TMH_pack_exchange_reply(hr) \
    408         GNUNET_JSON_pack_uint64 ("exchange_code", (hr)->ec),                \
    409         GNUNET_JSON_pack_uint64 ("exchange_http_status", (hr)->http_status), \
    410         GNUNET_JSON_pack_uint64 ("exchange_ec", (hr)->ec), /* LEGACY */  \
    411         GNUNET_JSON_pack_uint64 ("exchange_hc", (hr)->http_status), /* LEGACY */ \
    412         GNUNET_JSON_pack_allow_null ( \
    413           GNUNET_JSON_pack_object_incref ("exchange_reply", (json_t *) (hr)-> \
    414                                           reply))
    415 
    416 
    417 /**
    418  * TMH_trigger_webhook is a function that need to be use when someone
    419  * pay. Merchant need to have a notification.
    420  *
    421  * @param instance that we need to send the webhook as a notification
    422  * @param event of the webhook
    423  * @param args argument of the function
    424  */
    425 enum GNUNET_DB_QueryStatus
    426 TMH_trigger_webhook (const char *instance,
    427                      const char *action,
    428                      const json_t *args);
    429 
    430 
    431 /**
    432  * Return JSON array with all of the exchange accounts
    433  * that support the given @a wire_method.
    434  *
    435  * @param master_pub master public key to match exchange by
    436  * @param wire_method NULL for any
    437  * @return JSON array with information about all matching accounts
    438  */
    439 json_t *
    440 TMH_exchange_accounts_by_method (
    441   const struct TALER_MasterPublicKeyP *master_pub,
    442   const char *wire_method);
    443 
    444 /**
    445  * Check validity of login @a token for the given @a instance_id.
    446  *
    447  * @param token the login token given in the request
    448  * @param instance_id the instance the login is to be checked against
    449  * @param[out] as set to scope of the token if it is valid
    450  * @return TALER_EC_NONE on success
    451  */
    452 enum TALER_ErrorCode
    453 TMH_check_token (const char *token,
    454                  const char *instance_id,
    455                  enum TMH_AuthScope *as);
    456 
    457 #endif