merchant

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

merchantdb_lib.h (19256B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014, 2015, 2016, 2020 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Lesser 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.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 
     17 /**
     18  * @file src/include/merchantdb_lib.h
     19  * @brief database helper functions used by the merchant backend
     20  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
     21  */
     22 #ifndef TALER_MERCHANTDB_LIB_H
     23 #define TALER_MERCHANTDB_LIB_H
     24 
     25 #include <gnunet/gnunet_pq_lib.h>
     26 #include <taler/taler_util.h>
     27 
     28 /**
     29  * Handle to interact with the database.
     30  */
     31 struct TALER_MERCHANTDB_PostgresContext;
     32 
     33 GNUNET_NETWORK_STRUCT_BEGIN
     34 
     35 /**
     36  * Format of the data hashed to generate the notification
     37  * string whenever the KYC status for an account has
     38  * changed.
     39  */
     40 struct TALER_MERCHANTDB_MerchantKycStatusChangeEventP
     41 {
     42   /**
     43    * Type is TALER_DBEVENT_MERCHANT_EXCHANGE_KYC_STATUS_CHANGED.
     44    */
     45   struct GNUNET_DB_EventHeaderP header;
     46 
     47   /**
     48    * Salted hash of the affected account.
     49    */
     50   struct TALER_MerchantWireHashP h_wire;
     51 };
     52 
     53 /**
     54  * Event triggered when an order is paid.
     55  */
     56 struct TMH_OrderPayEventP
     57 {
     58   /**
     59    * Type is #TALER_DBEVENT_MERCHANT_ORDER_PAID
     60    */
     61   struct GNUNET_DB_EventHeaderP header;
     62 
     63   /**
     64    * Always zero (for alignment).
     65    */
     66   uint32_t reserved GNUNET_PACKED;
     67 
     68   /**
     69    * Merchant's public key
     70    */
     71   struct TALER_MerchantPublicKeyP merchant_pub;
     72 
     73   /**
     74    * Hash of the order ID.
     75    */
     76   struct GNUNET_HashCode h_order_id;
     77 };
     78 
     79 
     80 GNUNET_NETWORK_STRUCT_END
     81 
     82 
     83 /**
     84  * Connect to postgresql database
     85  *
     86  * @param cfg the configuration handle
     87  * @return connection to the database; NULL upon error
     88  */
     89 struct TALER_MERCHANTDB_PostgresContext *
     90 TALER_MERCHANTDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
     91 
     92 
     93 /**
     94  * Disconnect from the database
     95  *
     96  * @param pg database handle to close
     97  */
     98 void
     99 TALER_MERCHANTDB_disconnect (struct TALER_MERCHANTDB_PostgresContext *pg);
    100 
    101 
    102 void
    103 check_connection (struct TALER_MERCHANTDB_PostgresContext *pg);
    104 
    105 
    106 /**
    107  * Possible token family kinds.
    108  */
    109 enum TALER_MERCHANTDB_TokenFamilyKind
    110 {
    111 
    112   /**
    113    * Token family representing a discount token
    114    */
    115   TALER_MERCHANTDB_TFK_Discount = 0,
    116 
    117   /**
    118    * Token family representing a subscription token
    119    */
    120   TALER_MERCHANTDB_TFK_Subscription = 1,
    121 
    122 };
    123 
    124 /**
    125  * Results from trying to increase a refund.
    126  */
    127 enum TALER_MERCHANTDB_RefundStatus
    128 {
    129 
    130   /**
    131    * Refund amount exceeds legal exchange limits.
    132    */
    133   TALER_MERCHANTDB_RS_LEGAL_FAILURE = -5,
    134 
    135   /**
    136    * Refund amount currency does not match original payment.
    137    */
    138   TALER_MERCHANTDB_RS_BAD_CURRENCY = -4,
    139 
    140   /**
    141    * Refund amount exceeds original payment.
    142    */
    143   TALER_MERCHANTDB_RS_TOO_HIGH = -3,
    144 
    145   /**
    146    * Hard database failure.
    147    */
    148   TALER_MERCHANTDB_RS_HARD_ERROR = -2,
    149 
    150   /**
    151    * Soft database failure.
    152    */
    153   TALER_MERCHANTDB_RS_SOFT_ERROR = -1,
    154 
    155   /**
    156    * Order not found.
    157    */
    158   TALER_MERCHANTDB_RS_NO_SUCH_ORDER = 0,
    159 
    160   /**
    161    * Refund is now at or above the requested amount.
    162    */
    163   TALER_MERCHANTDB_RS_SUCCESS = 1
    164 
    165 };
    166 
    167 /**
    168  * Details about an OTP device.
    169  */
    170 struct TALER_MERCHANTDB_OtpDeviceDetails
    171 {
    172 
    173   /**
    174    * Description of the device.
    175    */
    176   char *otp_description;
    177 
    178   /**
    179    * Current usage counter value.
    180    */
    181   uint64_t otp_ctr;
    182 
    183   /**
    184    * Base64-encoded key.
    185    */
    186   char *otp_key;
    187 
    188   /**
    189    * Algorithm used to compute purchase confirmations.
    190    */
    191   enum TALER_MerchantConfirmationAlgorithm otp_algorithm;
    192 };
    193 
    194 
    195 /**
    196  * Details about a template.
    197  */
    198 struct TALER_MERCHANTDB_TemplateDetails
    199 {
    200   /**
    201    * Description of the template.
    202    */
    203   char *template_description;
    204 
    205   /**
    206    * In this template contract, we can have additional information.
    207    */
    208   json_t *template_contract;
    209 
    210   /**
    211    * ID of the OTP device linked to the template, or NULL.
    212    */
    213   char *otp_id;
    214 
    215   /**
    216    * Editable default values for fields not specified
    217    * in the @e template_contract. NULL if the user
    218    * cannot edit anything.
    219    */
    220   json_t *editable_defaults;
    221 
    222 };
    223 
    224 
    225 /**
    226  * Structure to hold Donau instance details from the database.
    227  */
    228 struct TALER_MERCHANTDB_DonauInstance
    229 {
    230   /**
    231    * Donau instance serial
    232    */
    233   uint64_t donau_instance_serial;
    234 
    235   /**
    236    * The URL for the Donau instance.
    237    */
    238   char *donau_url;
    239 
    240   /**
    241    * The name of the charity associated with the Donau instance.
    242    */
    243   char *charity_name;
    244 
    245   /**
    246    * Pointer to the public key of the charity, used for cryptographic operations.
    247    * This is represented as an EDDSA public key structure.
    248    */
    249   struct DONAU_CharityPublicKeyP *charity_pub_key;
    250 
    251   /**
    252    * A unique identifier for the charity in the Donau instance.
    253    */
    254   uint64_t charity_id;
    255 
    256   /**
    257    * The maximum allowable amount for donations to this charity in the current year.
    258    * This is tracked for regulatory or internal business constraints.
    259    */
    260   struct TALER_Amount charity_max_per_year;
    261 
    262   /**
    263    * The total amount of donations received by the charity in the current year.
    264    * This field helps track progress toward the yearly donation limit.
    265    */
    266   struct TALER_Amount charity_receipts_to_date;
    267 
    268   /**
    269    * The current year being tracked for donations.
    270    * This is used to differentiate donation data between years.
    271    */
    272   int64_t current_year;
    273 
    274   /**
    275    * A JSON object containing key information specific to the Donau instance,
    276    * such as cryptographic keys or other relevant details.
    277    */
    278   json_t *donau_keys_json;
    279 };
    280 
    281 
    282 /**
    283  * Details about a product.
    284  *
    285  * FIXME: reuse TALER_MERCHANT_Product as a member in this structure!
    286  */
    287 struct TALER_MERCHANTDB_ProductDetails
    288 {
    289   /**
    290    * Name of the product.
    291    */
    292   char *product_name;
    293 
    294   /**
    295    * Description of the product.
    296    */
    297   char *description;
    298 
    299   /**
    300    * Internationalized description.
    301    */
    302   json_t *description_i18n;
    303 
    304   /**
    305    * Unit in which the product is sold.
    306    */
    307   char *unit;
    308 
    309   /**
    310    * Optional list of per-unit prices. When NULL or empty, @e price
    311    * must be used as the canonical single price.
    312    */
    313   struct TALER_Amount *price_array;
    314 
    315   /**
    316    * Number of entries in @e price_array.
    317    */
    318   size_t price_array_length;
    319 
    320   /**
    321    * Base64-encoded product image, or an empty string.
    322    */
    323   char *image;
    324 
    325   /**
    326    * Hash of the product image data, or NULL.
    327    */
    328   char *image_hash;
    329 
    330   /**
    331    * List of taxes the merchant pays for this product. Never NULL,
    332    * but can be an empty array.
    333    */
    334   json_t *taxes;
    335 
    336   /**
    337    * Number of units of the product in stock in sum in total, including all
    338    * existing sales and lost product, in product-specific units. UINT64_MAX
    339    * indicates "infinite".
    340    */
    341   uint64_t total_stock;
    342 
    343   /**
    344    * Fractional part of stock in units of 1/1000000 of the base value.
    345    */
    346   uint32_t total_stock_frac;
    347 
    348   /**
    349    * Honor fractional stock if TRUE, else only integer stock.
    350    */
    351   bool allow_fractional_quantity;
    352 
    353   /**
    354    * Precision level (number of decimal places) to apply when
    355    * fractional quantities are enabled.
    356    */
    357   uint32_t fractional_precision_level;
    358 
    359   /**
    360    * Number of units of the product in sold, in product-specific units.
    361    */
    362   uint64_t total_sold;
    363 
    364   /**
    365    * Fractional part of units sold in units of 1/1000000 of the base value.
    366    */
    367   uint32_t total_sold_frac;
    368 
    369   /**
    370    * Number of units of stock lost.
    371    */
    372   uint64_t total_lost;
    373 
    374   /**
    375    * Fractional part of lost units in units of 1/1000000 of the base value.
    376    */
    377   uint32_t total_lost_frac;
    378 
    379   /**
    380    * Number of units currently reserved by locks (shopping cart locks and
    381    * locks held by unpaid orders).  These units are unavailable for new
    382    * orders.  Maintained by the database, not set by the application.
    383    */
    384   uint64_t total_locked;
    385 
    386   /**
    387    * Fractional part of locked units in units of 1/1000000 of the base value.
    388    */
    389   uint32_t total_locked_frac;
    390 
    391   /**
    392    * Identifies where the product is in stock, possibly an empty map.
    393    */
    394   json_t *address;
    395 
    396   /**
    397    * Identifies when the product will be restocked. 0 for unknown,
    398    * #GNUNET_TIME_UNIT_FOREVER_ABS for never.
    399    */
    400   struct GNUNET_TIME_Timestamp next_restock;
    401 
    402   /**
    403    * Minimum required age for consumers buying this product.
    404    * Default is 0. Only enforced of an exchange supports age
    405    * restrictions.
    406    */
    407   uint32_t minimum_age;
    408 
    409   /**
    410    * Group in which the product is in. 0 for default group.
    411    */
    412   uint64_t product_group_id;
    413 
    414   /**
    415    * Money pot into which sales of this product should go into by default.
    416    */
    417   uint64_t money_pot_id;
    418 
    419   /**
    420    * True if the price for this product is given in net,
    421    * False if its the gross price.
    422    */
    423   bool price_is_net;
    424 
    425 };
    426 
    427 
    428 /**
    429  * Details about a webhook.
    430  */
    431 struct TALER_MERCHANTDB_WebhookDetails
    432 {
    433 
    434   /**
    435    * event of the webhook.
    436    */
    437   char *event_type;
    438 
    439   /**
    440    * URL of the webhook. The customer will be redirected on this url.
    441    */
    442   char *url;
    443 
    444   /**
    445    * Http method used by the webhook.
    446    */
    447   char *http_method;
    448 
    449   /**
    450    * Header template of the webhook.
    451    */
    452   char *header_template;
    453 
    454   /**
    455    * Body template of the webhook.
    456    */
    457   char *body_template;
    458 
    459 };
    460 
    461 
    462 /**
    463  * Details about a product category.
    464  */
    465 struct TALER_MERCHANTDB_CategoryDetails
    466 {
    467 
    468   /**
    469    * Name of the category.
    470    */
    471   char *category_name;
    472 
    473   /**
    474    * Translations of the name of the category.
    475    */
    476   json_t *category_name_i18n;
    477 
    478 };
    479 
    480 
    481 /**
    482  * Details about the pending webhook.
    483  */
    484 struct TALER_MERCHANTDB_PendingWebhookDetails
    485 {
    486 
    487   /**
    488    * Identifies when we should make the next request to the webhook. 0 for unknown,
    489    * #GNUNET_TIME_UNIT_FOREVER_ABS for never.
    490    */
    491   struct GNUNET_TIME_Absolute next_attempt;
    492 
    493   /**
    494    * How often have we tried this request so far.
    495    */
    496   uint32_t retries;
    497 
    498   /**
    499    * URL of the webhook. The customer will be redirected on this url.
    500    */
    501   char *url;
    502 
    503   /**
    504    * Http method used for the webhook.
    505    */
    506   char *http_method;
    507 
    508   /**
    509    * Header of the webhook.
    510    */
    511   char *header;
    512 
    513   /**
    514    * Body of the webhook.
    515    */
    516   char *body;
    517 
    518 };
    519 
    520 
    521 /**
    522  * Details about a token family.
    523  */
    524 struct TALER_MERCHANTDB_TokenFamilyDetails
    525 {
    526   /**
    527    * Token family slug used for identification.
    528    */
    529   char *slug;
    530 
    531   /**
    532    * User readable name of the token family.
    533    */
    534   char *name;
    535 
    536   /**
    537    * Description of the token family.
    538    */
    539   char *description;
    540 
    541   /**
    542    * Internationalized token family description.
    543    */
    544   json_t *description_i18n;
    545 
    546   /**
    547    * Meta-data associated with the token family.
    548    * Includes information like "trusted_domains" or
    549    * "expected_domains", if set.
    550    */
    551   json_t *extra_data;
    552 
    553   /**
    554    * Cipher that should be used for this token family.  Note: We do not expose
    555    * this over the API and do not let clients set it. NULL for default (when
    556    * calling database).
    557    */
    558   char *cipher_spec;
    559 
    560   /**
    561    * Start time of the token family duration.
    562    */
    563   struct GNUNET_TIME_Timestamp valid_after;
    564 
    565   /**
    566    * End time of the token family duration.
    567    */
    568   struct GNUNET_TIME_Timestamp valid_before;
    569 
    570   /**
    571    * Validity duration of the token family. Must be larger or
    572    * equal to @a rounding plus @a start_offset_s.
    573    */
    574   struct GNUNET_TIME_Relative duration;
    575 
    576   /**
    577    * Rounding duration of the token family.
    578    */
    579   struct GNUNET_TIME_Relative validity_granularity;
    580 
    581   /**
    582    * Offset (in seconds) to subtract from the rounded
    583    * validity start period.
    584    */
    585   struct GNUNET_TIME_Relative start_offset;
    586 
    587   /**
    588    * Token family kind.
    589    */
    590   enum TALER_MERCHANTDB_TokenFamilyKind kind;
    591 
    592   /**
    593    * Counter for each issued token of this family.
    594    */
    595   uint64_t issued;
    596 
    597   /**
    598    * Counter for each used token of this family.
    599    */
    600   uint64_t used;
    601 };
    602 
    603 
    604 /**
    605  * Minimal product details for inventory templates.
    606  */
    607 struct TALER_MERCHANTDB_InventoryProductDetails
    608 {
    609   /**
    610    * Name of the product.
    611    */
    612   char *product_name;
    613 
    614   /**
    615    * Description of the product.
    616    */
    617   char *description;
    618 
    619   /**
    620    * Internationalized description.
    621    */
    622   json_t *description_i18n;
    623 
    624   /**
    625    * Unit in which the product is sold.
    626    */
    627   char *unit;
    628 
    629   /**
    630    * List of per-unit prices.
    631    */
    632   struct TALER_Amount *price_array;
    633 
    634   /**
    635    * Number of entries in @e price_array.
    636    */
    637   size_t price_array_length;
    638 
    639   /**
    640    * Hash of the product image data, or NULL.
    641    */
    642   char *image_hash;
    643 
    644   /**
    645    * Honor fractional stock if TRUE, else only integer stock.
    646    */
    647   bool allow_fractional_quantity;
    648 
    649   /**
    650    * Precision level (number of decimal places) to apply when
    651    * fractional quantities are enabled.
    652    */
    653   uint32_t fractional_precision_level;
    654 
    655   /**
    656    * Remaining units after sold/lost/locked deductions.
    657    */
    658   uint64_t remaining_stock;
    659 
    660   /**
    661    * Fractional part of remaining units in units of 1/1000000 of the base value.
    662    */
    663   uint32_t remaining_stock_frac;
    664 
    665   /**
    666    * List of taxes the merchant pays for this product. Never NULL,
    667    * but can be an empty array.
    668    */
    669   json_t *taxes;
    670 };
    671 
    672 
    673 /**
    674  * Details about an inventory measurement unit.
    675  */
    676 struct TALER_MERCHANTDB_UnitDetails
    677 {
    678 
    679   /**
    680    * Database serial.
    681    */
    682   uint64_t unit_serial;
    683 
    684   /**
    685    * Backend identifier used in product payloads.
    686    */
    687   char *unit;
    688 
    689   /**
    690    * Default long label (fallback string).
    691    */
    692   char *unit_name_long;
    693 
    694   /**
    695    * Default short label (fallback string).
    696    */
    697   char *unit_name_short;
    698 
    699   /**
    700    * Internationalised long labels.
    701    */
    702   json_t *unit_name_long_i18n;
    703 
    704   /**
    705    * Internationalised short labels.
    706    */
    707   json_t *unit_name_short_i18n;
    708 
    709   /**
    710    * Whether fractional quantities are enabled by default.
    711    */
    712   bool unit_allow_fraction;
    713 
    714   /**
    715    * Maximum number of fractional digits honoured by default.
    716    */
    717   uint32_t unit_precision_level;
    718 
    719   /**
    720    * Hidden from selectors when false.
    721    */
    722   bool unit_active;
    723 
    724   /**
    725    * Built-in units cannot be deleted.
    726    */
    727   bool unit_builtin;
    728 };
    729 
    730 
    731 /**
    732  * Details about a wire account of the merchant.
    733  */
    734 struct TALER_MERCHANTDB_AccountDetails
    735 {
    736   /**
    737    * Hash of the wire details (@e payto_uri and @e salt).
    738    */
    739   struct TALER_MerchantWireHashP h_wire;
    740 
    741   /**
    742    * Salt value used for hashing @e payto_uri.
    743    */
    744   struct TALER_WireSaltP salt;
    745 
    746   /**
    747    * Instance ID. Do not free (may be aliased with
    748    * the instance ID given in the query!).
    749    * FIXME: set in all functions involving this struct!
    750    */
    751   const char *instance_id;
    752 
    753   /**
    754    * Actual account address as a payto://-URI.
    755    */
    756   struct TALER_FullPayto payto_uri;
    757 
    758   /**
    759    * Where can the taler-merchant-wirewatch helper
    760    * download information about incoming transfers?
    761    * NULL if not available.
    762    */
    763   char *credit_facade_url;
    764 
    765   /**
    766    * JSON with credentials to use to access the
    767    * @e credit_facade_url.
    768    */
    769   json_t *credit_facade_credentials;
    770 
    771   /**
    772    * Additional meta data to include in wire transfers to this
    773    * account. Can be NULL if not used.
    774    */
    775   char *extra_wire_subject_metadata;
    776 
    777   /**
    778    * Is the account set for active use in new contracts?
    779    */
    780   bool active;
    781 
    782 };
    783 
    784 
    785 /**
    786  * Binary login token. Just a vanilla token made out
    787  * of random bits.
    788  */
    789 struct TALER_MERCHANTDB_LoginTokenP
    790 {
    791   /**
    792    * 32 bytes of entropy.
    793    */
    794   uint64_t data[32 / 8];
    795 };
    796 
    797 /**
    798  * Authentication settings for an instance.
    799  */
    800 struct TALER_MERCHANTDB_InstanceAuthSettings
    801 {
    802   /**
    803    * Hash used for authentication.  All zero if authentication is off.
    804    */
    805   struct TALER_MerchantAuthenticationHashP auth_hash;
    806 
    807   /**
    808    * Salt used to hash the "Authentication" header, the result must then
    809    * match the @e auth_hash.
    810    */
    811   struct TALER_MerchantAuthenticationSaltP auth_salt;
    812 };
    813 
    814 
    815 /**
    816  * General settings for an instance.
    817  */
    818 struct TALER_MERCHANTDB_InstanceSettings
    819 {
    820   /**
    821    * prefix for the instance under "/instances/"
    822    */
    823   char *id;
    824 
    825   /**
    826    * legal name of the instance
    827    */
    828   char *name;
    829 
    830   /**
    831    * merchant's site url
    832    */
    833   char *website;
    834 
    835   /**
    836    * email contact for password reset / possibly admin / customers
    837    */
    838   char *email;
    839 
    840   /**
    841    * phone contact for password reset / possibly admin / customers
    842    */
    843   char *phone;
    844 
    845   /**
    846    * merchant's logo data uri
    847    */
    848   char *logo;
    849 
    850   /**
    851    * Address of the business
    852    */
    853   json_t *address;
    854 
    855   /**
    856    * jurisdiction of the business
    857    */
    858   json_t *jurisdiction;
    859 
    860   /**
    861    * Use STEFAN curves to determine acceptable
    862    * fees by default (otherwise: accept no fees by default).
    863    */
    864   bool use_stefan;
    865 
    866   /**
    867    * True of @e phone was validated.
    868    */
    869   bool phone_validated;
    870 
    871   /**
    872    * True of @e email was validated.
    873    */
    874   bool email_validated;
    875 
    876   /**
    877    * If the frontend does NOT specify an execution date, how long should
    878    * we tell the exchange to wait to aggregate transactions before
    879    * executing the wire transfer?  This delay is added to the current
    880    * time when we generate the advisory execution time for the exchange.
    881    */
    882   struct GNUNET_TIME_Relative default_wire_transfer_delay;
    883 
    884   /**
    885    * If the frontend does NOT specify a payment deadline, how long should
    886    * offers we make be valid by default?
    887    */
    888   struct GNUNET_TIME_Relative default_pay_delay;
    889 
    890   /**
    891    * If the frontend does NOT specify a refund deadline, how long should
    892    * refunds be possible?
    893    */
    894   struct GNUNET_TIME_Relative default_refund_delay;
    895 
    896   /**
    897    * How much should we round up the wire transfer deadline computed by
    898    * adding the @e default_wire_transfer_delay to the refund deadline.
    899    */
    900   enum GNUNET_TIME_RounderInterval default_wire_transfer_rounding_interval;
    901 
    902 };
    903 
    904 
    905 /**
    906  * Free members of @a pd, but not @a pd itself.
    907  *
    908  * @param[in] pd product details to clean up
    909  */
    910 void
    911 TALER_MERCHANTDB_product_details_free (
    912   struct TALER_MERCHANTDB_ProductDetails *pd);
    913 
    914 
    915 /**
    916  * Free members of @a tp, but not @a tp itself.
    917  *
    918  * @param[in] tp template details to clean up
    919  */
    920 void
    921 TALER_MERCHANTDB_template_details_free (
    922   struct TALER_MERCHANTDB_TemplateDetails *tp);
    923 
    924 
    925 /**
    926  * Free members of @a wb, but not @a wb itself.
    927  *
    928  * @param[in] wb webhook details to clean up
    929  */
    930 void
    931 TALER_MERCHANTDB_webhook_details_free (
    932   struct TALER_MERCHANTDB_WebhookDetails *wb);
    933 
    934 /**
    935  * Free members of @a pwb, but not @a pwb itself.
    936  *
    937  * @param[in] pwb pending webhook details to clean up
    938  */
    939 void
    940 TALER_MERCHANTDB_pending_webhook_details_free (
    941   struct TALER_MERCHANTDB_PendingWebhookDetails *pwb);
    942 
    943 
    944 /**
    945  * Free members of @a tf, but not @a tf itself.
    946  *
    947  * @param[in] tf token family details to clean up
    948  */
    949 void
    950 TALER_MERCHANTDB_token_family_details_free (
    951   struct TALER_MERCHANTDB_TokenFamilyDetails *tf);
    952 
    953 
    954 /**
    955  * Free members of @a cd, but not @a cd itself.
    956  *
    957  * @param[in] cd token family details to clean up
    958  */
    959 void
    960 TALER_MERCHANTDB_category_details_free (
    961   struct TALER_MERCHANTDB_CategoryDetails *cd);
    962 
    963 /**
    964  * Free members of @a ud, but not @a ud itself.
    965  *
    966  * @param[in] ud unit details to clean up
    967  */
    968 void
    969 TALER_MERCHANTDB_unit_details_free (
    970   struct TALER_MERCHANTDB_UnitDetails *ud);
    971 
    972 #endif  /* MERCHANT_DB_H */
    973 
    974 /* end of taler_merchantdb_lib.h */