merchant

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

merchantdb_lib.h (19603B)


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